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,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* baseline-seams — the host implementations behind the four `ToolCliContext`
|
|
3
|
+
* baseline/ratchet seams (ADR-0036): `saveBaseline`, `compareBaseline`,
|
|
4
|
+
* `exportBaselineSarif`, `exportBaselineFingerprints`.
|
|
5
|
+
*
|
|
6
|
+
* The host owns persistence (`BaselineRepo`), the pure diff (`diffBaseline` from
|
|
7
|
+
* `@opensip-cli/output`), SARIF re-render, and the git-trackable JSON export.
|
|
8
|
+
* The seams are **read-only** of `signal.fingerprint`: the tool stamps its
|
|
9
|
+
* envelope's signals (`stampFingerprints`) at envelope-construction time and the
|
|
10
|
+
* plane NEVER re-fingerprints. Factored out of `cli-context.ts` to keep that
|
|
11
|
+
* file within its size budget.
|
|
12
|
+
*/
|
|
13
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
14
|
+
import { dirname } from 'node:path';
|
|
15
|
+
import { ConfigurationError, SeverityPolicy, } from '@opensip-cli/core';
|
|
16
|
+
import { BaselineRepo } from '@opensip-cli/datastore';
|
|
17
|
+
import { diffBaseline } from '@opensip-cli/output';
|
|
18
|
+
import { writeEnvelopeSarif } from './deliver-envelope.js';
|
|
19
|
+
/** Thrown (→ exit 2) when a gate compare/export runs before any baseline was saved. */
|
|
20
|
+
function missingBaseline(tool) {
|
|
21
|
+
return new ConfigurationError(`No baseline found for '${tool}' in the project SQLite store. If this is a first ` +
|
|
22
|
+
`run — or you upgraded across a release that changed the baseline schema (the ` +
|
|
23
|
+
`per-tool baseline tables were dropped and recaptured, ADR-0036) — run ` +
|
|
24
|
+
`\`opensip-cli ${tool} --gate-save\` to (re)capture one. The git-trackable ` +
|
|
25
|
+
`JSON fingerprint baseline (graph-baseline-export) is a file, not a DB row, and ` +
|
|
26
|
+
`is untouched.`, { code: 'CONFIGURATION.GATE.BASELINE_MISSING' });
|
|
27
|
+
}
|
|
28
|
+
/** Assert each signal carries a fingerprint — the plane never stamps (ADR-0036). */
|
|
29
|
+
// @graph-ignore-next-line graph:always-throws-branch -- not throw-dominated: returns the mapped entries; the throw is a guard fired only when a tool hands unstamped signals (a contract violation the plane must surface).
|
|
30
|
+
function requireStampedEntries(tool, signals) {
|
|
31
|
+
return signals.map((s) => {
|
|
32
|
+
if (!s.fingerprint) {
|
|
33
|
+
throw new ConfigurationError(`saveBaseline(${tool}): signal ${s.ruleId} is not fingerprint-stamped. The tool must ` +
|
|
34
|
+
`stamp its signals (stampFingerprints) before the seam — the plane never fingerprints.`, { code: 'CONFIGURATION.GATE.UNSTAMPED_SIGNAL' });
|
|
35
|
+
}
|
|
36
|
+
return { fingerprint: s.fingerprint, payload: s };
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build the four baseline seams over a lazy datastore resolver. `getDatastore`
|
|
41
|
+
* throws when accessed outside a project scope (the host's existing contract).
|
|
42
|
+
*/
|
|
43
|
+
export function buildBaselineSeams(deps) {
|
|
44
|
+
const { getDatastore, logger } = deps;
|
|
45
|
+
const repoFor = () => new BaselineRepo(getDatastore());
|
|
46
|
+
return {
|
|
47
|
+
// Sync-bodied (SQLite is synchronous) but typed Promise to match the seam
|
|
48
|
+
// contract; a sync throw still rejects for an `await`ing caller.
|
|
49
|
+
saveBaseline: (tool, envelope) => {
|
|
50
|
+
const env = envelope;
|
|
51
|
+
const entries = requireStampedEntries(tool, env.signals);
|
|
52
|
+
repoFor().save(tool, entries);
|
|
53
|
+
logger.info({
|
|
54
|
+
evt: 'cli.baseline.save.complete',
|
|
55
|
+
module: 'cli:baseline-seams',
|
|
56
|
+
tool,
|
|
57
|
+
count: entries.length,
|
|
58
|
+
});
|
|
59
|
+
return Promise.resolve();
|
|
60
|
+
},
|
|
61
|
+
compareBaseline: (tool, envelope) => {
|
|
62
|
+
const repo = repoFor();
|
|
63
|
+
if (!repo.exists(tool))
|
|
64
|
+
return Promise.reject(missingBaseline(tool));
|
|
65
|
+
const env = envelope;
|
|
66
|
+
return Promise.resolve(diffBaseline(env.signals, repo.load(tool)));
|
|
67
|
+
},
|
|
68
|
+
/** @throws {ConfigurationError} (→ exit 2) when no baseline exists for `tool`. */
|
|
69
|
+
// @fitness-ignore-next-line throws-documentation -- contract is in the @throws above + on the ToolCliContext.exportBaselineSarif seam; the check cannot read an object-property arrow's leading JSDoc.
|
|
70
|
+
exportBaselineSarif: async (tool, path) => {
|
|
71
|
+
const repo = repoFor();
|
|
72
|
+
if (!repo.exists(tool))
|
|
73
|
+
throw missingBaseline(tool);
|
|
74
|
+
const capturedAt = repo.capturedAt(tool);
|
|
75
|
+
/* v8 ignore next 3 -- defensive: exists() returned true above (same as fingerprints export) */
|
|
76
|
+
if (capturedAt === undefined) {
|
|
77
|
+
throw new ConfigurationError(`Baseline meta row for '${tool}' missing after exists() reported present.`, { code: 'CONFIGURATION.GATE.BASELINE_INCONSISTENT' });
|
|
78
|
+
}
|
|
79
|
+
const signals = repo
|
|
80
|
+
.load(tool)
|
|
81
|
+
.map((r) => r.payload)
|
|
82
|
+
.filter((s) => s !== null);
|
|
83
|
+
// Compute a minimal but truthful verdict/summary from the captured signals
|
|
84
|
+
// so that SARIF consumers (and any envelope-level logic) see consistent
|
|
85
|
+
// counts instead of an all-zeroes synthetic. This is a reconstruction of
|
|
86
|
+
// historical findings; "passed" here means "the captured set contained no
|
|
87
|
+
// error-severity findings" (matching the spirit of the run verdict).
|
|
88
|
+
let errors = 0;
|
|
89
|
+
let warnings = 0;
|
|
90
|
+
for (const s of signals) {
|
|
91
|
+
if (SeverityPolicy.isError(s.severity))
|
|
92
|
+
errors += 1;
|
|
93
|
+
else
|
|
94
|
+
warnings += 1;
|
|
95
|
+
}
|
|
96
|
+
const summary = {
|
|
97
|
+
total: signals.length,
|
|
98
|
+
passed: signals.length - errors,
|
|
99
|
+
failed: errors,
|
|
100
|
+
errors,
|
|
101
|
+
warnings,
|
|
102
|
+
};
|
|
103
|
+
// SARIF export RECONSTRUCTS (no stored envelope): formatSignalSarif derives
|
|
104
|
+
// results from `signals` + the driver name from `tool` only, so the other
|
|
105
|
+
// envelope fields are mostly inert filler. We now populate a plausible
|
|
106
|
+
// verdict so downstream SARIF or machine consumers are not misled.
|
|
107
|
+
// The runId/createdAt make it obvious this is a reconstruction from a
|
|
108
|
+
// previously captured baseline (units and per-unit facts like filesValidated
|
|
109
|
+
// are not recoverable without storing the full original envelope).
|
|
110
|
+
const synthetic = {
|
|
111
|
+
schemaVersion: 2,
|
|
112
|
+
tool: tool,
|
|
113
|
+
runId: `baseline:${tool}`,
|
|
114
|
+
createdAt: new Date(capturedAt).toISOString(),
|
|
115
|
+
verdict: {
|
|
116
|
+
score: signals.length === 0 ? 1 : summary.passed / summary.total,
|
|
117
|
+
passed: errors === 0,
|
|
118
|
+
summary,
|
|
119
|
+
},
|
|
120
|
+
units: [],
|
|
121
|
+
signals,
|
|
122
|
+
};
|
|
123
|
+
await writeEnvelopeSarif(synthetic, path);
|
|
124
|
+
},
|
|
125
|
+
/** @throws {ConfigurationError} (→ exit 2) when no baseline exists for `tool`. */
|
|
126
|
+
// @fitness-ignore-next-line throws-documentation -- contract is in the @throws above + on the ToolCliContext.exportBaselineFingerprints seam; the check cannot read an object-property arrow's leading JSDoc.
|
|
127
|
+
exportBaselineFingerprints: async (tool, path) => {
|
|
128
|
+
const repo = repoFor();
|
|
129
|
+
if (!repo.exists(tool))
|
|
130
|
+
throw missingBaseline(tool);
|
|
131
|
+
const capturedAt = repo.capturedAt(tool);
|
|
132
|
+
/* v8 ignore next 3 -- defensive: exists() returned true above */
|
|
133
|
+
if (capturedAt === undefined) {
|
|
134
|
+
throw new ConfigurationError(`Baseline meta row for '${tool}' missing after exists() reported present.`, { code: 'CONFIGURATION.GATE.BASELINE_INCONSISTENT' });
|
|
135
|
+
}
|
|
136
|
+
const rows = repo.load(tool);
|
|
137
|
+
const fingerprints = rows.map((r) => r.fingerprint).sort((a, b) => a.localeCompare(b));
|
|
138
|
+
const file = {
|
|
139
|
+
version: '1',
|
|
140
|
+
tool,
|
|
141
|
+
capturedAt: new Date(capturedAt).toISOString(),
|
|
142
|
+
// Reconstruction note: this is a fingerprint list only. It does not
|
|
143
|
+
// contain the original per-unit (check/rule) metadata or validated counts.
|
|
144
|
+
// It is suitable for git-trackable ratchet comparison (graph) and for
|
|
145
|
+
// re-import via --gate-compare style flows that only need identities.
|
|
146
|
+
note: 'reconstructed from baseline entries; units and per-finding details are not preserved',
|
|
147
|
+
signalCount: fingerprints.length,
|
|
148
|
+
fingerprints,
|
|
149
|
+
};
|
|
150
|
+
const serialized = JSON.stringify(file, null, 2);
|
|
151
|
+
await mkdir(dirname(path), { recursive: true });
|
|
152
|
+
await writeFile(path, serialized, 'utf8');
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=baseline-seams.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline-seams.js","sourceRoot":"","sources":["../../src/bootstrap/baseline-seams.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BootstrapError — a typed pre-handler failure thrown by the `preAction` guards
|
|
3
|
+
* instead of writing to a stream + `process.exit()` (launch, §4.7).
|
|
4
|
+
*
|
|
5
|
+
* Bootstrap failures (no project, schema-too-old, config-resolve, tool-init) used
|
|
6
|
+
* to bypass the central renderer: each guard wrote its own message and called
|
|
7
|
+
* `process.exit(n)`, so `--json` produced nothing structured for exactly the
|
|
8
|
+
* highest-friction failures. Now each guard THROWS a `BootstrapError`, and one
|
|
9
|
+
* top-level boundary (the `parseAsync().catch`) renders it through the same
|
|
10
|
+
* `CommandOutcome` seam as every other result — `--json` emits a structured,
|
|
11
|
+
* suggestion-bearing `bootstrap.error` outcome; human mode writes the unchanged
|
|
12
|
+
* formatted message to stderr (byte-identical to the legacy bytes).
|
|
13
|
+
*
|
|
14
|
+
* The error carries BOTH a clean `message` (for the `--json` `errors[].message`)
|
|
15
|
+
* and the original multi-line `humanMessage` (for the byte-identical stderr path),
|
|
16
|
+
* plus an explicit `exitCode` — schema/no-project/config are `2`, a tool-init
|
|
17
|
+
* failure is `1` — so the boundary sets the exit code from the error itself rather
|
|
18
|
+
* than re-deriving it.
|
|
19
|
+
*/
|
|
20
|
+
import { ToolError } from '@opensip-cli/core';
|
|
21
|
+
export interface BootstrapErrorInput {
|
|
22
|
+
/** Clean, single-line message for the structured `--json` outcome. */
|
|
23
|
+
readonly message: string;
|
|
24
|
+
/**
|
|
25
|
+
* The exact multi-line text the guard used to write to stderr. The human
|
|
26
|
+
* boundary writes `${humanMessage}\n` verbatim — preserving the legacy
|
|
27
|
+
* bytes — instead of routing through the Ink error renderer.
|
|
28
|
+
*/
|
|
29
|
+
readonly humanMessage: string;
|
|
30
|
+
/** Actionable next step surfaced in the structured outcome's `errors[].suggestion`. */
|
|
31
|
+
readonly suggestion?: string;
|
|
32
|
+
/** Process exit code (2 for config/no-project, 1 for a tool-init failure). */
|
|
33
|
+
readonly exitCode: number;
|
|
34
|
+
}
|
|
35
|
+
export declare class BootstrapError extends ToolError {
|
|
36
|
+
readonly humanMessage: string;
|
|
37
|
+
readonly suggestion: string | undefined;
|
|
38
|
+
readonly exitCode: number;
|
|
39
|
+
constructor(input: BootstrapErrorInput);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=bootstrap-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap-error.d.ts","sourceRoot":"","sources":["../../src/bootstrap/bootstrap-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,uFAAuF;IACvF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,cAAe,SAAQ,SAAS;IAC3C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,KAAK,EAAE,mBAAmB;CAOvC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BootstrapError — a typed pre-handler failure thrown by the `preAction` guards
|
|
3
|
+
* instead of writing to a stream + `process.exit()` (launch, §4.7).
|
|
4
|
+
*
|
|
5
|
+
* Bootstrap failures (no project, schema-too-old, config-resolve, tool-init) used
|
|
6
|
+
* to bypass the central renderer: each guard wrote its own message and called
|
|
7
|
+
* `process.exit(n)`, so `--json` produced nothing structured for exactly the
|
|
8
|
+
* highest-friction failures. Now each guard THROWS a `BootstrapError`, and one
|
|
9
|
+
* top-level boundary (the `parseAsync().catch`) renders it through the same
|
|
10
|
+
* `CommandOutcome` seam as every other result — `--json` emits a structured,
|
|
11
|
+
* suggestion-bearing `bootstrap.error` outcome; human mode writes the unchanged
|
|
12
|
+
* formatted message to stderr (byte-identical to the legacy bytes).
|
|
13
|
+
*
|
|
14
|
+
* The error carries BOTH a clean `message` (for the `--json` `errors[].message`)
|
|
15
|
+
* and the original multi-line `humanMessage` (for the byte-identical stderr path),
|
|
16
|
+
* plus an explicit `exitCode` — schema/no-project/config are `2`, a tool-init
|
|
17
|
+
* failure is `1` — so the boundary sets the exit code from the error itself rather
|
|
18
|
+
* than re-deriving it.
|
|
19
|
+
*/
|
|
20
|
+
import { ToolError } from '@opensip-cli/core';
|
|
21
|
+
export class BootstrapError extends ToolError {
|
|
22
|
+
humanMessage;
|
|
23
|
+
suggestion;
|
|
24
|
+
exitCode;
|
|
25
|
+
constructor(input) {
|
|
26
|
+
super(input.message, 'CONFIGURATION.BOOTSTRAP');
|
|
27
|
+
this.name = 'BootstrapError';
|
|
28
|
+
this.humanMessage = input.humanMessage;
|
|
29
|
+
this.suggestion = input.suggestion;
|
|
30
|
+
this.exitCode = input.exitCode;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=bootstrap-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap-error.js","sourceRoot":"","sources":["../../src/bootstrap/bootstrap-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAiB9C,MAAM,OAAO,cAAe,SAAQ,SAAS;IAClC,YAAY,CAAS;IACrB,UAAU,CAAqB;IAC/B,QAAQ,CAAS;IAE1B,YAAY,KAA0B;QACpC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,yBAAyB,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QACvC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* build-command-registration-input — thin builder for the data needed by
|
|
3
|
+
* `registerCliCommands` after tool mounting.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from the top-level composition root in `index.ts` (roadmap item 2)
|
|
6
|
+
* to further reduce inline logic in the bootstrap sequencer. This follows the
|
|
7
|
+
* same pattern as `build-per-run-scope.ts`.
|
|
8
|
+
*
|
|
9
|
+
* The host owns "pluginLayouts", "toolScaffolds", "sessionReplayRegistry", and
|
|
10
|
+
* "toolCommandSpecs" preparation so the main entry point stays focused on
|
|
11
|
+
* sequencing (registries, bootstrap, mounting, registration, dispatch).
|
|
12
|
+
*/
|
|
13
|
+
import { SessionReplayRegistry } from '../session-replay-registry.js';
|
|
14
|
+
import type { CommandSpec, PluginLayout, ScaffoldContext, ScaffoldFile, ToolCliContext, ToolRegistry } from '@opensip-cli/core';
|
|
15
|
+
/** The structured input consumed by `registerCliCommands`. */
|
|
16
|
+
export interface CommandRegistrationInput {
|
|
17
|
+
readonly pluginLayouts: readonly NonNullable<PluginLayout>[];
|
|
18
|
+
readonly toolScaffolds: readonly {
|
|
19
|
+
readonly layout: PluginLayout;
|
|
20
|
+
readonly scaffoldExamples: ((ctx: ScaffoldContext) => readonly ScaffoldFile[]) | undefined;
|
|
21
|
+
readonly stableExampleIds: (() => readonly string[]) | undefined;
|
|
22
|
+
readonly scaffoldConfigBlock: (() => string) | undefined;
|
|
23
|
+
}[];
|
|
24
|
+
readonly sessionReplayRegistry: SessionReplayRegistry;
|
|
25
|
+
readonly toolCommandSpecs: readonly CommandSpec<unknown, ToolCliContext>[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Collects the registry-derived data needed for CLI command registration.
|
|
29
|
+
* Emits the ADR-0038 back-compat diagnostic for expected bundled tools that
|
|
30
|
+
* are absent (this warning is intentionally loud when a bundled tool is
|
|
31
|
+
* missing, as it affects `init` scaffolding).
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildCommandRegistrationInput(registry: ToolRegistry): CommandRegistrationInput;
|
|
34
|
+
//# sourceMappingURL=build-command-registration-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-command-registration-input.d.ts","sourceRoot":"","sources":["../../src/bootstrap/build-command-registration-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAItE,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,cAAc,EACd,YAAY,EACb,MAAM,mBAAmB,CAAC;AAE3B,8DAA8D;AAC9D,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,aAAa,EAAE,SAAS,WAAW,CAAC,YAAY,CAAC,EAAE,CAAC;IAC7D,QAAQ,CAAC,aAAa,EAAE,SAAS;QAC/B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;QAC9B,QAAQ,CAAC,gBAAgB,EAAE,CAAC,CAAC,GAAG,EAAE,eAAe,KAAK,SAAS,YAAY,EAAE,CAAC,GAAG,SAAS,CAAC;QAC3F,QAAQ,CAAC,gBAAgB,EAAE,CAAC,MAAM,SAAS,MAAM,EAAE,CAAC,GAAG,SAAS,CAAC;QACjE,QAAQ,CAAC,mBAAmB,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;KAC1D,EAAE,CAAC;IACJ,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;IACtD,QAAQ,CAAC,gBAAgB,EAAE,SAAS,WAAW,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,CAAC;CAC5E;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,YAAY,GAAG,wBAAwB,CAsD9F"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* build-command-registration-input — thin builder for the data needed by
|
|
3
|
+
* `registerCliCommands` after tool mounting.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from the top-level composition root in `index.ts` (roadmap item 2)
|
|
6
|
+
* to further reduce inline logic in the bootstrap sequencer. This follows the
|
|
7
|
+
* same pattern as `build-per-run-scope.ts`.
|
|
8
|
+
*
|
|
9
|
+
* The host owns "pluginLayouts", "toolScaffolds", "sessionReplayRegistry", and
|
|
10
|
+
* "toolCommandSpecs" preparation so the main entry point stays focused on
|
|
11
|
+
* sequencing (registries, bootstrap, mounting, registration, dispatch).
|
|
12
|
+
*/
|
|
13
|
+
import { logger } from '@opensip-cli/core';
|
|
14
|
+
import { SessionReplayRegistry } from '../session-replay-registry.js';
|
|
15
|
+
import { EXPECTED_SCAFFOLDING_TOOL_IDS } from './register-tools.js';
|
|
16
|
+
/**
|
|
17
|
+
* Collects the registry-derived data needed for CLI command registration.
|
|
18
|
+
* Emits the ADR-0038 back-compat diagnostic for expected bundled tools that
|
|
19
|
+
* are absent (this warning is intentionally loud when a bundled tool is
|
|
20
|
+
* missing, as it affects `init` scaffolding).
|
|
21
|
+
*/
|
|
22
|
+
export function buildCommandRegistrationInput(registry) {
|
|
23
|
+
// Source the plugin-supporting domains from the registered tools'
|
|
24
|
+
// declared layouts — the kernel never enumerates them (ADR-0009).
|
|
25
|
+
const pluginLayouts = registry
|
|
26
|
+
.list()
|
|
27
|
+
.map((t) => t.pluginLayout)
|
|
28
|
+
.filter((l) => l !== undefined);
|
|
29
|
+
// ADR-0038: the per-tool `init`-scaffold contributions, sourced from the same
|
|
30
|
+
// registry. `init` iterates these (each tool's pluginLayout + scaffoldExamples)
|
|
31
|
+
// instead of hardcoding fit/sim. A tool with no pluginLayout contributes nothing.
|
|
32
|
+
const toolScaffolds = registry.list().flatMap((t) => {
|
|
33
|
+
const layout = t.pluginLayout;
|
|
34
|
+
if (layout === undefined)
|
|
35
|
+
return [];
|
|
36
|
+
return [
|
|
37
|
+
{
|
|
38
|
+
layout,
|
|
39
|
+
scaffoldExamples: t.scaffoldExamples,
|
|
40
|
+
stableExampleIds: t.stableExampleIds,
|
|
41
|
+
scaffoldConfigBlock: t.scaffoldConfigBlock,
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
});
|
|
45
|
+
// Back-compat diagnostic (ADR-0038): the old init always scaffolded fit/sim;
|
|
46
|
+
// the registry-driven init scaffolds FEWER dirs if one of those is absent. A
|
|
47
|
+
// loud warning makes a silent under-scaffold observable; a genuinely
|
|
48
|
+
// uninstalled third-party tool stays silent (correct). The expected-id pin
|
|
49
|
+
// lives beside BUNDLED_TOOL_PACKAGES (register-tools.ts) — see its JSDoc for
|
|
50
|
+
// why it is a historical constant rather than derived from loaded manifests.
|
|
51
|
+
for (const expectedId of EXPECTED_SCAFFOLDING_TOOL_IDS) {
|
|
52
|
+
if (!registry.list().some((t) => (t.metadata.name ?? t.metadata.id) === expectedId)) {
|
|
53
|
+
logger.warn({
|
|
54
|
+
evt: 'cli.tool.expected_bundled_absent',
|
|
55
|
+
module: 'cli:bootstrap',
|
|
56
|
+
tool: expectedId,
|
|
57
|
+
msg: `Expected bundled tool '${expectedId}' is absent from the registry — its init scaffold dirs will not be created.`,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const sessionReplayRegistry = SessionReplayRegistry.fromTools(registry);
|
|
62
|
+
// The live tool command surface, sourced from the populated registry so the
|
|
63
|
+
// `completion` command derives its flags from the same specs the runtime
|
|
64
|
+
// mounts (no hand-maintained flag list to drift).
|
|
65
|
+
const toolCommandSpecs = registry.list().flatMap((t) => t.commandSpecs ?? []);
|
|
66
|
+
return {
|
|
67
|
+
pluginLayouts,
|
|
68
|
+
toolScaffolds,
|
|
69
|
+
sessionReplayRegistry,
|
|
70
|
+
toolCommandSpecs,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=build-command-registration-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-command-registration-input.js","sourceRoot":"","sources":["../../src/bootstrap/build-command-registration-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,OAAO,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAC;AAwBpE;;;;;GAKG;AACH,MAAM,UAAU,6BAA6B,CAAC,QAAsB;IAClE,kEAAkE;IAClE,kEAAkE;IAClE,MAAM,aAAa,GAAG,QAAQ;SAC3B,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;SAC1B,MAAM,CAAC,CAAC,CAAC,EAA8B,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IAE9D,8EAA8E;IAC9E,gFAAgF;IAChF,kFAAkF;IAClF,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QAClD,MAAM,MAAM,GAAG,CAAC,CAAC,YAAY,CAAC;QAC9B,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,EAAE,CAAC;QACpC,OAAO;YACL;gBACE,MAAM;gBACN,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;gBACpC,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;gBACpC,mBAAmB,EAAE,CAAC,CAAC,mBAAmB;aAC3C;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,6EAA6E;IAC7E,6EAA6E;IAC7E,qEAAqE;IACrE,2EAA2E;IAC3E,6EAA6E;IAC7E,6EAA6E;IAC7E,KAAK,MAAM,UAAU,IAAI,6BAA6B,EAAE,CAAC;QACvD,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,UAAU,CAAC,EAAE,CAAC;YACpF,MAAM,CAAC,IAAI,CAAC;gBACV,GAAG,EAAE,kCAAkC;gBACvC,MAAM,EAAE,eAAe;gBACvB,IAAI,EAAE,UAAU;gBAChB,GAAG,EAAE,0BAA0B,UAAU,6EAA6E;aACvH,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,qBAAqB,GAAG,qBAAqB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAExE,4EAA4E;IAC5E,yEAAyE;IACzE,kDAAkD;IAClD,MAAM,gBAAgB,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAE9E,OAAO;QACL,aAAa;QACb,aAAa;QACb,qBAAqB;QACrB,gBAAgB;KACjB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* build-per-run-scope — thin, pure(ish) builder for the per-invocation RunScope.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from pre-action-hook (and cli-context assembly) to address
|
|
5
|
+
* composition-root concentration (GA architectural blocker #2).
|
|
6
|
+
*
|
|
7
|
+
* The hook remains the sequencer of high-level steps (project resolution,
|
|
8
|
+
* bailouts, logger config, update nag). This builder owns the exact
|
|
9
|
+
* scope-construction + wiring of:
|
|
10
|
+
* - signalSink (cloud)
|
|
11
|
+
* - toolConfig + configDocument (ADR-0023 one-reader)
|
|
12
|
+
* - targets (ADR-0037)
|
|
13
|
+
* - contributeScope from all registered tools
|
|
14
|
+
* - capability registry wiring
|
|
15
|
+
* - RunScope construction with explicit inputs
|
|
16
|
+
*
|
|
17
|
+
* Inputs are explicit so the builder is testable in isolation and the
|
|
18
|
+
* hook stays focused on orchestration.
|
|
19
|
+
*/
|
|
20
|
+
import { type LanguageRegistry, type Logger, type ProjectContext, RunScope, type ToolPluginManifest, type ToolProvenance, type ToolRegistry } from '@opensip-cli/core';
|
|
21
|
+
import type { loadCliDefaults } from './cli-defaults.js';
|
|
22
|
+
/** Inputs required to build a fully wired per-run scope. */
|
|
23
|
+
export interface BuildPerRunScopeInput {
|
|
24
|
+
readonly project: ProjectContext;
|
|
25
|
+
readonly runId: string;
|
|
26
|
+
readonly cwd: string;
|
|
27
|
+
readonly cliDefaults: ReturnType<typeof loadCliDefaults>;
|
|
28
|
+
readonly registries: {
|
|
29
|
+
readonly languages: LanguageRegistry;
|
|
30
|
+
readonly tools: ToolRegistry;
|
|
31
|
+
};
|
|
32
|
+
readonly manifests: readonly ToolPluginManifest[];
|
|
33
|
+
/**
|
|
34
|
+
* Provenance of the tools admitted this run, recorded by the bootstrap and
|
|
35
|
+
* stamped onto the scope (paired index-wise with `manifests`) so host
|
|
36
|
+
* commands read it via `currentScope()` rather than a module global.
|
|
37
|
+
*/
|
|
38
|
+
readonly provenance: readonly ToolProvenance[];
|
|
39
|
+
readonly apiKey?: string;
|
|
40
|
+
readonly noCloud?: boolean;
|
|
41
|
+
readonly logger: Logger;
|
|
42
|
+
/**
|
|
43
|
+
* Presentation state resolved by the hook before the scope is built:
|
|
44
|
+
* the CLI package version and the cached newer-version string (if any).
|
|
45
|
+
* Passed in — NOT derivable from `cliDefaults` (the `cli:` config block
|
|
46
|
+
* carries no package version).
|
|
47
|
+
*/
|
|
48
|
+
readonly ui: {
|
|
49
|
+
readonly version: string;
|
|
50
|
+
readonly update: string | undefined;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Build the per-run RunScope + perform the post-construction wiring
|
|
55
|
+
* (contributeScope, capabilities, toolConfig, targets).
|
|
56
|
+
*
|
|
57
|
+
* This is the extracted builder. It is intentionally not 100% pure
|
|
58
|
+
* (it calls into config resolution, signal sink selection, etc.)
|
|
59
|
+
* but all inputs are explicit and side effects are contained.
|
|
60
|
+
*/
|
|
61
|
+
export declare function buildPerRunScope(input: BuildPerRunScopeInput): RunScope;
|
|
62
|
+
//# sourceMappingURL=build-per-run-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-per-run-scope.d.ts","sourceRoot":"","sources":["../../src/bootstrap/build-per-run-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,MAAM,EACX,KAAK,cAAc,EAEnB,QAAQ,EACR,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;IACzD,QAAQ,CAAC,UAAU,EAAE;QACnB,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;QACrC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;KAC9B,CAAC;IACF,QAAQ,CAAC,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAClD;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,cAAc,EAAE,CAAC;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE;QACX,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;KACrC,CAAC;CACH;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,QAAQ,CAqIvE"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* build-per-run-scope — thin, pure(ish) builder for the per-invocation RunScope.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from pre-action-hook (and cli-context assembly) to address
|
|
5
|
+
* composition-root concentration (GA architectural blocker #2).
|
|
6
|
+
*
|
|
7
|
+
* The hook remains the sequencer of high-level steps (project resolution,
|
|
8
|
+
* bailouts, logger config, update nag). This builder owns the exact
|
|
9
|
+
* scope-construction + wiring of:
|
|
10
|
+
* - signalSink (cloud)
|
|
11
|
+
* - toolConfig + configDocument (ADR-0023 one-reader)
|
|
12
|
+
* - targets (ADR-0037)
|
|
13
|
+
* - contributeScope from all registered tools
|
|
14
|
+
* - capability registry wiring
|
|
15
|
+
* - RunScope construction with explicit inputs
|
|
16
|
+
*
|
|
17
|
+
* Inputs are explicit so the builder is testable in isolation and the
|
|
18
|
+
* hook stays focused on orchestration.
|
|
19
|
+
*/
|
|
20
|
+
import { join } from 'node:path';
|
|
21
|
+
import { resolveEffectiveCloudConfig } from '@opensip-cli/config';
|
|
22
|
+
import { createCapabilityRegistry, resolveUserPaths, RunScope, } from '@opensip-cli/core';
|
|
23
|
+
import { resolveSignalSink } from '@opensip-cli/output';
|
|
24
|
+
import { buildDatastoreThunk } from '../cli-context.js';
|
|
25
|
+
import { buildTargets } from './build-targets.js';
|
|
26
|
+
import { composeAndValidateToolConfig, wireCapabilityRegistry } from './config-and-capabilities.js';
|
|
27
|
+
/**
|
|
28
|
+
* Build the per-run RunScope + perform the post-construction wiring
|
|
29
|
+
* (contributeScope, capabilities, toolConfig, targets).
|
|
30
|
+
*
|
|
31
|
+
* This is the extracted builder. It is intentionally not 100% pure
|
|
32
|
+
* (it calls into config resolution, signal sink selection, etc.)
|
|
33
|
+
* but all inputs are explicit and side effects are contained.
|
|
34
|
+
*/
|
|
35
|
+
export function buildPerRunScope(input) {
|
|
36
|
+
const { project, runId, cliDefaults, registries, manifests, provenance, apiKey, noCloud, logger, ui, } = input;
|
|
37
|
+
const { languages, tools } = registries;
|
|
38
|
+
// ADR-0008: select the cloud signal sink for this run.
|
|
39
|
+
const signalSink = resolveSignalSink({
|
|
40
|
+
apiKey,
|
|
41
|
+
cloud: resolveEffectiveCloudConfig(cliDefaults.cloud),
|
|
42
|
+
noCloud,
|
|
43
|
+
cacheDir: join(resolveUserPaths().userHomeDir, 'cache'), // note: resolveUserPaths is from core
|
|
44
|
+
});
|
|
45
|
+
// ADR-0023 Phase 4: compose + STRICT-validate config before building the
|
|
46
|
+
// scope (a typo in any tool namespace → CONFIGURATION_ERROR); resolved
|
|
47
|
+
// config rides the scope (tools read scope.toolConfig.<namespace>).
|
|
48
|
+
const { config: toolConfig, document: configDocument } = composeAndValidateToolConfig({
|
|
49
|
+
tools,
|
|
50
|
+
manifests,
|
|
51
|
+
configPath: project.scope === 'project' ? project.configPath : undefined,
|
|
52
|
+
env: process.env,
|
|
53
|
+
});
|
|
54
|
+
// ADR-0037: build the host file-targeting accessor from the SAME single
|
|
55
|
+
// validated config document the composer already read (ADR-0023: one
|
|
56
|
+
// reader — `buildTargets` is a pure builder, never a second `readYamlFile`).
|
|
57
|
+
const targets = buildTargets({ document: configDocument });
|
|
58
|
+
const scope = new RunScope({
|
|
59
|
+
logger,
|
|
60
|
+
projectContext: project,
|
|
61
|
+
languages,
|
|
62
|
+
tools,
|
|
63
|
+
signalSink,
|
|
64
|
+
runId,
|
|
65
|
+
// Closure-based lazy datastore. SQLite is materialised only on
|
|
66
|
+
// first access. The thunk captures `project` so non-action paths
|
|
67
|
+
// (post-action handlers, error printers) that read via
|
|
68
|
+
// `getOrOpenDatastore()` find the same instance.
|
|
69
|
+
datastore: buildDatastoreThunk(project, logger),
|
|
70
|
+
// Presentation settings the render paths read via currentScope()?.ui.
|
|
71
|
+
// bannerSize stays an untyped string at the kernel boundary; the
|
|
72
|
+
// cli-ui render sites narrow it with normalizeBannerSize.
|
|
73
|
+
// bannerSize stays derivable from config; version/update are resolved by
|
|
74
|
+
// the hook (package version + cached update-check result) and passed in.
|
|
75
|
+
ui: {
|
|
76
|
+
bannerSize: cliDefaults.ui?.banner ?? 'mini',
|
|
77
|
+
version: ui.version,
|
|
78
|
+
update: ui.update,
|
|
79
|
+
},
|
|
80
|
+
// Per-run admitted-tool facts, recorded by the bootstrap. Stamped here (not
|
|
81
|
+
// a module global) so host commands (`plugin list`, `tools list`, `tools
|
|
82
|
+
// uninstall`) read them via `currentScope()` — the single source of truth.
|
|
83
|
+
toolManifests: manifests,
|
|
84
|
+
toolProvenance: provenance,
|
|
85
|
+
});
|
|
86
|
+
// Lifecycle diagnostics: record wiring steps (contributeScope + capabilities)
|
|
87
|
+
// on the bus *before* enterScope. These ride the eventual CommandOutcome so
|
|
88
|
+
// --json consumers and the uniform diagnostics snapshot see the full
|
|
89
|
+
// per-run construction (addresses architecture review findings on observability
|
|
90
|
+
// of steps 6/7 and blast-radius files).
|
|
91
|
+
const contributing = tools.list().filter((t) => !!t.contributeScope);
|
|
92
|
+
scope.diagnostics.event('load', 'debug', `${contributing.length} tool(s) contributed subscope`, {
|
|
93
|
+
tools: contributing.map((t) => t.metadata.id ?? t.metadata.name),
|
|
94
|
+
});
|
|
95
|
+
scope.diagnostics.counter('tools.subscope_contributions', contributing.length);
|
|
96
|
+
// D7: each registered tool contributes its tool-specific subscope (e.g.
|
|
97
|
+
// `scope.simulation`, `scope.graph`) BEFORE the scope is entered. IoC (M4):
|
|
98
|
+
// the tool RETURNS its slot via `contributeScope()`; the kernel installs it
|
|
99
|
+
// with `Object.assign` (registration order; a tool with no hook is skipped).
|
|
100
|
+
for (const tool of tools.list()) {
|
|
101
|
+
const contribution = tool.contributeScope?.();
|
|
102
|
+
if (contribution)
|
|
103
|
+
Object.assign(scope, contribution);
|
|
104
|
+
}
|
|
105
|
+
// §5.3 Phase 4: per-run capability registry (manifest domains → real registrars).
|
|
106
|
+
const capabilities = wireCapabilityRegistry({
|
|
107
|
+
tools,
|
|
108
|
+
manifests,
|
|
109
|
+
registry: createCapabilityRegistry(logger),
|
|
110
|
+
});
|
|
111
|
+
const wired = capabilities.listDomains().map((d) => d.id);
|
|
112
|
+
scope.diagnostics.event('load', 'debug', `wired ${wired.length} capability domain(s)`, {
|
|
113
|
+
domains: wired,
|
|
114
|
+
});
|
|
115
|
+
scope.diagnostics.counter('capabilities.wired', wired.length);
|
|
116
|
+
// Host-resolved verdict policies (ADR-0035) are derived once from the fully
|
|
117
|
+
// precedence-resolved toolConfig (flag > env > file > defaults) and stamped
|
|
118
|
+
// onto the scope. All readers (result builders, gate compare, internal "is
|
|
119
|
+
// error?" logic) inside this run must use the stamped value (or a helper that
|
|
120
|
+
// reads it) so the numbers that drove `envelope.verdict.passed` and the exit
|
|
121
|
+
// code are identical everywhere. See fitness `resolveFitVerdictPolicy`.
|
|
122
|
+
const fitnessBlock = toolConfig
|
|
123
|
+
? toolConfig.fitness
|
|
124
|
+
: undefined;
|
|
125
|
+
const fitnessVerdictPolicy = {
|
|
126
|
+
failOnErrors: typeof fitnessBlock?.failOnErrors === 'number' ? fitnessBlock.failOnErrors : 1,
|
|
127
|
+
failOnWarnings: typeof fitnessBlock?.failOnWarnings === 'number' ? fitnessBlock.failOnWarnings : 0,
|
|
128
|
+
};
|
|
129
|
+
Object.assign(scope, {
|
|
130
|
+
capabilities,
|
|
131
|
+
toolConfig,
|
|
132
|
+
targets,
|
|
133
|
+
fitnessVerdictPolicy,
|
|
134
|
+
...configDocumentSlot(project, configDocument),
|
|
135
|
+
});
|
|
136
|
+
// Also surface the config validation result for the uniform lifecycle view.
|
|
137
|
+
const toolConfigNamespaces = tools.list().filter((t) => !!t.config).length;
|
|
138
|
+
scope.diagnostics.event('validate', 'debug', `config composed for ${toolConfigNamespaces} tool namespace(s)`);
|
|
139
|
+
return scope;
|
|
140
|
+
}
|
|
141
|
+
// Helper duplicated from pre-action-hook for now (small, can be shared later if it grows).
|
|
142
|
+
function configDocumentSlot(project, configDocument) {
|
|
143
|
+
return project.scope === 'project' && project.configPath !== undefined
|
|
144
|
+
? { configDocument: configDocument }
|
|
145
|
+
: {};
|
|
146
|
+
}
|
|
147
|
+
// Note: resolveUserPaths is used above but was in the original hook import from core.
|
|
148
|
+
// In real extraction we would import it here. For this focused GA step we keep the
|
|
149
|
+
// construction close to original to minimize diff while still thinning the hook.
|
|
150
|
+
// The important win is that pre-action-hook no longer contains the 60+ lines of
|
|
151
|
+
// scope assembly + wiring.
|
|
152
|
+
//# sourceMappingURL=build-per-run-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-per-run-scope.js","sourceRoot":"","sources":["../../src/bootstrap/build-per-run-scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
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 { type TargetResolver } from '@opensip-cli/core';
|
|
21
|
+
/**
|
|
22
|
+
* Build the host's `scope.targets` resolver from the validated config document.
|
|
23
|
+
*
|
|
24
|
+
* Takes the SAME validated document the single sanctioned reader
|
|
25
|
+
* (`composeAndValidateToolConfig`) already produced — this is a pure builder, it
|
|
26
|
+
* never reads the config file itself (ADR-0023: one reader). The host-owned
|
|
27
|
+
* `targets:` / `globalExcludes:` namespaces were strict-validated whole-document
|
|
28
|
+
* by the composed schema; they are re-parsed here through the same field schemas
|
|
29
|
+
* only to recover their narrowed types (idempotent on already-validated data, no
|
|
30
|
+
* I/O), then each target is registered into a substrate `TargetRegistry` and
|
|
31
|
+
* wrapped in a `TargetResolver` with the bound `resolveTargets` /
|
|
32
|
+
* `applyGlobalExcludes` closures.
|
|
33
|
+
*
|
|
34
|
+
* @param args.document The validated config document from
|
|
35
|
+
* `composeAndValidateToolConfig`, or an empty object for a config-less run.
|
|
36
|
+
* @returns The `TargetResolver` to attach to `scope.targets`, or `undefined`
|
|
37
|
+
* when there is no config document or no `targets:` block to resolve.
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildTargets(args: {
|
|
40
|
+
readonly document: unknown;
|
|
41
|
+
}): TargetResolver | undefined;
|
|
42
|
+
//# sourceMappingURL=build-targets.d.ts.map
|