refactor(appkit): introduce ServiceManager for core service lifecycle#374
Open
ditadi wants to merge 1 commit into
Open
refactor(appkit): introduce ServiceManager for core service lifecycle#374ditadi wants to merge 1 commit into
ditadi wants to merge 1 commit into
Conversation
This was referenced May 11, 2026
AppKit's core previously ran a hardcoded boot sequence for cache +
telemetry. This refactor introduces a generic service container so
the core no longer names concrete services in its bootstrap path:
- `ServiceManager` — container that holds booted core services,
resolves them by name via `get<T>(name)`, and stops them in reverse
start order. `add(name, null)` is a no-op so callers can pass
opt-out results directly.
- `startCoreServices(config)` — builds the ServiceManager AppKit ships
with; lives next to the concrete service modules so `core/appkit.ts`
stays free of concrete-class imports.
Cache and Telemetry expose a `static boot(config)` returning
`{ instance, stop } | null`. Telemetry returns `null` when no OTLP
endpoint is configured (preserves the existing opt-out semantics).
Plugins receive a typed `services` locator through `attachContext`;
the shape is inlined in `BasePlugin` so the shared package does not
gain a new exported interface. New plugins resolve services via
`services.get<MyService>("my-service")` when the base class doesn't
surface them as properties.
Groundwork only — no behaviour change, no public-API removal. The
goal is to make room for a third core service (TaskFlow) without
re-threading the cross-package `attachContext` contract: adding a
new service touches only the service module and `startCoreServices`.
TaskFlow itself is intentionally NOT in this PR.
Verified: pnpm -r typecheck, pnpm build, full vitest run
(123 files, 2261 tests) all green.
Signed-off-by: ditadi <victordperd@gmail.com>
6efbe15 to
a8b7010
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🥞 Stacked PR
Use this link to review incremental changes.
AppKit's core previously ran a hardcoded boot sequence for cache + telemetry. This refactor introduces a generic service container so the core no longer names concrete services in its bootstrap path:
ServiceManager— holds booted core services, resolves them by name viaget<T>(name), and stops them in reverse start order.add(name, null)is a no-op so callers can pass opt-out results directly.startCoreServices(config)— builds theServiceManagerAppKit ships with; lives next to the concrete service modules socore/appkit.tsstays free of concrete-class imports.Cache and Telemetry expose a
static boot(config)returning{ instance, stop } | null. Telemetry returnsnullwhen no OTLP endpoint is configured (preserves the existing opt-out semantics).Plugins receive a typed
serviceslocator throughattachContext. The shape is inlined inBasePluginso thesharedpackage does not gain a new exported interface. Plugins resolve services viaservices.get<MyService>("my-service")when the base class doesn't surface them as properties.Groundwork only — no behaviour change, no public-API removal. The goal is to make room for a third core service (TaskFlow) without re-threading the cross-package
attachContextcontract: adding a new service touches only the service module andstartCoreServices. TaskFlow itself is intentionally NOT in this PR.Verified: `pnpm -r typecheck`, `pnpm build`, full vitest run (123 files, 2261 tests) all green.
Signed-off-by: ditadi victordperd@gmail.com