opensip-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +8 -0
- package/README.md +51 -0
- package/dist/api.d.ts +17 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +16 -0
- package/dist/api.js.map +1 -0
- package/dist/bootstrap/admit-tool-package.d.ts +117 -0
- package/dist/bootstrap/admit-tool-package.d.ts.map +1 -0
- package/dist/bootstrap/admit-tool-package.js +170 -0
- package/dist/bootstrap/admit-tool-package.js.map +1 -0
- package/dist/bootstrap/baseline-seams.d.ts +30 -0
- package/dist/bootstrap/baseline-seams.d.ts.map +1 -0
- package/dist/bootstrap/baseline-seams.js +156 -0
- package/dist/bootstrap/baseline-seams.js.map +1 -0
- package/dist/bootstrap/bootstrap-error.d.ts +41 -0
- package/dist/bootstrap/bootstrap-error.d.ts.map +1 -0
- package/dist/bootstrap/bootstrap-error.js +33 -0
- package/dist/bootstrap/bootstrap-error.js.map +1 -0
- package/dist/bootstrap/build-command-registration-input.d.ts +34 -0
- package/dist/bootstrap/build-command-registration-input.d.ts.map +1 -0
- package/dist/bootstrap/build-command-registration-input.js +73 -0
- package/dist/bootstrap/build-command-registration-input.js.map +1 -0
- package/dist/bootstrap/build-per-run-scope.d.ts +62 -0
- package/dist/bootstrap/build-per-run-scope.d.ts.map +1 -0
- package/dist/bootstrap/build-per-run-scope.js +152 -0
- package/dist/bootstrap/build-per-run-scope.js.map +1 -0
- package/dist/bootstrap/build-targets.d.ts +42 -0
- package/dist/bootstrap/build-targets.d.ts.map +1 -0
- package/dist/bootstrap/build-targets.js +117 -0
- package/dist/bootstrap/build-targets.js.map +1 -0
- package/dist/bootstrap/cli-defaults.d.ts +35 -0
- package/dist/bootstrap/cli-defaults.d.ts.map +1 -0
- package/dist/bootstrap/cli-defaults.js +65 -0
- package/dist/bootstrap/cli-defaults.js.map +1 -0
- package/dist/bootstrap/config-and-capabilities.d.ts +74 -0
- package/dist/bootstrap/config-and-capabilities.d.ts.map +1 -0
- package/dist/bootstrap/config-and-capabilities.js +224 -0
- package/dist/bootstrap/config-and-capabilities.js.map +1 -0
- package/dist/bootstrap/deliver-envelope.d.ts +80 -0
- package/dist/bootstrap/deliver-envelope.d.ts.map +1 -0
- package/dist/bootstrap/deliver-envelope.js +195 -0
- package/dist/bootstrap/deliver-envelope.js.map +1 -0
- package/dist/bootstrap/egress-plane.d.ts +22 -0
- package/dist/bootstrap/egress-plane.d.ts.map +1 -0
- package/dist/bootstrap/egress-plane.js +37 -0
- package/dist/bootstrap/egress-plane.js.map +1 -0
- package/dist/bootstrap/host-planes.d.ts +28 -0
- package/dist/bootstrap/host-planes.d.ts.map +1 -0
- package/dist/bootstrap/host-planes.js +152 -0
- package/dist/bootstrap/host-planes.js.map +1 -0
- package/dist/bootstrap/index.d.ts +76 -0
- package/dist/bootstrap/index.d.ts.map +1 -0
- package/dist/bootstrap/index.js +109 -0
- package/dist/bootstrap/index.js.map +1 -0
- package/dist/bootstrap/live-plane.d.ts +51 -0
- package/dist/bootstrap/live-plane.d.ts.map +1 -0
- package/dist/bootstrap/live-plane.js +72 -0
- package/dist/bootstrap/live-plane.js.map +1 -0
- package/dist/bootstrap/load-tool-capabilities.d.ts +42 -0
- package/dist/bootstrap/load-tool-capabilities.d.ts.map +1 -0
- package/dist/bootstrap/load-tool-capabilities.js +76 -0
- package/dist/bootstrap/load-tool-capabilities.js.map +1 -0
- package/dist/bootstrap/output-plane.d.ts +37 -0
- package/dist/bootstrap/output-plane.d.ts.map +1 -0
- package/dist/bootstrap/output-plane.js +114 -0
- package/dist/bootstrap/output-plane.js.map +1 -0
- package/dist/bootstrap/owning-tool-init.d.ts +32 -0
- package/dist/bootstrap/owning-tool-init.d.ts.map +1 -0
- package/dist/bootstrap/owning-tool-init.js +69 -0
- package/dist/bootstrap/owning-tool-init.js.map +1 -0
- package/dist/bootstrap/pre-action-guards.d.ts +44 -0
- package/dist/bootstrap/pre-action-guards.d.ts.map +1 -0
- package/dist/bootstrap/pre-action-guards.js +136 -0
- package/dist/bootstrap/pre-action-guards.js.map +1 -0
- package/dist/bootstrap/pre-action-hook.d.ts +68 -0
- package/dist/bootstrap/pre-action-hook.d.ts.map +1 -0
- package/dist/bootstrap/pre-action-hook.js +289 -0
- package/dist/bootstrap/pre-action-hook.js.map +1 -0
- package/dist/bootstrap/pre-action-messages.d.ts +32 -0
- package/dist/bootstrap/pre-action-messages.d.ts.map +1 -0
- package/dist/bootstrap/pre-action-messages.js +49 -0
- package/dist/bootstrap/pre-action-messages.js.map +1 -0
- package/dist/bootstrap/process-idempotency.d.ts +17 -0
- package/dist/bootstrap/process-idempotency.d.ts.map +1 -0
- package/dist/bootstrap/process-idempotency.js +20 -0
- package/dist/bootstrap/process-idempotency.js.map +1 -0
- package/dist/bootstrap/register-language-adapters.d.ts +23 -0
- package/dist/bootstrap/register-language-adapters.d.ts.map +1 -0
- package/dist/bootstrap/register-language-adapters.js +35 -0
- package/dist/bootstrap/register-language-adapters.js.map +1 -0
- package/dist/bootstrap/register-tools.d.ts +228 -0
- package/dist/bootstrap/register-tools.d.ts.map +1 -0
- package/dist/bootstrap/register-tools.js +696 -0
- package/dist/bootstrap/register-tools.js.map +1 -0
- package/dist/bootstrap/render.d.ts +27 -0
- package/dist/bootstrap/render.d.ts.map +1 -0
- package/dist/bootstrap/render.js +53 -0
- package/dist/bootstrap/render.js.map +1 -0
- package/dist/bootstrap/report.d.ts +34 -0
- package/dist/bootstrap/report.d.ts.map +1 -0
- package/dist/bootstrap/report.js +47 -0
- package/dist/bootstrap/report.js.map +1 -0
- package/dist/bootstrap/run-plane.d.ts +105 -0
- package/dist/bootstrap/run-plane.d.ts.map +1 -0
- package/dist/bootstrap/run-plane.js +190 -0
- package/dist/bootstrap/run-plane.js.map +1 -0
- package/dist/bootstrap/scope-access.d.ts +68 -0
- package/dist/bootstrap/scope-access.d.ts.map +1 -0
- package/dist/bootstrap/scope-access.js +115 -0
- package/dist/bootstrap/scope-access.js.map +1 -0
- package/dist/bootstrap/state-seams.d.ts +14 -0
- package/dist/bootstrap/state-seams.d.ts.map +1 -0
- package/dist/bootstrap/state-seams.js +26 -0
- package/dist/bootstrap/state-seams.js.map +1 -0
- package/dist/bootstrap/tool-lifecycle.d.ts +102 -0
- package/dist/bootstrap/tool-lifecycle.d.ts.map +1 -0
- package/dist/bootstrap/tool-lifecycle.js +103 -0
- package/dist/bootstrap/tool-lifecycle.js.map +1 -0
- package/dist/bootstrap/tool-trust.d.ts +49 -0
- package/dist/bootstrap/tool-trust.d.ts.map +1 -0
- package/dist/bootstrap/tool-trust.js +65 -0
- package/dist/bootstrap/tool-trust.js.map +1 -0
- package/dist/bootstrap/validate-tool.d.ts +22 -0
- package/dist/bootstrap/validate-tool.d.ts.map +1 -0
- package/dist/bootstrap/validate-tool.js +38 -0
- package/dist/bootstrap/validate-tool.js.map +1 -0
- package/dist/cli-context.d.ts +38 -0
- package/dist/cli-context.d.ts.map +1 -0
- package/dist/cli-context.js +134 -0
- package/dist/cli-context.js.map +1 -0
- package/dist/commands/agent-catalog.d.ts +45 -0
- package/dist/commands/agent-catalog.d.ts.map +1 -0
- package/dist/commands/agent-catalog.js +115 -0
- package/dist/commands/agent-catalog.js.map +1 -0
- package/dist/commands/assemble-outcome.d.ts +69 -0
- package/dist/commands/assemble-outcome.d.ts.map +1 -0
- package/dist/commands/assemble-outcome.js +121 -0
- package/dist/commands/assemble-outcome.js.map +1 -0
- package/dist/commands/clear.d.ts +32 -0
- package/dist/commands/clear.d.ts.map +1 -0
- package/dist/commands/clear.js +73 -0
- package/dist/commands/clear.js.map +1 -0
- package/dist/commands/completion.d.ts +90 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +233 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/configure.d.ts +32 -0
- package/dist/commands/configure.d.ts.map +1 -0
- package/dist/commands/configure.js +94 -0
- package/dist/commands/configure.js.map +1 -0
- package/dist/commands/history.d.ts +18 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +48 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/host-command-specs.d.ts +49 -0
- package/dist/commands/host-command-specs.d.ts.map +1 -0
- package/dist/commands/host-command-specs.js +331 -0
- package/dist/commands/host-command-specs.js.map +1 -0
- package/dist/commands/host-subcommand-groups.d.ts +69 -0
- package/dist/commands/host-subcommand-groups.d.ts.map +1 -0
- package/dist/commands/host-subcommand-groups.js +374 -0
- package/dist/commands/host-subcommand-groups.js.map +1 -0
- package/dist/commands/index.d.ts +36 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +36 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init/config-templates.d.ts +16 -0
- package/dist/commands/init/config-templates.d.ts.map +1 -0
- package/dist/commands/init/config-templates.js +108 -0
- package/dist/commands/init/config-templates.js.map +1 -0
- package/dist/commands/init/file-classifier.d.ts +40 -0
- package/dist/commands/init/file-classifier.d.ts.map +1 -0
- package/dist/commands/init/file-classifier.js +155 -0
- package/dist/commands/init/file-classifier.js.map +1 -0
- package/dist/commands/init/language-detection.d.ts +44 -0
- package/dist/commands/init/language-detection.d.ts.map +1 -0
- package/dist/commands/init/language-detection.js +124 -0
- package/dist/commands/init/language-detection.js.map +1 -0
- package/dist/commands/init/scaffold-writer.d.ts +26 -0
- package/dist/commands/init/scaffold-writer.d.ts.map +1 -0
- package/dist/commands/init/scaffold-writer.js +102 -0
- package/dist/commands/init/scaffold-writer.js.map +1 -0
- package/dist/commands/init/state-machine.d.ts +32 -0
- package/dist/commands/init/state-machine.d.ts.map +1 -0
- package/dist/commands/init/state-machine.js +105 -0
- package/dist/commands/init/state-machine.js.map +1 -0
- package/dist/commands/init.d.ts +95 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +209 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mount-command-spec.d.ts +106 -0
- package/dist/commands/mount-command-spec.d.ts.map +1 -0
- package/dist/commands/mount-command-spec.js +313 -0
- package/dist/commands/mount-command-spec.js.map +1 -0
- package/dist/commands/mount-result-command.d.ts +71 -0
- package/dist/commands/mount-result-command.d.ts.map +1 -0
- package/dist/commands/mount-result-command.js +76 -0
- package/dist/commands/mount-result-command.js.map +1 -0
- package/dist/commands/plugin/config-edit.d.ts +20 -0
- package/dist/commands/plugin/config-edit.d.ts.map +1 -0
- package/dist/commands/plugin/config-edit.js +102 -0
- package/dist/commands/plugin/config-edit.js.map +1 -0
- package/dist/commands/plugin/domain-resolution.d.ts +38 -0
- package/dist/commands/plugin/domain-resolution.d.ts.map +1 -0
- package/dist/commands/plugin/domain-resolution.js +98 -0
- package/dist/commands/plugin/domain-resolution.js.map +1 -0
- package/dist/commands/plugin/host-dir.d.ts +42 -0
- package/dist/commands/plugin/host-dir.d.ts.map +1 -0
- package/dist/commands/plugin/host-dir.js +168 -0
- package/dist/commands/plugin/host-dir.js.map +1 -0
- package/dist/commands/plugin-host-ops.d.ts +41 -0
- package/dist/commands/plugin-host-ops.d.ts.map +1 -0
- package/dist/commands/plugin-host-ops.js +114 -0
- package/dist/commands/plugin-host-ops.js.map +1 -0
- package/dist/commands/plugin.d.ts +81 -0
- package/dist/commands/plugin.d.ts.map +1 -0
- package/dist/commands/plugin.js +287 -0
- package/dist/commands/plugin.js.map +1 -0
- package/dist/commands/render-outcome.d.ts +52 -0
- package/dist/commands/render-outcome.d.ts.map +1 -0
- package/dist/commands/render-outcome.js +55 -0
- package/dist/commands/render-outcome.js.map +1 -0
- package/dist/commands/session-show.d.ts +27 -0
- package/dist/commands/session-show.d.ts.map +1 -0
- package/dist/commands/session-show.js +166 -0
- package/dist/commands/session-show.js.map +1 -0
- package/dist/commands/shared.d.ts +107 -0
- package/dist/commands/shared.d.ts.map +1 -0
- package/dist/commands/shared.js +13 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/commands/tools/data-purge.d.ts +20 -0
- package/dist/commands/tools/data-purge.d.ts.map +1 -0
- package/dist/commands/tools/data-purge.js +59 -0
- package/dist/commands/tools/data-purge.js.map +1 -0
- package/dist/commands/tools/index.d.ts +16 -0
- package/dist/commands/tools/index.d.ts.map +1 -0
- package/dist/commands/tools/index.js +213 -0
- package/dist/commands/tools/index.js.map +1 -0
- package/dist/commands/tools/install.d.ts +24 -0
- package/dist/commands/tools/install.d.ts.map +1 -0
- package/dist/commands/tools/install.js +83 -0
- package/dist/commands/tools/install.js.map +1 -0
- package/dist/commands/tools/list.d.ts +41 -0
- package/dist/commands/tools/list.d.ts.map +1 -0
- package/dist/commands/tools/list.js +103 -0
- package/dist/commands/tools/list.js.map +1 -0
- package/dist/commands/tools/runtime-probe-entry.d.ts +14 -0
- package/dist/commands/tools/runtime-probe-entry.d.ts.map +1 -0
- package/dist/commands/tools/runtime-probe-entry.js +36 -0
- package/dist/commands/tools/runtime-probe-entry.js.map +1 -0
- package/dist/commands/tools/runtime-probe.d.ts +29 -0
- package/dist/commands/tools/runtime-probe.d.ts.map +1 -0
- package/dist/commands/tools/runtime-probe.js +66 -0
- package/dist/commands/tools/runtime-probe.js.map +1 -0
- package/dist/commands/tools/storage-contract-checks.d.ts +37 -0
- package/dist/commands/tools/storage-contract-checks.d.ts.map +1 -0
- package/dist/commands/tools/storage-contract-checks.js +91 -0
- package/dist/commands/tools/storage-contract-checks.js.map +1 -0
- package/dist/commands/tools/uninstall.d.ts +29 -0
- package/dist/commands/tools/uninstall.d.ts.map +1 -0
- package/dist/commands/tools/uninstall.js +77 -0
- package/dist/commands/tools/uninstall.js.map +1 -0
- package/dist/commands/tools/validate.d.ts +44 -0
- package/dist/commands/tools/validate.d.ts.map +1 -0
- package/dist/commands/tools/validate.js +202 -0
- package/dist/commands/tools/validate.js.map +1 -0
- package/dist/commands/uninstall/targets.d.ts +53 -0
- package/dist/commands/uninstall/targets.d.ts.map +1 -0
- package/dist/commands/uninstall/targets.js +205 -0
- package/dist/commands/uninstall/targets.js.map +1 -0
- package/dist/commands/uninstall.d.ts +88 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +184 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/env/host-env-specs.d.ts +52 -0
- package/dist/env/host-env-specs.d.ts.map +1 -0
- package/dist/env/host-env-specs.js +129 -0
- package/dist/env/host-env-specs.js.map +1 -0
- package/dist/error-handler.d.ts +64 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +180 -0
- package/dist/error-handler.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +154 -0
- package/dist/index.js.map +1 -0
- package/dist/open-report.d.ts +40 -0
- package/dist/open-report.d.ts.map +1 -0
- package/dist/open-report.js +54 -0
- package/dist/open-report.js.map +1 -0
- package/dist/report-compose.d.ts +35 -0
- package/dist/report-compose.d.ts.map +1 -0
- package/dist/report-compose.js +103 -0
- package/dist/report-compose.js.map +1 -0
- package/dist/session-replay-registry.d.ts +20 -0
- package/dist/session-replay-registry.d.ts.map +1 -0
- package/dist/session-replay-registry.js +38 -0
- package/dist/session-replay-registry.js.map +1 -0
- package/dist/telemetry/profiling.d.ts +42 -0
- package/dist/telemetry/profiling.d.ts.map +1 -0
- package/dist/telemetry/profiling.js +160 -0
- package/dist/telemetry/profiling.js.map +1 -0
- package/dist/telemetry/sdk-init.d.ts +87 -0
- package/dist/telemetry/sdk-init.d.ts.map +1 -0
- package/dist/telemetry/sdk-init.js +235 -0
- package/dist/telemetry/sdk-init.js.map +1 -0
- package/dist/ui/App.d.ts +32 -0
- package/dist/ui/App.d.ts.map +1 -0
- package/dist/ui/App.js +35 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/render.d.ts +15 -0
- package/dist/ui/render.d.ts.map +1 -0
- package/dist/ui/render.js +21 -0
- package/dist/ui/render.js.map +1 -0
- package/dist/ui/result-to-view.d.ts +40 -0
- package/dist/ui/result-to-view.d.ts.map +1 -0
- package/dist/ui/result-to-view.js +389 -0
- package/dist/ui/result-to-view.js.map +1 -0
- package/dist/ui/views/init-view.d.ts +9 -0
- package/dist/ui/views/init-view.d.ts.map +1 -0
- package/dist/ui/views/init-view.js +119 -0
- package/dist/ui/views/init-view.js.map +1 -0
- package/dist/ui/views/misc-views.d.ts +18 -0
- package/dist/ui/views/misc-views.d.ts.map +1 -0
- package/dist/ui/views/misc-views.js +244 -0
- package/dist/ui/views/misc-views.js.map +1 -0
- package/dist/ui/views/plugin-view.d.ts +8 -0
- package/dist/ui/views/plugin-view.d.ts.map +1 -0
- package/dist/ui/views/plugin-view.js +135 -0
- package/dist/ui/views/plugin-view.js.map +1 -0
- package/dist/ui/views/tools-views.d.ts +12 -0
- package/dist/ui/views/tools-views.d.ts.map +1 -0
- package/dist/ui/views/tools-views.js +152 -0
- package/dist/ui/views/tools-views.js.map +1 -0
- package/dist/update-notifier.d.ts +108 -0
- package/dist/update-notifier.d.ts.map +1 -0
- package/dist/update-notifier.js +188 -0
- package/dist/update-notifier.js.map +1 -0
- package/dist/update-state.d.ts +40 -0
- package/dist/update-state.d.ts.map +1 -0
- package/dist/update-state.js +81 -0
- package/dist/update-state.js.map +1 -0
- package/dist/welcome.d.ts +53 -0
- package/dist/welcome.d.ts.map +1 -0
- package/dist/welcome.js +89 -0
- package/dist/welcome.js.map +1 -0
- package/package.json +100 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-targets.d.ts","sourceRoot":"","sources":["../../src/bootstrap/build-targets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA4C5E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,cAAc,GAAG,SAAS,CAqD7F"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* build-targets — the host's once-per-run construction of `scope.targets`
|
|
3
|
+
* (ADR-0037, generic-targeting-runtime Phase 1).
|
|
4
|
+
*
|
|
5
|
+
* The composition root reads the already-resolved config document, parses the
|
|
6
|
+
* host-owned `targets:` / `globalExcludes:` blocks through the
|
|
7
|
+
* `@opensip-cli/config` Zod field schemas, registers each target into the
|
|
8
|
+
* substrate `TargetRegistry`, and returns a `TargetResolver` — the structural
|
|
9
|
+
* scope-slot shape `core` declares — wrapping the registry plus the bound
|
|
10
|
+
* `resolveTargets` / `applyGlobalExcludes` closures + the project
|
|
11
|
+
* `globalExcludes`. The CLI bootstrap attaches the result as `scope.targets`,
|
|
12
|
+
* mirroring how `composeAndValidateToolConfig` produces `scope.toolConfig`.
|
|
13
|
+
*
|
|
14
|
+
* The host build is the GENERIC half only: it does NOT validate `checkOverrides`
|
|
15
|
+
* (a check-slug concept) — that cross-validation stays in
|
|
16
|
+
* `@opensip-cli/fitness`'s loader (Phase 2). A run with no config document, or
|
|
17
|
+
* a config document with no `targets:` block, yields `undefined` — exactly like
|
|
18
|
+
* a config-less `toolConfig`.
|
|
19
|
+
*/
|
|
20
|
+
import { globalExcludesSchema, targetsRecordSchema } from '@opensip-cli/config';
|
|
21
|
+
import { ConfigurationError } from '@opensip-cli/core';
|
|
22
|
+
import { TargetRegistry, applyGlobalExcludes, resolveTargets } from '@opensip-cli/targeting';
|
|
23
|
+
/**
|
|
24
|
+
* Default per-target exclusion globs, applied when a target declares no
|
|
25
|
+
* explicit `exclude`. Mirrors the fitness loader's fallback normalization so
|
|
26
|
+
* the host-built set and the scope-less fallback build (fitness
|
|
27
|
+
* `targets/loader.ts`, kept for programmatic/test use) stay byte-identical.
|
|
28
|
+
*/
|
|
29
|
+
const DEFAULT_EXCLUDES = ['**/node_modules/**', '**/dist/**'];
|
|
30
|
+
/** A plain-object guard that treats arrays and null as non-objects. */
|
|
31
|
+
function isPlainObject(value) {
|
|
32
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Normalize one parsed `targets.<name>` entry into the frozen `Target` shape
|
|
36
|
+
* the substrate registry holds — defaulting `exclude` to {@link DEFAULT_EXCLUDES}
|
|
37
|
+
* and freezing every array, matching the fitness loader's `buildFromParsed`.
|
|
38
|
+
*/
|
|
39
|
+
function toTarget(name, entry) {
|
|
40
|
+
const config = Object.freeze({
|
|
41
|
+
name,
|
|
42
|
+
description: entry.description,
|
|
43
|
+
include: Object.freeze([...entry.include]),
|
|
44
|
+
exclude: Object.freeze([...(entry.exclude ?? DEFAULT_EXCLUDES)]),
|
|
45
|
+
...(entry.tags && { tags: Object.freeze([...entry.tags]) }),
|
|
46
|
+
...(entry.languages && { languages: Object.freeze([...entry.languages]) }),
|
|
47
|
+
...(entry.concerns && { concerns: Object.freeze([...entry.concerns]) }),
|
|
48
|
+
});
|
|
49
|
+
return Object.freeze({ config });
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Build the host's `scope.targets` resolver from the validated config document.
|
|
53
|
+
*
|
|
54
|
+
* Takes the SAME validated document the single sanctioned reader
|
|
55
|
+
* (`composeAndValidateToolConfig`) already produced — this is a pure builder, it
|
|
56
|
+
* never reads the config file itself (ADR-0023: one reader). The host-owned
|
|
57
|
+
* `targets:` / `globalExcludes:` namespaces were strict-validated whole-document
|
|
58
|
+
* by the composed schema; they are re-parsed here through the same field schemas
|
|
59
|
+
* only to recover their narrowed types (idempotent on already-validated data, no
|
|
60
|
+
* I/O), then each target is registered into a substrate `TargetRegistry` and
|
|
61
|
+
* wrapped in a `TargetResolver` with the bound `resolveTargets` /
|
|
62
|
+
* `applyGlobalExcludes` closures.
|
|
63
|
+
*
|
|
64
|
+
* @param args.document The validated config document from
|
|
65
|
+
* `composeAndValidateToolConfig`, or an empty object for a config-less run.
|
|
66
|
+
* @returns The `TargetResolver` to attach to `scope.targets`, or `undefined`
|
|
67
|
+
* when there is no config document or no `targets:` block to resolve.
|
|
68
|
+
*/
|
|
69
|
+
export function buildTargets(args) {
|
|
70
|
+
const { document } = args;
|
|
71
|
+
if (!isPlainObject(document))
|
|
72
|
+
return undefined;
|
|
73
|
+
// No `targets:` block → no resolver. A document may carry only tool config
|
|
74
|
+
// (graph/sim namespaces) with no file targeting, exactly like a config-less run.
|
|
75
|
+
if (document.targets === undefined)
|
|
76
|
+
return undefined;
|
|
77
|
+
let targetsRecord;
|
|
78
|
+
try {
|
|
79
|
+
targetsRecord = targetsRecordSchema.parse(document.targets);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
83
|
+
throw new ConfigurationError(`Invalid 'targets:' block in opensip-cli.config.yml: ${detail}`, {
|
|
84
|
+
code: 'CONFIGURATION.TARGETS.INVALID',
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
let globalExcludes;
|
|
88
|
+
try {
|
|
89
|
+
globalExcludes = Object.freeze(document.globalExcludes === undefined
|
|
90
|
+
? []
|
|
91
|
+
: [...globalExcludesSchema.parse(document.globalExcludes)]);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
95
|
+
throw new ConfigurationError(`Invalid 'globalExcludes:' block in opensip-cli.config.yml: ${detail}`, { code: 'CONFIGURATION.TARGETS.INVALID' });
|
|
96
|
+
}
|
|
97
|
+
const registry = new TargetRegistry();
|
|
98
|
+
for (const [name, entry] of Object.entries(targetsRecord)) {
|
|
99
|
+
registry.register(toTarget(name, entry));
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
getByName: (name) => registry.getByName(name),
|
|
103
|
+
// @fitness-ignore-next-line batch-operation-limits -- getAll() over the project's declared target set (a handful of named file-sets per config document), bounded like core's tool registry getAll.
|
|
104
|
+
getAll: () => registry.getAll(),
|
|
105
|
+
getByTag: (tag) => registry.getByTag(tag),
|
|
106
|
+
has: (name) => registry.has(name),
|
|
107
|
+
resolveTargets: (names, rootDir) => {
|
|
108
|
+
const resolved = names
|
|
109
|
+
.map((name) => registry.getByName(name))
|
|
110
|
+
.filter((t) => t !== undefined);
|
|
111
|
+
return resolveTargets(resolved, rootDir, globalExcludes);
|
|
112
|
+
},
|
|
113
|
+
applyGlobalExcludes: (files, rootDir) => applyGlobalExcludes(files, rootDir, globalExcludes),
|
|
114
|
+
globalExcludes,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=build-targets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-targets.js","sourceRoot":"","sources":["../../src/bootstrap/build-targets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cli-defaults — read the `cli:` block from
|
|
3
|
+
* `opensip-cli.config.yml` and merge it into Commander-parsed opts.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from `index.ts` so the merge precedence is testable and the
|
|
6
|
+
* bootstrap module owns config-resolution end-to-end. Order is
|
|
7
|
+
* load → merge → derive (silent/debug) so flag-driven log mode reflects
|
|
8
|
+
* the merged opts (F10).
|
|
9
|
+
*
|
|
10
|
+
* The schema + loader live in `@opensip-cli/config`
|
|
11
|
+
* (`loadCliDefaults`, `cliConfigSchema`) — the `cli:` block is
|
|
12
|
+
* tool-agnostic and a project shipping only `simulation` shouldn't need
|
|
13
|
+
* fitness installed just to read its own CLI defaults. Relocated out of
|
|
14
|
+
* `@opensip-cli/contracts` in the launch contract (ADR-0023; restores contracts
|
|
15
|
+
* types-only). Audit 2026-05-23 G2.
|
|
16
|
+
*/
|
|
17
|
+
import type { CliDefaults } from '@opensip-cli/config';
|
|
18
|
+
export type { CliDefaults } from '@opensip-cli/config';
|
|
19
|
+
/**
|
|
20
|
+
* Best-effort load of the `cli:` block. Falls back to `{}` when the
|
|
21
|
+
* config is missing or malformed — config-presence is optional. The
|
|
22
|
+
* underlying loader (in `@opensip-cli/contracts`) is already
|
|
23
|
+
* permissive on every failure path; the wrapper here exists so the
|
|
24
|
+
* absence path emits a structured debug log keyed against `cli:` (the
|
|
25
|
+
* contracts loader stays dependency-light and doesn't reach for the
|
|
26
|
+
* logger).
|
|
27
|
+
*/
|
|
28
|
+
export declare function loadCliDefaults(cwd: string, explicitConfigPath?: string): CliDefaults;
|
|
29
|
+
/**
|
|
30
|
+
* Apply the `cli:` defaults onto Commander-parsed opts when the
|
|
31
|
+
* corresponding flag wasn't supplied. Mutates `opts` in place — matches
|
|
32
|
+
* Commander's expectation that opts are the post-merge truth.
|
|
33
|
+
*/
|
|
34
|
+
export declare function mergeConfigDefaults(opts: Record<string, unknown>, config: CliDefaults): void;
|
|
35
|
+
//# sourceMappingURL=cli-defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-defaults.d.ts","sourceRoot":"","sources":["../../src/bootstrap/cli-defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIvD,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,MAAM,GAAG,WAAW,CAarF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAa5F"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cli-defaults — read the `cli:` block from
|
|
3
|
+
* `opensip-cli.config.yml` and merge it into Commander-parsed opts.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from `index.ts` so the merge precedence is testable and the
|
|
6
|
+
* bootstrap module owns config-resolution end-to-end. Order is
|
|
7
|
+
* load → merge → derive (silent/debug) so flag-driven log mode reflects
|
|
8
|
+
* the merged opts (F10).
|
|
9
|
+
*
|
|
10
|
+
* The schema + loader live in `@opensip-cli/config`
|
|
11
|
+
* (`loadCliDefaults`, `cliConfigSchema`) — the `cli:` block is
|
|
12
|
+
* tool-agnostic and a project shipping only `simulation` shouldn't need
|
|
13
|
+
* fitness installed just to read its own CLI defaults. Relocated out of
|
|
14
|
+
* `@opensip-cli/contracts` in the launch contract (ADR-0023; restores contracts
|
|
15
|
+
* types-only). Audit 2026-05-23 G2.
|
|
16
|
+
*/
|
|
17
|
+
import { loadCliDefaults as loadCliDefaultsFromConfig, resolveApiKey } from '@opensip-cli/config';
|
|
18
|
+
import { logger } from '@opensip-cli/core';
|
|
19
|
+
/**
|
|
20
|
+
* Best-effort load of the `cli:` block. Falls back to `{}` when the
|
|
21
|
+
* config is missing or malformed — config-presence is optional. The
|
|
22
|
+
* underlying loader (in `@opensip-cli/contracts`) is already
|
|
23
|
+
* permissive on every failure path; the wrapper here exists so the
|
|
24
|
+
* absence path emits a structured debug log keyed against `cli:` (the
|
|
25
|
+
* contracts loader stays dependency-light and doesn't reach for the
|
|
26
|
+
* logger).
|
|
27
|
+
*/
|
|
28
|
+
export function loadCliDefaults(cwd, explicitConfigPath) {
|
|
29
|
+
try {
|
|
30
|
+
return loadCliDefaultsFromConfig(cwd, explicitConfigPath);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
34
|
+
logger.debug({
|
|
35
|
+
evt: 'cli.config.unavailable',
|
|
36
|
+
module: 'cli',
|
|
37
|
+
cwd,
|
|
38
|
+
error: message,
|
|
39
|
+
});
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Apply the `cli:` defaults onto Commander-parsed opts when the
|
|
45
|
+
* corresponding flag wasn't supplied. Mutates `opts` in place — matches
|
|
46
|
+
* Commander's expectation that opts are the post-merge truth.
|
|
47
|
+
*/
|
|
48
|
+
export function mergeConfigDefaults(opts, config) {
|
|
49
|
+
// NOTE (ADR-0022): `recipe` is deliberately NOT a cli-wide default. Recipe
|
|
50
|
+
// defaults are tool-scoped — `fit`/`graph`/`sim` own disjoint recipe
|
|
51
|
+
// namespaces, so `opts.recipe` reflects only the explicit `--recipe` flag.
|
|
52
|
+
if (config.verbose && opts.verbose === false)
|
|
53
|
+
opts.verbose = config.verbose;
|
|
54
|
+
if (config.json && opts.json === false)
|
|
55
|
+
opts.json = config.json;
|
|
56
|
+
if (config.reportTo && opts.reportTo === undefined)
|
|
57
|
+
opts.reportTo = config.reportTo;
|
|
58
|
+
if (config.exclude && Array.isArray(opts.exclude) && opts.exclude.length === 0) {
|
|
59
|
+
opts.exclude.push(...config.exclude);
|
|
60
|
+
}
|
|
61
|
+
if (opts.apiKey === undefined) {
|
|
62
|
+
opts.apiKey = config.apiKey ?? resolveApiKey();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=cli-defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-defaults.js","sourceRoot":"","sources":["../../src/bootstrap/cli-defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,eAAe,IAAI,yBAAyB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAClG,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAQ3C;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,kBAA2B;IACtE,IAAI,CAAC;QACH,OAAO,yBAAyB,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,CAAC,KAAK,CAAC;YACX,GAAG,EAAE,wBAAwB;YAC7B,MAAM,EAAE,KAAK;YACb,GAAG;YACH,KAAK,EAAE,OAAO;SACf,CAAC,CAAC;QACH,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAA6B,EAAE,MAAmB;IACpF,2EAA2E;IAC3E,qEAAqE;IACrE,2EAA2E;IAC3E,IAAI,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK;QAAE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC5E,IAAI,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK;QAAE,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IAChE,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACpF,IAAI,MAAM,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAK,IAAI,CAAC,OAAoB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5F,IAAI,CAAC,OAAoB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,aAAa,EAAE,CAAC;IACjD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* config-and-capabilities — the pre-dispatch composition seam for the
|
|
3
|
+
* capability-configuration release (ADR-0023 / §5.3, Phase 4).
|
|
4
|
+
*
|
|
5
|
+
* Two host responsibilities the composition root owns once per run, extracted
|
|
6
|
+
* from the pre-action-hook to keep that hook within its complexity budget:
|
|
7
|
+
*
|
|
8
|
+
* 1. {@link composeAndValidateToolConfig} — gather every registered tool's
|
|
9
|
+
* contributed `ToolConfigDeclaration`, compose them into ONE strict
|
|
10
|
+
* whole-document schema, validate the parsed `opensip-cli.config.yml`
|
|
11
|
+
* STRICT before any command runs (a typo in ANY tool namespace throws a
|
|
12
|
+
* single `ConfigurationError` → `CONFIGURATION_ERROR` exit through the
|
|
13
|
+
* existing error boundary), then resolve precedence (flag > env > file >
|
|
14
|
+
* defaults) and return the resolved config to attach to the scope.
|
|
15
|
+
*
|
|
16
|
+
* 2. {@link wireCapabilityRegistry} — construct the per-run capability
|
|
17
|
+
* registry, register every admitted manifest's declared domains (each
|
|
18
|
+
* seeded with a DEFERRED placeholder registrar), then replace each
|
|
19
|
+
* placeholder with the owning tool's REAL registrar
|
|
20
|
+
* (`tool.capabilityRegistrars`). The host routes by domain; the tool owns
|
|
21
|
+
* the registrar.
|
|
22
|
+
*
|
|
23
|
+
* This module is the ONE place the CLI imports `@opensip-cli/config` (the
|
|
24
|
+
* composer + precedence resolver). Tools never import it; they read their
|
|
25
|
+
* validated namespace off `scope.toolConfig`.
|
|
26
|
+
*/
|
|
27
|
+
import { type CapabilityRegistry, type ResolvedToolConfig, type ToolPluginManifest, type ToolRegistry } from '@opensip-cli/core';
|
|
28
|
+
/**
|
|
29
|
+
* Compose + strict-validate the config document, then resolve precedence.
|
|
30
|
+
*
|
|
31
|
+
* Reads the project config file (when one exists), composes the registered
|
|
32
|
+
* tools' schemas, validates STRICT (rejecting a typo inside any tool
|
|
33
|
+
* namespace), and resolves precedence. Returns `undefined` when there is no
|
|
34
|
+
* config document to validate (a project-agnostic command or a config-less
|
|
35
|
+
* project) — the scope then carries no `toolConfig` and tools fall back to
|
|
36
|
+
* their in-tool defaults.
|
|
37
|
+
*
|
|
38
|
+
* @param tools The per-run tool registry (supplies the contributed schemas).
|
|
39
|
+
* @param configPath The resolved path to `opensip-cli.config.yml`, or
|
|
40
|
+
* `undefined` when the run has no config document.
|
|
41
|
+
* @param env The environment map for env-binding precedence (typically
|
|
42
|
+
* `process.env`).
|
|
43
|
+
* @returns The resolved tool config to attach to the scope, or `undefined`.
|
|
44
|
+
* @throws {ConfigurationError} (`CONFIGURATION_ERROR`) when the document fails
|
|
45
|
+
* strict validation in ANY tool namespace.
|
|
46
|
+
*/
|
|
47
|
+
export declare function composeAndValidateToolConfig(args: {
|
|
48
|
+
readonly tools: ToolRegistry;
|
|
49
|
+
readonly manifests?: readonly ToolPluginManifest[];
|
|
50
|
+
readonly configPath: string | undefined;
|
|
51
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
52
|
+
}): {
|
|
53
|
+
readonly config: ResolvedToolConfig | undefined;
|
|
54
|
+
readonly document: unknown;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Construct + populate the per-run capability registry (§5.3, Phase 4).
|
|
58
|
+
*
|
|
59
|
+
* Registers every admitted manifest's declared capability domains (each with
|
|
60
|
+
* a deferred placeholder registrar), then replaces each placeholder with the
|
|
61
|
+
* owning tool's REAL registrar from `tool.capabilityRegistrars`. A registrar
|
|
62
|
+
* for a domain the tool's manifest did not declare is skipped (the host only
|
|
63
|
+
* wires registrars for declared domains).
|
|
64
|
+
*
|
|
65
|
+
* @param tools The per-run tool registry (supplies each tool's real registrars).
|
|
66
|
+
* @param manifests The admitted manifests (supply the declared domains).
|
|
67
|
+
* @returns The populated registry, ready to attach to `scope.capabilities`.
|
|
68
|
+
*/
|
|
69
|
+
export declare function wireCapabilityRegistry(args: {
|
|
70
|
+
readonly tools: ToolRegistry;
|
|
71
|
+
readonly manifests: readonly ToolPluginManifest[];
|
|
72
|
+
readonly registry: CapabilityRegistry;
|
|
73
|
+
}): CapabilityRegistry;
|
|
74
|
+
//# sourceMappingURL=config-and-capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-and-capabilities.d.ts","sourceRoot":"","sources":["../../src/bootstrap/config-and-capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAWH,OAAO,EACL,KAAK,kBAAkB,EAIvB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EAElB,MAAM,mBAAmB,CAAC;AA2E3B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IACjD,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACnD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;CAC5D,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAuDlF;AA2CD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;CACvC,GAAG,kBAAkB,CAuBrB"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* config-and-capabilities — the pre-dispatch composition seam for the
|
|
3
|
+
* capability-configuration release (ADR-0023 / §5.3, Phase 4).
|
|
4
|
+
*
|
|
5
|
+
* Two host responsibilities the composition root owns once per run, extracted
|
|
6
|
+
* from the pre-action-hook to keep that hook within its complexity budget:
|
|
7
|
+
*
|
|
8
|
+
* 1. {@link composeAndValidateToolConfig} — gather every registered tool's
|
|
9
|
+
* contributed `ToolConfigDeclaration`, compose them into ONE strict
|
|
10
|
+
* whole-document schema, validate the parsed `opensip-cli.config.yml`
|
|
11
|
+
* STRICT before any command runs (a typo in ANY tool namespace throws a
|
|
12
|
+
* single `ConfigurationError` → `CONFIGURATION_ERROR` exit through the
|
|
13
|
+
* existing error boundary), then resolve precedence (flag > env > file >
|
|
14
|
+
* defaults) and return the resolved config to attach to the scope.
|
|
15
|
+
*
|
|
16
|
+
* 2. {@link wireCapabilityRegistry} — construct the per-run capability
|
|
17
|
+
* registry, register every admitted manifest's declared domains (each
|
|
18
|
+
* seeded with a DEFERRED placeholder registrar), then replace each
|
|
19
|
+
* placeholder with the owning tool's REAL registrar
|
|
20
|
+
* (`tool.capabilityRegistrars`). The host routes by domain; the tool owns
|
|
21
|
+
* the registrar.
|
|
22
|
+
*
|
|
23
|
+
* This module is the ONE place the CLI imports `@opensip-cli/config` (the
|
|
24
|
+
* composer + precedence resolver). Tools never import it; they read their
|
|
25
|
+
* validated namespace off `scope.toolConfig`.
|
|
26
|
+
*/
|
|
27
|
+
import { analyzeNamespaceClaims, composeConfigSchema, hostConfigDeclarations, resolveConfig, validateConfigDocument, } from '@opensip-cli/config';
|
|
28
|
+
import { ConfigurationError, logger, readYamlFileOrThrow, registerCapabilityDomainsFromManifest, } from '@opensip-cli/core';
|
|
29
|
+
/** A plain-object guard that treats arrays and null as non-objects. */
|
|
30
|
+
function isPlainObject(value) {
|
|
31
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Collect the contributed config declarations from the registered tools. A
|
|
35
|
+
* tool's `config` slot is the kernel-side `ToolConfigContribution` carrier; it
|
|
36
|
+
* is structurally a `ToolConfigDeclaration` (the schema is `unknown` at the
|
|
37
|
+
* kernel boundary, a Zod schema at the config layer), so narrowing it here —
|
|
38
|
+
* the composition root, which DOES import `@opensip-cli/config` — is sound.
|
|
39
|
+
*/
|
|
40
|
+
function collectDeclarations(tools) {
|
|
41
|
+
const declarations = [];
|
|
42
|
+
for (const tool of tools.list()) {
|
|
43
|
+
if (tool.config !== undefined) {
|
|
44
|
+
declarations.push(tool.config);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return declarations;
|
|
48
|
+
}
|
|
49
|
+
function addPluginConfigKey(keys, key, kind) {
|
|
50
|
+
if (key === undefined)
|
|
51
|
+
return;
|
|
52
|
+
const existing = keys.get(key);
|
|
53
|
+
if (existing !== undefined && existing !== kind) {
|
|
54
|
+
throw new ConfigurationError(`Plugin config key '${key}' is declared with conflicting value kinds (${existing}, ${kind}).`, { code: 'CONFIGURATION_ERROR', namespace: 'plugins' });
|
|
55
|
+
}
|
|
56
|
+
keys.set(key, kind);
|
|
57
|
+
}
|
|
58
|
+
function collectPluginConfigKeys(manifests) {
|
|
59
|
+
const keys = new Map();
|
|
60
|
+
for (const manifest of manifests) {
|
|
61
|
+
for (const capability of manifest.capabilities ?? []) {
|
|
62
|
+
const configKeys = capability.discovery?.configKeys;
|
|
63
|
+
if (configKeys === undefined)
|
|
64
|
+
continue;
|
|
65
|
+
addPluginConfigKey(keys, configKeys.packages, 'packages');
|
|
66
|
+
addPluginConfigKey(keys, configKeys.autoDiscover, 'autoDiscover');
|
|
67
|
+
addPluginConfigKey(keys, configKeys.scopes, 'scopes');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return [...keys.entries()].map(([key, kind]) => ({ key, kind }));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Project the validated document's per-namespace blocks into the `file`
|
|
74
|
+
* precedence source (`namespace -> { key -> value }`). Only the declared
|
|
75
|
+
* namespaces are read; unclaimed top-level keys (cli/targets/globalExcludes)
|
|
76
|
+
* are not this resolver's concern.
|
|
77
|
+
*/
|
|
78
|
+
function fileBlocksFor(declarations, validated) {
|
|
79
|
+
const file = {};
|
|
80
|
+
if (!isPlainObject(validated))
|
|
81
|
+
return file;
|
|
82
|
+
for (const decl of declarations) {
|
|
83
|
+
const block = validated[decl.namespace];
|
|
84
|
+
if (isPlainObject(block))
|
|
85
|
+
file[decl.namespace] = block;
|
|
86
|
+
}
|
|
87
|
+
return file;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Compose + strict-validate the config document, then resolve precedence.
|
|
91
|
+
*
|
|
92
|
+
* Reads the project config file (when one exists), composes the registered
|
|
93
|
+
* tools' schemas, validates STRICT (rejecting a typo inside any tool
|
|
94
|
+
* namespace), and resolves precedence. Returns `undefined` when there is no
|
|
95
|
+
* config document to validate (a project-agnostic command or a config-less
|
|
96
|
+
* project) — the scope then carries no `toolConfig` and tools fall back to
|
|
97
|
+
* their in-tool defaults.
|
|
98
|
+
*
|
|
99
|
+
* @param tools The per-run tool registry (supplies the contributed schemas).
|
|
100
|
+
* @param configPath The resolved path to `opensip-cli.config.yml`, or
|
|
101
|
+
* `undefined` when the run has no config document.
|
|
102
|
+
* @param env The environment map for env-binding precedence (typically
|
|
103
|
+
* `process.env`).
|
|
104
|
+
* @returns The resolved tool config to attach to the scope, or `undefined`.
|
|
105
|
+
* @throws {ConfigurationError} (`CONFIGURATION_ERROR`) when the document fails
|
|
106
|
+
* strict validation in ANY tool namespace.
|
|
107
|
+
*/
|
|
108
|
+
export function composeAndValidateToolConfig(args) {
|
|
109
|
+
const { tools, configPath, env, manifests = [] } = args;
|
|
110
|
+
const toolDeclarations = collectDeclarations(tools);
|
|
111
|
+
// A run with no tools that declare config (e.g. a project-agnostic context)
|
|
112
|
+
// carries no toolConfig — tools fall back to their in-tool defaults. The host
|
|
113
|
+
// document-level blocks (cli/dashboard/schemaVersion) only need composing when
|
|
114
|
+
// there is a tool dispatch to validate the document for; the real CLI always
|
|
115
|
+
// registers fit/graph/sim, so they are always composed in practice.
|
|
116
|
+
if (toolDeclarations.length === 0)
|
|
117
|
+
return { config: undefined, document: {} };
|
|
118
|
+
// Compose the host document-level declarations (cli/dashboard/schemaVersion,
|
|
119
|
+
// and from Phase 1 the targeting blocks) BESIDE the tool declarations, so the
|
|
120
|
+
// whole document — not just the tool namespaces — validates STRICT through the
|
|
121
|
+
// one composed schema (ADR-0023, the launch seam).
|
|
122
|
+
const declarations = [
|
|
123
|
+
...hostConfigDeclarations({ pluginConfigKeys: collectPluginConfigKeys(manifests) }),
|
|
124
|
+
...toolDeclarations,
|
|
125
|
+
];
|
|
126
|
+
// When a configPath was resolved by the project context (i.e. a real
|
|
127
|
+
// opensip-cli.config.yml or a package.json pointer), read it *strictly*.
|
|
128
|
+
// Malformed YAML or unreadable file must fail before any dispatch (a
|
|
129
|
+
// silent `{}` would bypass targets, gates, cloud settings, etc.).
|
|
130
|
+
// When no configPath, fall back to defaults only (permissive discovery
|
|
131
|
+
// paths elsewhere still use the non-throwing reader).
|
|
132
|
+
const raw = configPath === undefined ? {} : readYamlFileOrThrow(configPath, { loader: 'project-config' });
|
|
133
|
+
const document = isPlainObject(raw) ? raw : {};
|
|
134
|
+
const schema = composeConfigSchema(declarations);
|
|
135
|
+
// STRICT gate: a typo in any tool namespace throws ConfigurationError here,
|
|
136
|
+
// before dispatch. The CLI error boundary maps it to CONFIGURATION_ERROR.
|
|
137
|
+
const validated = validateConfigDocument(schema, document);
|
|
138
|
+
// ADR-0043: the composer TOLERATES unclaimed top-level namespaces (the
|
|
139
|
+
// uninstalled-tool forward-compat contract) — but never silently. Two cases:
|
|
140
|
+
// - the namespace equals a LOADED tool's id → that tool declares no
|
|
141
|
+
// Tool.config yet its block exists: a tool-authoring bug, hard-reject;
|
|
142
|
+
// - otherwise → warn loudly (structured event + stderr for CI), with a
|
|
143
|
+
// did-you-mean when the key is edit-distance-close to a claimed one.
|
|
144
|
+
reportUnclaimedNamespaces({ declarations, document: validated, tools });
|
|
145
|
+
// The validated document is returned alongside the resolved config so the
|
|
146
|
+
// host can build the targeting substrate (`buildTargets`) from the SAME
|
|
147
|
+
// single validated read — no second `readYamlFile` (ADR-0023 one-reader).
|
|
148
|
+
// `targets`/`globalExcludes` are host namespaces validated by the composed
|
|
149
|
+
// schema; `buildTargets` is a pure builder over them, never a reader.
|
|
150
|
+
return {
|
|
151
|
+
config: resolveConfig({
|
|
152
|
+
declarations,
|
|
153
|
+
file: fileBlocksFor(declarations, validated),
|
|
154
|
+
env,
|
|
155
|
+
}),
|
|
156
|
+
document: validated,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The ADR-0043 unclaimed-namespace policy: reject a LOADED tool's undeclared
|
|
161
|
+
* block; warn (event + stderr, once per namespace per run) on the rest.
|
|
162
|
+
*
|
|
163
|
+
* @throws {ConfigurationError} when an unclaimed namespace equals a loaded
|
|
164
|
+
* tool's id — the block exists but the tool cannot consume it.
|
|
165
|
+
*/
|
|
166
|
+
function reportUnclaimedNamespaces(args) {
|
|
167
|
+
const report = analyzeNamespaceClaims(args.declarations, args.document);
|
|
168
|
+
if (report.unclaimed.length === 0)
|
|
169
|
+
return;
|
|
170
|
+
const loadedToolNames = new Set(args.tools.list().map((t) => t.metadata.name ?? t.metadata.id));
|
|
171
|
+
const toolBugs = report.unclaimed.filter((u) => loadedToolNames.has(u.namespace));
|
|
172
|
+
if (toolBugs.length > 0) {
|
|
173
|
+
const names = toolBugs.map((u) => `'${u.namespace}'`).join(', ');
|
|
174
|
+
throw new ConfigurationError(`Config declares ${names} but the loaded tool(s) of the same id contribute no Tool.config — ` +
|
|
175
|
+
`the block can never apply. Remove the block or fix the tool's config contribution. (ADR-0043)`, { code: 'CONFIGURATION_ERROR' });
|
|
176
|
+
}
|
|
177
|
+
for (const u of report.unclaimed) {
|
|
178
|
+
const didYouMean = u.suggestion === undefined ? '' : ` — did you mean '${u.suggestion}:'?`;
|
|
179
|
+
logger.warn({
|
|
180
|
+
evt: 'cli.config.unclaimed_namespace',
|
|
181
|
+
module: 'cli:bootstrap',
|
|
182
|
+
namespace: u.namespace,
|
|
183
|
+
suggestion: u.suggestion,
|
|
184
|
+
});
|
|
185
|
+
process.stderr.write(`opensip: config namespace '${u.namespace}:' is not claimed by any loaded tool${didYouMean} ` +
|
|
186
|
+
`(expected if that tool isn't installed in this project)\n`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Construct + populate the per-run capability registry (§5.3, Phase 4).
|
|
191
|
+
*
|
|
192
|
+
* Registers every admitted manifest's declared capability domains (each with
|
|
193
|
+
* a deferred placeholder registrar), then replaces each placeholder with the
|
|
194
|
+
* owning tool's REAL registrar from `tool.capabilityRegistrars`. A registrar
|
|
195
|
+
* for a domain the tool's manifest did not declare is skipped (the host only
|
|
196
|
+
* wires registrars for declared domains).
|
|
197
|
+
*
|
|
198
|
+
* @param tools The per-run tool registry (supplies each tool's real registrars).
|
|
199
|
+
* @param manifests The admitted manifests (supply the declared domains).
|
|
200
|
+
* @returns The populated registry, ready to attach to `scope.capabilities`.
|
|
201
|
+
*/
|
|
202
|
+
export function wireCapabilityRegistry(args) {
|
|
203
|
+
const { tools, manifests, registry } = args;
|
|
204
|
+
// 1. Register every manifest-declared domain with a deferred placeholder.
|
|
205
|
+
for (const manifest of manifests) {
|
|
206
|
+
registerCapabilityDomainsFromManifest(manifest, registry);
|
|
207
|
+
}
|
|
208
|
+
// 2. Replace each placeholder with the owning tool's real registrar. A
|
|
209
|
+
// registrar whose domain id was not declared in any manifest is skipped
|
|
210
|
+
// (hasDomain false) — the host never invents a domain a tool didn't
|
|
211
|
+
// declare.
|
|
212
|
+
for (const tool of tools.list()) {
|
|
213
|
+
const registrars = tool.capabilityRegistrars;
|
|
214
|
+
if (registrars === undefined)
|
|
215
|
+
continue;
|
|
216
|
+
for (const [domainId, registrar] of Object.entries(registrars)) {
|
|
217
|
+
if (registry.hasDomain(domainId)) {
|
|
218
|
+
registry.setRegistrar(domainId, registrar);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return registry;
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=config-and-capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-and-capabilities.js","sourceRoot":"","sources":["../../src/bootstrap/config-and-capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deliver-envelope — the composition root's signal-delivery step (ADR-0011,
|
|
3
|
+
* Phase 3).
|
|
4
|
+
*
|
|
5
|
+
* After a tool returns its {@link SignalEnvelope}, the root — not the tool —
|
|
6
|
+
* delivers it to the effectful sinks:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Cloud sync (best-effort).** Map the envelope → `SignalBatch`
|
|
9
|
+
* (`@opensip-cli/core` `buildSignalBatch`, adding repo identity and
|
|
10
|
+
* preserving the envelope's `runId`/`createdAt`; dropping `verdict`/`units`
|
|
11
|
+
* — the cloud wire shape stays `schemaVersion: 1`) and emit it through the
|
|
12
|
+
* run's `scope.signalSink`. The sink is a no-op for the keyless / not-
|
|
13
|
+
* entitled majority. NEVER throws, NEVER affects the exit code (ADR-0008).
|
|
14
|
+
* Ships the envelope's signals as-is — **no SARIF detour** on this path.
|
|
15
|
+
*
|
|
16
|
+
* 2. **`--report-to` (owns exit code 4).** When `reportTo` is set, format the
|
|
17
|
+
* envelope to SARIF via the single shared `formatSignalSarif` formatter and
|
|
18
|
+
* POST it through the shared chunked transport (`postChunked`). An upload
|
|
19
|
+
* failure exits `EXIT_CODES.REPORT_FAILED` (4) — but only when the run
|
|
20
|
+
* otherwise passed; a real check/gate failure (`runFailed`) dominates and
|
|
21
|
+
* is never masked by a reporting failure (ADR-0008).
|
|
22
|
+
*
|
|
23
|
+
* This is the seam that keeps tool engines free of `@opensip-cli/output`:
|
|
24
|
+
* engines return envelopes, and the composition root owns formatting,
|
|
25
|
+
* delivery, and report-upload exit-code policy.
|
|
26
|
+
*/
|
|
27
|
+
import type { SignalEnvelope } from '@opensip-cli/contracts';
|
|
28
|
+
import type { Logger, RepoIdentity, SignalBatch, SignalDeliveryResult } from '@opensip-cli/core';
|
|
29
|
+
/** Options the root supplies when delivering a tool's envelope. */
|
|
30
|
+
export interface DeliverEnvelopeOptions {
|
|
31
|
+
/** Project / repo working directory — the repo-identity probe root. */
|
|
32
|
+
readonly cwd: string;
|
|
33
|
+
/** `--report-to <url>` target, when requested. */
|
|
34
|
+
readonly reportTo?: string;
|
|
35
|
+
/** Cloud API key for `--report-to` (read off the same flag as cloud sync). */
|
|
36
|
+
readonly apiKey?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Optional override for the findings-failure decision (ADR-0035). Normal runs
|
|
39
|
+
* OMIT this — the host derives the findings exit from `envelope.verdict.passed`
|
|
40
|
+
* (the single verdict). The gate-COMPARE modes pass their baseline-diff
|
|
41
|
+
* predicate (`degraded`): "net-new findings since baseline" is NOT expressible
|
|
42
|
+
* over the run's own verdict, so the host honours the override for that mode.
|
|
43
|
+
*/
|
|
44
|
+
readonly runFailed?: boolean;
|
|
45
|
+
/** Exit-code setter (the CLI's single write path). */
|
|
46
|
+
readonly setExitCode?: (code: number) => void;
|
|
47
|
+
/** Pre-resolved repo identity; resolved from `cwd` when omitted. */
|
|
48
|
+
readonly repo?: RepoIdentity;
|
|
49
|
+
readonly logger?: Logger;
|
|
50
|
+
/** Injectable `fetch` for the `--report-to` upload (tests). */
|
|
51
|
+
readonly fetchImpl?: typeof fetch;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Outcome of an envelope delivery. The canonical shape is core's
|
|
55
|
+
* {@link SignalDeliveryResult} (the `ToolCliContext.deliverSignals` return);
|
|
56
|
+
* this alias keeps the historical local name for existing imports.
|
|
57
|
+
*/
|
|
58
|
+
export type DeliverEnvelopeResult = SignalDeliveryResult;
|
|
59
|
+
/**
|
|
60
|
+
* Map a {@link SignalEnvelope} to the cloud {@link SignalBatch} wire shape:
|
|
61
|
+
* add repo identity, preserve the run identity, drop `verdict`/`units`.
|
|
62
|
+
*/
|
|
63
|
+
export declare function envelopeToSignalBatch(envelope: SignalEnvelope, repo: RepoIdentity): SignalBatch;
|
|
64
|
+
/**
|
|
65
|
+
* The root's post-run signal-delivery step. Emits the envelope to the cloud
|
|
66
|
+
* sink (best-effort) and, when `--report-to` is set, uploads its SARIF
|
|
67
|
+
* (owning exit code 4). Never throws.
|
|
68
|
+
*/
|
|
69
|
+
export declare function deliverEnvelope(envelope: SignalEnvelope, opts: DeliverEnvelopeOptions): Promise<DeliverEnvelopeResult>;
|
|
70
|
+
/**
|
|
71
|
+
* Root-owned SARIF-**file** sink (ADR-0011): format the envelope to SARIF via
|
|
72
|
+
* the single shared `formatSignalSarif` formatter and write the bytes to
|
|
73
|
+
* `path`, creating parent directories as needed. This is the seam behind
|
|
74
|
+
* `ToolCliContext.writeSarif` — a tool that exports SARIF to a file (e.g.
|
|
75
|
+
* `graph sarif-export`) routes through it instead of importing
|
|
76
|
+
* `@opensip-cli/output` itself. The formatter is pure; this function owns
|
|
77
|
+
* the effect (fs write).
|
|
78
|
+
*/
|
|
79
|
+
export declare function writeEnvelopeSarif(envelope: SignalEnvelope, path: string): Promise<void>;
|
|
80
|
+
//# sourceMappingURL=deliver-envelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deliver-envelope.d.ts","sourceRoot":"","sources":["../../src/bootstrap/deliver-envelope.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAcH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAIjG,mEAAmE;AACnE,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,sDAAsD;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,oEAAoE;IACpE,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,oBAAoB,CAAC;AAEzD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,YAAY,GAAG,WAAW,CAS/F;AA0FD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,qBAAqB,CAAC,CA0EhC;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9F"}
|