Skip to content

Dev#13

Merged
Snider merged 29 commits intomainfrom
dev
Mar 24, 2026
Merged

Dev#13
Snider merged 29 commits intomainfrom
dev

Conversation

@Snider
Copy link
Copy Markdown
Contributor

@Snider Snider commented Mar 24, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • New initialisation methods for application components and configuration.
    • New service registration and lifecycle management system with automatic event handling.
    • Enhanced options builder API for simplified configuration construction.
  • Refactor

    • Streamlined application startup and shutdown lifecycle via unified runtime method.
    • Improved service resolution with type-safe accessors.
    • Converted global state to per-instance isolation for thread safety.

Snider and others added 29 commits March 24, 2026 16:23
New() returns Result, accepts CoreOption functionals.
Restores v0.3.3 service registration contract:
- WithService(factory func(*Core) Result) — service factory receives Core
- WithOptions(Options) — key-value configuration
- WithServiceLock() — immutable after construction

Services registered in New() form the application conclave with
shared IPC access. Each Core instance has its own bus scope.

Co-Authored-By: Virgil <virgil@lethean.io>
…. Check: 1) API contract ...' (#29) from agent/review-pr--28--read-claude-md-first--che into dev
- WithOptions copies the Options slice (constructor isolation regression)
- WithService auto-discovers service name from package path via reflect
- WithService auto-registers HandleIPCEvents if present (v0.3.3 parity)
- Add test for failing option short-circuit in New()

Co-Authored-By: Virgil <virgil@lethean.io>
- HandleIPCEvents only auto-registered for services the factory didn't
  register itself (prevents double handler registration)
- Auto-discovery only creates Service{} placeholder when factory didn't
  call c.Service() — factories that register themselves keep full lifecycle

Addresses Codex review findings 1 and 2 from third pass.

Co-Authored-By: Virgil <virgil@lethean.io>
WithService is now a simple factory call — no reflect, no auto-registration.
New() calls discoverHandlers() after all opts run, scanning Config for
service instances that implement HandleIPCEvents.

This eliminates both double-registration and empty-placeholder issues:
- Factories wire their own lifecycle via c.Service()
- HandleIPCEvents discovered once, after all services are registered
- No tension between factory-registered and auto-discovered paths

Co-Authored-By: Virgil <virgil@lethean.io>
Restores v0.3.3 service manager capabilities:
- RegisterService(name, instance) stores the raw instance
- Auto-discovers Startable/Stoppable interfaces → wires lifecycle
- Auto-discovers HandleIPCEvents → wires to IPC bus
- ServiceFor[T](c, name) for typed instance retrieval
- Service DTO gains Instance field for instance tracking

WithService is a simple factory call — no reflect, no magic.
discoverHandlers removed — RegisterService handles it inline.
No double-registration: IPC wired once at registration time.

Co-Authored-By: Virgil <virgil@lethean.io>
Options is now a proper struct with New(), Set(), Get(), typed accessors.
Result gains New(), Result(), Get() methods on the struct.
WithOption("key", value) convenience for core.New().

options_test.go: 22 tests passing against the new contract.
Other test files mechanically updated for compilation.

Co-Authored-By: Virgil <virgil@lethean.io>
App.New() creates from Options. App.Find() locates programs on PATH.
Both are struct methods — no package-level functions.
8 tests passing.

Co-Authored-By: Virgil <virgil@lethean.io>
Cli struct unchanged — already conforms.
Tests use WithOption() convenience. 9 tests passing.

Co-Authored-By: Virgil <virgil@lethean.io>
Cli{}.New(c) replaces &Cli{core: c} in contract.go.
9 tests passing.

Co-Authored-By: Virgil <virgil@lethean.io>
Cli as service with ServiceRuntime, incomplete.
Need to properly port v0.3.3 service_manager, message_bus,
WithService with full name/IPC discovery.

Co-Authored-By: Virgil <virgil@lethean.io>
…tration

- WithService now calls factory, discovers service name from package path via
  reflect/runtime (last path segment, _test suffix stripped, lowercased), and
  calls RegisterService — which handles Startable/Stoppable/HandleIPCEvents
- If factory returns nil Value (self-registered), WithService returns OK without
  a second registration
- Add contract_test.go with _Good/_Bad tests covering all three code paths
- Fix core.go Cli() accessor: use ServiceFor[*Cli](c, "cli") (was cli.New())
- Fix pre-existing })) → }}) syntax errors in command_test, service_test, lock_test
- Fix pre-existing Options{...} → NewOptions(...) in core_test, data_test,
  drive_test, i18n_test (Options is a struct, not a slice)

Co-Authored-By: Virgil <virgil@lethean.io>
…tration

WithService now: calls factory, discovers service name from instance's
package path via reflect.TypeOf, discovers HandleIPCEvents method,
calls RegisterService. If factory returns nil Value, assumes self-registered.

Also fixes: Cli() accessor uses ServiceFor, test files updated for Options struct.

Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Virgil <virgil@lethean.io>
…arity

Co-Authored-By: Virgil <virgil@lethean.io>
WithService: full name discovery + IPC handler auto-registration via reflect
WithName: explicit service naming
RegisterService: Startable/Stoppable/HandleIPCEvents auto-discovery
MustServiceFor[T]: panics if not found
WithServiceLock: enable/apply split (v0.3.3 parity)
Cli: registered as service via CliRegister, accessed via ServiceFor

@todo Codex: Fix data_test.go and embed_test.go — embed path resolution
after Options changed from []Option to struct. Mount paths need updating.

Co-Authored-By: Virgil <virgil@lethean.io>
…ixes

Root cause: Result.New didn't mark single-value results as OK=true,
breaking Mount/ReadDir/fs helpers that used Result{}.New(value, err).

Also: data_test.go and embed_test.go updated for Options struct,
doc comments updated across data.go, drive.go, command.go, contract.go.

All tests green. Coverage 82.2%.

Co-Authored-By: Virgil <virgil@lethean.io>
Config.New() initialises ConfigOptions.
Fs.New(root) sets sandbox root.
ErrorLog uses Default() fallback — no explicit init needed.
contract.go uses constructors instead of struct literals.

All tests green.

Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Virgil <virgil@lethean.io>
…' (#28) from feat/service-options into dev
- Run() uses context.Background() for shutdown (c.context is cancelled)
- Stoppable closure uses context.Background() for OnShutdown
- WithService delegates HandleIPCEvents to RegisterService only

Fixes Codex review findings 1, 2, 3.

Co-Authored-By: Virgil <virgil@lethean.io>
…(#36) from fix/codex-review-findings into dev
Tests: Run, RegisterService, ServiceFor, MustServiceFor _Bad/_Ugly variants.
Fix: Lock map is now per-Core instance, not package-level global.
This prevents deadlocks when multiple Core instances exist (e.g. tests).

Coverage: 82.4% → 83.6%

Co-Authored-By: Virgil <virgil@lethean.io>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 24, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 36d9554e-6192-4dd4-8586-d6ae79de9fd3

📥 Commits

Reviewing files that changed from the base of the PR and between a6be0df and f6ed40d.

📒 Files selected for processing (26)
  • app.go
  • app_test.go
  • cli.go
  • cli_test.go
  • command.go
  • command_test.go
  • config.go
  • contract.go
  • contract_test.go
  • core.go
  • core_test.go
  • data.go
  • data_test.go
  • drive.go
  • drive_test.go
  • embed.go
  • embed_test.go
  • fs.go
  • i18n_test.go
  • ipc.go
  • lock.go
  • options.go
  • options_test.go
  • runtime.go
  • service.go
  • service_test.go

📝 Walkthrough

Walkthrough

This PR refactors the core framework with a functional options pattern, service-oriented architecture, and improved resource isolation. Changes include restructuring the App and Options APIs, converting Cli to a registered service, introducing CoreOption functional options, and adding lifecycle management via RegisterService with auto-wired Startup/Shutdown hooks and IPC event handling.

Changes

Cohort / File(s) Summary
Core constructor and options refactoring
contract.go, contract_test.go, core.go, core_test.go
Replaced New(opts ...Options) with New(opts ...CoreOption). Added functional option helpers (WithOptions, WithService, WithName, WithOption, WithServiceLock) supporting service registration and initialization. Added Core.Run() lifecycle method. Changed Cli() to dynamically resolve from services instead of stored field.
Service management and registration
service.go, service_test.go
Added RegisterService() for service registration with auto-wired lifecycle callbacks (OnStartup, OnShutdown) and IPC event handling. Extended Service struct with Instance field. Added typed accessors ServiceFor[T]() and MustServiceFor[T](). Updated Service() retrieval to return instance when available.
CLI refactoring to service-based
cli.go, cli_test.go
Converted Cli to embed *ServiceRuntime[CliOptions]. Added CliRegister() function for CLI service registration. Updated option construction to use NewOptions() builder pattern.
App and Find API restructuring
app.go, app_test.go
Added exported fields to App struct (Filename, Path, Runtime). Introduced App.New() constructor method. Changed Find() from package-level function to App.Find() method. Updated tests to reflect new constructor and method signatures.
Options and Result API refactoring
options.go, options_test.go, runtime.go
Changed Options from slice to struct with internal items field. Added NewOptions() constructor and Set() method. Enhanced Result with New() and Get() methods. Updated usage throughout codebase to use builder pattern.
Configuration and service utilities
config.go, service.go
Added Config.New() initializer method. Added per-Core lock isolation in Lock struct, replacing global lock state (lock.go). Updated retrieval and accessor patterns across service classes.
Test infrastructure and examples
command.go, command_test.go, data.go, data_test.go, drive.go, drive_test.go, embed.go, embed_test.go, fs.go, i18n_test.go, ipc.go
Updated documentation examples and test helper methods to use NewOptions() constructor. Added test helpers (mountTestData, mustMountTestFS). Changed Result construction from Result() to New() in multiple places (fs.go, embed.go). Added filesystem sandbox initialization via Fs.New().

Comment @coderabbitai help to get the list of available commands and usage tips.

@Snider Snider merged commit de6fa03 into main Mar 24, 2026
1 check was pending
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant