Skip to content

v7.0.0

Choose a tag to compare

@vectronic vectronic released this 17 Sep 18:22
· 76 commits to main since this release

7.0.0 (2026-09-17)

⚠ BREAKING CHANGES

  • ConfigurationServiceProvider's constructor no longer accepts
    keyValueServiceEnabled, and no longer exposes getScopedKeyValueService/getContextForScope/
    configLocationService - use the new KeyValueServiceProvider instead. This package's
    index.ts no longer exports ConfigLocationService/CONFIG_LOCATION_SERVICE_ID. runner.ts's
    run() now takes an additional keyValueServiceProvider parameter.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

  • docs: fix stale runner.ts overview comment after StartupService/provider-split changes

The overview comment still described the old "for each ServiceProvider"
loop and didn't mention the priority-ordered StartupTask merge, the
blocking/background task distinction, or the per-task scoped KeyValueService
Context decoration - all introduced by the service-lifecycle redesign.

Also drops the unused configurationServiceProvider parameter from
executeParsedCommand(), which never referenced it - default argument values
are already applied by the scanning functions before this runs.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

  • refactor!: separate startupTasks from serviceProviders in launcher functions

launchSingleCommandCLI/launchMultiCommandCLI took one serviceProviders array
accepting either a ServiceProvider or a plain StartupTask, discriminated at
runtime via isStartupTask(). Splitting into two type-safe parameters
(serviceProviders: ServiceProvider[], startupTasks: StartupTask[]) removes
the need for that union type and runtime guard entirely.

startupTasks is appended as a new trailing parameter (after options) rather
than inserted before it, so existing 6-positional-argument callers are
unaffected.

  • ServiceProviderOrStartupTask and isStartupTask are removed.
    A StartupTask (e.g. from createBannerStartupTask()) must now be passed via
    the new startupTasks parameter instead of mixed into serviceProviders.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

  • fix!: stop exposing full config dump through the general ConfigurationService lookup

ConfigurationService.getConfigString() was reachable by any command/task via
context.getServiceById(CONFIGURATION_SERVICE_ID), and returned the entire
config file - including every other command's and service's key-value data
and any embedded secret sentinels. Since SecretService.getSecret() doesn't
validate that a sentinel belongs to the caller's own scope, a command could
extract another consumer's sentinel from the dump, write it into its own
KeyValueService scope, and have it transparently decrypted - fully
defeating the per-scope isolation fix.

DumpConfigCommand (the only legitimate consumer, and a command
ConfigurationServiceProvider already constructs itself) now receives
getConfigString via a direct constructor reference instead, the same
pattern already used for KeyValueServiceProvider's internal-only access -
never exposed through Context.

  • ConfigurationService no longer has getConfigString().
    DumpConfigCommand's constructor now requires a getConfigString: () => string
    argument.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

  • chore: depend on published dynamic-cli-framework-api 4.0.0

Replaces the local bun-link development dependency now that the
service-lifecycle redesign's api package changes (StartupService,
ShutdownService.registerTask, ConfigurationService, UpgradeService's
waitForResult removal) are published.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

  • style: apply oxfmt formatting

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

  • chore: bump dynamic-cli-framework-api to published 4.0.1

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

  • chore: update docs

  • chore: fmt

Features