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,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `tools validate` — user-invocable tool conformance (ADR-0041).
|
|
3
|
+
*
|
|
4
|
+
* The SAME admission pipeline bootstrap runs (`admitToolPackage` — one
|
|
5
|
+
* validator, four consumers), rendered as a sectioned report, plus the
|
|
6
|
+
* Tier A storage-contract scan (ADR-0042) and the config-contract checks.
|
|
7
|
+
*
|
|
8
|
+
* EXECUTION MODEL (the trust posture, stated plainly): validating a package
|
|
9
|
+
* is trusting it to execute — the runtime sections import the candidate's
|
|
10
|
+
* module. Mitigations, not promises: staging installs run npm with
|
|
11
|
+
* `--ignore-scripts` (install-time hooks never fire), and the module import
|
|
12
|
+
* happens in a child-process probe with a hard timeout (a crash boundary,
|
|
13
|
+
* NOT a security boundary).
|
|
14
|
+
*
|
|
15
|
+
* Staging: an npm/tarball spec installs into a TEMP host dir (removed in
|
|
16
|
+
* `finally`); a local directory path validates IN PLACE by default, or via a
|
|
17
|
+
* temp-host install with `--install-deps` (which also resolves the package's
|
|
18
|
+
* dependencies so the runtime sections can load it).
|
|
19
|
+
*/
|
|
20
|
+
import { existsSync, mkdtempSync, rmSync, statSync } from 'node:fs';
|
|
21
|
+
import { tmpdir } from 'node:os';
|
|
22
|
+
import { isAbsolute, join, resolve } from 'node:path';
|
|
23
|
+
import { admitToolPackage } from '../../bootstrap/admit-tool-package.js';
|
|
24
|
+
import { ensureHostDir } from '../plugin/host-dir.js';
|
|
25
|
+
import { npmInstallIntoHost } from '../plugin-host-ops.js';
|
|
26
|
+
import { runRuntimeProbe } from './runtime-probe.js';
|
|
27
|
+
import { runStorageContractChecks } from './storage-contract-checks.js';
|
|
28
|
+
/** The one-line execution notice printed before any candidate code can run. */
|
|
29
|
+
export const VALIDATE_EXECUTION_NOTICE = 'opensip: validating runs the package’s module (untrusted code; ' +
|
|
30
|
+
'install scripts stay blocked, the import runs in a sandboxed-by-timeout ' +
|
|
31
|
+
'child process — a crash boundary, not a security boundary).\n';
|
|
32
|
+
const NOOP_CLEANUP = () => {
|
|
33
|
+
/* in-place candidates own their dir; nothing was staged */
|
|
34
|
+
};
|
|
35
|
+
/** True when `spec` points at an existing local directory. */
|
|
36
|
+
function isLocalDirSpec(spec, cwd) {
|
|
37
|
+
const candidate = isAbsolute(spec) ? spec : resolve(cwd, spec);
|
|
38
|
+
return existsSync(candidate) && statSync(candidate).isDirectory();
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Stage the candidate. npm/tarball specs (and `--install-deps` paths) install
|
|
42
|
+
* into a fresh temp host with `--ignore-scripts`; bare local dirs stage in
|
|
43
|
+
* place (zero side effects).
|
|
44
|
+
*/
|
|
45
|
+
function stageCandidate(opts) {
|
|
46
|
+
const localDir = isLocalDirSpec(opts.spec, opts.cwd);
|
|
47
|
+
if (localDir && opts.installDeps !== true) {
|
|
48
|
+
const pkgDir = isAbsolute(opts.spec) ? opts.spec : resolve(opts.cwd, opts.spec);
|
|
49
|
+
return { pkgDir, cleanup: NOOP_CLEANUP, stagedByInstall: false };
|
|
50
|
+
}
|
|
51
|
+
const tempHost = mkdtempSync(join(tmpdir(), 'ost-tools-validate-'));
|
|
52
|
+
const cleanup = () => rmSync(tempHost, { recursive: true, force: true });
|
|
53
|
+
ensureHostDir(tempHost, 'tool');
|
|
54
|
+
const spec = localDir && !isAbsolute(opts.spec) ? resolve(opts.cwd, opts.spec) : opts.spec;
|
|
55
|
+
const outcome = npmInstallIntoHost(tempHost, spec);
|
|
56
|
+
if (!outcome.ok) {
|
|
57
|
+
return { pkgDir: '', cleanup, stagedByInstall: true, stagingError: outcome.error };
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
pkgDir: join(tempHost, 'node_modules', outcome.installedName),
|
|
61
|
+
cleanup,
|
|
62
|
+
stagedByInstall: true,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function section(name, status, diagnostics = []) {
|
|
66
|
+
return { name, status, diagnostics };
|
|
67
|
+
}
|
|
68
|
+
function storageSections(findings) {
|
|
69
|
+
const isBoundary = (f) => f.clause.includes('imports') || f.clause.includes('runners');
|
|
70
|
+
const fmt = (f) => `${f.file}:${f.line} — ${f.clause}`;
|
|
71
|
+
const boundaries = findings.filter((f) => isBoundary(f));
|
|
72
|
+
const storage = findings.filter((f) => !isBoundary(f));
|
|
73
|
+
return [
|
|
74
|
+
section('storage-contract', storage.length === 0 ? 'passed' : 'failed', storage.map(fmt)),
|
|
75
|
+
section('import-boundaries', boundaries.length === 0 ? 'passed' : 'failed', boundaries.map(fmt)),
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
/** Map one admission section result to a report section. */
|
|
79
|
+
function fromAdmission(s) {
|
|
80
|
+
return section(s.section, s.ok ? 'passed' : 'failed', s.diagnostic ? [s.diagnostic] : []);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* True when a FAILED probe over an IN-PLACE candidate failed on the
|
|
84
|
+
* candidate's own unresolved dependencies (expected without `--install-deps`).
|
|
85
|
+
* A probe-INFRA failure ("runtime probe crashed/timed out/…") must never
|
|
86
|
+
* classify as a candidate missing-dep, even when the child's stderr mentions
|
|
87
|
+
* an unresolved module.
|
|
88
|
+
*/
|
|
89
|
+
function isExpectedMissingDep(probe, stagedByInstall) {
|
|
90
|
+
if (probe.ok || stagedByInstall)
|
|
91
|
+
return false;
|
|
92
|
+
return probe.sections.some((s) => s.diagnostic !== undefined &&
|
|
93
|
+
!s.diagnostic.startsWith('runtime probe') &&
|
|
94
|
+
/cannot find (module|package)/i.test(s.diagnostic));
|
|
95
|
+
}
|
|
96
|
+
/** The three runtime sections marked skipped (in-place, deps not installed). */
|
|
97
|
+
function skippedRuntimeSections() {
|
|
98
|
+
return [
|
|
99
|
+
section('runtime-load', 'skipped', [
|
|
100
|
+
'dependencies not installed — rerun with --install-deps to verify the runtime sections',
|
|
101
|
+
]),
|
|
102
|
+
section('tool-shape', 'skipped'),
|
|
103
|
+
section('manifest-runtime-coherence', 'skipped'),
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Config contract (spec + ADR-0043 family): a manifest that declares config
|
|
108
|
+
* needs a runtime `Tool.config`; a runtime namespace must equal the tool id.
|
|
109
|
+
*/
|
|
110
|
+
function configContractSection(manifestDeclaresConfig, toolConfigNamespace, toolId) {
|
|
111
|
+
const diagnostics = [];
|
|
112
|
+
if (manifestDeclaresConfig && toolConfigNamespace === null) {
|
|
113
|
+
diagnostics.push('manifest declares config but the runtime Tool.config contribution is missing');
|
|
114
|
+
}
|
|
115
|
+
if (toolConfigNamespace !== null && toolConfigNamespace !== toolId) {
|
|
116
|
+
diagnostics.push(`Tool.config.namespace '${toolConfigNamespace}' does not match the tool id '${toolId ?? ''}'`);
|
|
117
|
+
}
|
|
118
|
+
return section('config-contract', diagnostics.length === 0 ? 'passed' : 'failed', diagnostics);
|
|
119
|
+
}
|
|
120
|
+
/** The runtime-probe + config-contract leg. Mutates nothing; returns its sections. */
|
|
121
|
+
function runtimeSectionsFor(staged, manifestDeclaresConfig, manifestToolId) {
|
|
122
|
+
const probe = runRuntimeProbe(staged.pkgDir);
|
|
123
|
+
if (isExpectedMissingDep(probe, staged.stagedByInstall)) {
|
|
124
|
+
return { sections: skippedRuntimeSections(), toolId: manifestToolId, incomplete: true };
|
|
125
|
+
}
|
|
126
|
+
const sections = probe.sections
|
|
127
|
+
.filter((s) => s.section !== 'manifest' && s.section !== 'compatibility')
|
|
128
|
+
.map((s) => fromAdmission(s));
|
|
129
|
+
let toolId = manifestToolId;
|
|
130
|
+
if (probe.ok) {
|
|
131
|
+
if (probe.toolId !== null)
|
|
132
|
+
toolId = probe.toolId;
|
|
133
|
+
sections.push(configContractSection(manifestDeclaresConfig, probe.toolConfigNamespace, toolId));
|
|
134
|
+
}
|
|
135
|
+
return { sections, toolId, incomplete: false };
|
|
136
|
+
}
|
|
137
|
+
function verdictFor(sections, incomplete) {
|
|
138
|
+
if (sections.some((s) => s.status === 'failed'))
|
|
139
|
+
return 'failed';
|
|
140
|
+
if (incomplete)
|
|
141
|
+
return 'incomplete';
|
|
142
|
+
return 'passed';
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Run every validation section against one candidate spec. Shared by
|
|
146
|
+
* `tools validate` (renders it) and `tools install` (gates activation on it).
|
|
147
|
+
* `keepStaged` hands ownership of the staged dir to the caller (install
|
|
148
|
+
* activates from the validated bytes — never a re-download).
|
|
149
|
+
*/
|
|
150
|
+
export async function runToolValidation(opts, { keepStaged = false } = {}) {
|
|
151
|
+
process.stderr.write(VALIDATE_EXECUTION_NOTICE);
|
|
152
|
+
const staged = stageCandidate(opts);
|
|
153
|
+
try {
|
|
154
|
+
if (staged.stagingError !== undefined) {
|
|
155
|
+
return {
|
|
156
|
+
result: {
|
|
157
|
+
type: 'tools-validate',
|
|
158
|
+
spec: opts.spec,
|
|
159
|
+
verdict: 'failed',
|
|
160
|
+
sections: [section('staging', 'failed', [staged.stagingError])],
|
|
161
|
+
},
|
|
162
|
+
cleanup: NOOP_CLEANUP,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
// Static admission sections (manifest + compatibility) — in-process, no
|
|
166
|
+
// candidate code runs.
|
|
167
|
+
const staticReport = await admitToolPackage({
|
|
168
|
+
dir: staged.pkgDir,
|
|
169
|
+
source: 'installed',
|
|
170
|
+
explicitlyRequested: true,
|
|
171
|
+
staticOnly: true,
|
|
172
|
+
});
|
|
173
|
+
const sections = staticReport.sections.map((s) => fromAdmission(s));
|
|
174
|
+
let toolId = staticReport.manifest?.id;
|
|
175
|
+
let incomplete = false;
|
|
176
|
+
if (staticReport.ok) {
|
|
177
|
+
// Runtime sections — child-process probe (untrusted code executes there).
|
|
178
|
+
const runtime = runtimeSectionsFor(staged, staticReport.manifest?.config !== undefined, toolId);
|
|
179
|
+
sections.push(...runtime.sections);
|
|
180
|
+
toolId = runtime.toolId;
|
|
181
|
+
incomplete = runtime.incomplete;
|
|
182
|
+
}
|
|
183
|
+
// Tier A storage contract (ADR-0042) — pure file scan, always runs.
|
|
184
|
+
sections.push(...storageSections(runStorageContractChecks(staged.pkgDir)));
|
|
185
|
+
return {
|
|
186
|
+
result: {
|
|
187
|
+
type: 'tools-validate',
|
|
188
|
+
spec: opts.spec,
|
|
189
|
+
...(toolId === undefined ? {} : { toolId }),
|
|
190
|
+
verdict: verdictFor(sections, incomplete),
|
|
191
|
+
sections,
|
|
192
|
+
},
|
|
193
|
+
...(keepStaged && staged.stagedByInstall ? { stagedPkgDir: staged.pkgDir } : {}),
|
|
194
|
+
cleanup: keepStaged ? staged.cleanup : NOOP_CLEANUP,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
if (!keepStaged)
|
|
199
|
+
staged.cleanup();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/commands/tools/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Uninstall target collection + display formatting.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `commands/uninstall.ts` so the executor there stays
|
|
5
|
+
* focused on the user/project mode dispatch and removal flow. Owns:
|
|
6
|
+
*
|
|
7
|
+
* - The `Target` / `TargetBucket` types
|
|
8
|
+
* - `collectTargets` (user mode + project mode bucketing)
|
|
9
|
+
* - The pre-prompt print helpers (`printUserModeTargets`,
|
|
10
|
+
* `printProjectDefault`, `printProjectPurge`) and supporting
|
|
11
|
+
* formatters (`formatSize`, `formatKeepLine`).
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Bucket classification per target:
|
|
15
|
+
* - 'runtime' — opensip-cli/.runtime/. Rebuildable. Removed by default.
|
|
16
|
+
* - 'user-content' — anything else under opensip-cli/. User-authored.
|
|
17
|
+
* Preserved unless --purge.
|
|
18
|
+
* - 'config' — opensip-cli.config.yml. Preserved unless --purge.
|
|
19
|
+
* - 'user-level' — ~/.opensip-cli/ in user mode.
|
|
20
|
+
*/
|
|
21
|
+
type TargetBucket = 'runtime' | 'user-content' | 'config' | 'user-level';
|
|
22
|
+
/** Discrete target to remove (a file or a directory). */
|
|
23
|
+
export interface Target {
|
|
24
|
+
readonly path: string;
|
|
25
|
+
readonly kind: 'file' | 'dir';
|
|
26
|
+
readonly sizeBytes: number;
|
|
27
|
+
readonly bucket: TargetBucket;
|
|
28
|
+
/** For user-content children: human label (e.g. 'fit/checks', 'notes'). */
|
|
29
|
+
readonly displayLabel?: string;
|
|
30
|
+
/** For user-content child directories: count of files inside (recursive). */
|
|
31
|
+
readonly fileCount?: number;
|
|
32
|
+
}
|
|
33
|
+
export type UninstallMode = 'user' | 'project';
|
|
34
|
+
/**
|
|
35
|
+
* Build the bucketed list of targets that currently exist for the given mode.
|
|
36
|
+
*
|
|
37
|
+
* Project mode:
|
|
38
|
+
* - .runtime/ → bucket 'runtime'
|
|
39
|
+
* - everything else under opensip-cli/ (per top-level entry)
|
|
40
|
+
* → bucket 'user-content' (one entry each)
|
|
41
|
+
* - opensip-cli.config.yml → bucket 'config'
|
|
42
|
+
*
|
|
43
|
+
* The user-content invariant is "everything under opensip-cli/ minus
|
|
44
|
+
* .runtime/" — NOT an enumeration of known subdirs like fit/ + sim/.
|
|
45
|
+
* Future tools and user-created folders (e.g. opensip-cli/notes/) are
|
|
46
|
+
* preserved automatically.
|
|
47
|
+
*/
|
|
48
|
+
export declare function collectTargets(mode: UninstallMode, userRoot: string, projectDir: string): Target[];
|
|
49
|
+
export declare function printUserModeTargets(write: (s: string) => void, targets: readonly Target[]): void;
|
|
50
|
+
export declare function printProjectDefault(write: (s: string) => void, toDelete: readonly Target[], toKeep: readonly Target[], projectRoot: string): void;
|
|
51
|
+
export declare function printProjectPurge(write: (s: string) => void, toDelete: readonly Target[], projectRoot: string): void;
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=targets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../../../src/commands/uninstall/targets.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;GAWG;AAOH;;;;;;;GAOG;AACH,KAAK,YAAY,GAAG,SAAS,GAAG,cAAc,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEzE,yDAAyD;AACzD,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,2EAA2E;IAC3E,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;AA+C/C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,MAAM,EAAE,CAMV;AAyED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAQjG;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAC1B,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,WAAW,EAAE,MAAM,GAClB,IAAI,CAsBN;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAC1B,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,WAAW,EAAE,MAAM,GAClB,IAAI,CASN"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// @fitness-ignore-file error-handling-quality -- file/dir walks for uninstall planning: missing/unreadable entries (TOCTOU vanish between readdir+stat, permission-denied subdirs) are the expected non-terminal signal to skip; failure-IS-the-signal is the contract in each catch.
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Uninstall target collection + display formatting.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from `commands/uninstall.ts` so the executor there stays
|
|
6
|
+
* focused on the user/project mode dispatch and removal flow. Owns:
|
|
7
|
+
*
|
|
8
|
+
* - The `Target` / `TargetBucket` types
|
|
9
|
+
* - `collectTargets` (user mode + project mode bucketing)
|
|
10
|
+
* - The pre-prompt print helpers (`printUserModeTargets`,
|
|
11
|
+
* `printProjectDefault`, `printProjectPurge`) and supporting
|
|
12
|
+
* formatters (`formatSize`, `formatKeepLine`).
|
|
13
|
+
*/
|
|
14
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
import { resolveProjectPaths } from '@opensip-cli/core';
|
|
17
|
+
/** Recursively tally size of a directory. */
|
|
18
|
+
function dirSize(path) {
|
|
19
|
+
let total = 0;
|
|
20
|
+
const entries = readdirSync(path, { withFileTypes: true });
|
|
21
|
+
for (const e of entries) {
|
|
22
|
+
const p = join(path, e.name);
|
|
23
|
+
try {
|
|
24
|
+
if (e.isDirectory()) {
|
|
25
|
+
total += dirSize(p);
|
|
26
|
+
}
|
|
27
|
+
else if (e.isFile()) {
|
|
28
|
+
total += statSync(p).size;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// File vanished between readdir + stat; ignore.
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return total;
|
|
36
|
+
}
|
|
37
|
+
function formatSize(bytes) {
|
|
38
|
+
if (bytes < 1024)
|
|
39
|
+
return `${bytes} B`;
|
|
40
|
+
if (bytes < 1024 * 1024)
|
|
41
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
42
|
+
if (bytes < 1024 * 1024 * 1024)
|
|
43
|
+
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
44
|
+
return `${(bytes / 1024 / 1024 / 1024).toFixed(2)} GB`;
|
|
45
|
+
}
|
|
46
|
+
/** Count files recursively under a directory; best-effort (unreadable subdirs skipped). */
|
|
47
|
+
function countFilesRecursive(dir) {
|
|
48
|
+
let count = 0;
|
|
49
|
+
const walk = (d) => {
|
|
50
|
+
try {
|
|
51
|
+
const entries = readdirSync(d, { withFileTypes: true });
|
|
52
|
+
for (const e of entries) {
|
|
53
|
+
const p = join(d, e.name);
|
|
54
|
+
if (e.isDirectory())
|
|
55
|
+
walk(p);
|
|
56
|
+
else if (e.isFile())
|
|
57
|
+
count++;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
/* unreadable subdir — best-effort */
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
walk(dir);
|
|
65
|
+
return count;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Build the bucketed list of targets that currently exist for the given mode.
|
|
69
|
+
*
|
|
70
|
+
* Project mode:
|
|
71
|
+
* - .runtime/ → bucket 'runtime'
|
|
72
|
+
* - everything else under opensip-cli/ (per top-level entry)
|
|
73
|
+
* → bucket 'user-content' (one entry each)
|
|
74
|
+
* - opensip-cli.config.yml → bucket 'config'
|
|
75
|
+
*
|
|
76
|
+
* The user-content invariant is "everything under opensip-cli/ minus
|
|
77
|
+
* .runtime/" — NOT an enumeration of known subdirs like fit/ + sim/.
|
|
78
|
+
* Future tools and user-created folders (e.g. opensip-cli/notes/) are
|
|
79
|
+
* preserved automatically.
|
|
80
|
+
*/
|
|
81
|
+
export function collectTargets(mode, userRoot, projectDir) {
|
|
82
|
+
if (mode === 'user') {
|
|
83
|
+
if (!existsSync(userRoot))
|
|
84
|
+
return [];
|
|
85
|
+
return [{ path: userRoot, kind: 'dir', sizeBytes: dirSize(userRoot), bucket: 'user-level' }];
|
|
86
|
+
}
|
|
87
|
+
return collectProjectTargets(projectDir);
|
|
88
|
+
}
|
|
89
|
+
function collectProjectTargets(projectDir) {
|
|
90
|
+
const paths = resolveProjectPaths(projectDir);
|
|
91
|
+
const targets = [];
|
|
92
|
+
if (existsSync(paths.runtimeDir)) {
|
|
93
|
+
targets.push({
|
|
94
|
+
path: paths.runtimeDir,
|
|
95
|
+
kind: 'dir',
|
|
96
|
+
sizeBytes: dirSize(paths.runtimeDir),
|
|
97
|
+
bucket: 'runtime',
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
if (existsSync(paths.userSourceDir)) {
|
|
101
|
+
targets.push(...collectUserContentTargets(paths.userSourceDir));
|
|
102
|
+
}
|
|
103
|
+
if (existsSync(paths.configFile)) {
|
|
104
|
+
targets.push({
|
|
105
|
+
path: paths.configFile,
|
|
106
|
+
kind: 'file',
|
|
107
|
+
sizeBytes: statSync(paths.configFile).size,
|
|
108
|
+
bucket: 'config',
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return targets;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Enumerate every top-level entry under opensip-cli/ EXCEPT .runtime/.
|
|
115
|
+
* Enumeration is for display; the invariant is "not .runtime/".
|
|
116
|
+
*/
|
|
117
|
+
function collectUserContentTargets(userSourceDir) {
|
|
118
|
+
const out = [];
|
|
119
|
+
let entries;
|
|
120
|
+
try {
|
|
121
|
+
entries = readdirSync(userSourceDir, { withFileTypes: true });
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
for (const entry of entries) {
|
|
127
|
+
if (entry.name === '.runtime')
|
|
128
|
+
continue;
|
|
129
|
+
const p = join(userSourceDir, entry.name);
|
|
130
|
+
const isDir = entry.isDirectory();
|
|
131
|
+
let sizeBytes = 0;
|
|
132
|
+
try {
|
|
133
|
+
sizeBytes = isDir ? dirSize(p) : statSync(p).size;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
/* skip unreadable */
|
|
137
|
+
}
|
|
138
|
+
out.push({
|
|
139
|
+
path: p,
|
|
140
|
+
kind: isDir ? 'dir' : 'file',
|
|
141
|
+
sizeBytes,
|
|
142
|
+
bucket: 'user-content',
|
|
143
|
+
displayLabel: entry.name,
|
|
144
|
+
fileCount: isDir ? countFilesRecursive(p) : undefined,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
function formatKeepLine(t) {
|
|
150
|
+
if (t.bucket === 'config')
|
|
151
|
+
return 'opensip-cli.config.yml';
|
|
152
|
+
if (t.displayLabel === undefined)
|
|
153
|
+
return t.path;
|
|
154
|
+
const slash = t.kind === 'dir' ? '/' : '';
|
|
155
|
+
let inner = '';
|
|
156
|
+
if (t.fileCount !== undefined) {
|
|
157
|
+
const plural = t.fileCount === 1 ? '' : 's';
|
|
158
|
+
inner = ` (${t.fileCount} file${plural})`;
|
|
159
|
+
}
|
|
160
|
+
return `opensip-cli/${t.displayLabel}${slash}${inner}`;
|
|
161
|
+
}
|
|
162
|
+
export function printUserModeTargets(write, targets) {
|
|
163
|
+
const totalSize = targets.reduce((sum, t) => sum + t.sizeBytes, 0);
|
|
164
|
+
write('\n');
|
|
165
|
+
write(`About to remove user-level state (${formatSize(totalSize)}):\n`);
|
|
166
|
+
for (const t of targets) {
|
|
167
|
+
write(` - ${t.path}${t.kind === 'dir' ? '/' : ''} (${formatSize(t.sizeBytes)})\n`);
|
|
168
|
+
}
|
|
169
|
+
write('\n');
|
|
170
|
+
}
|
|
171
|
+
export function printProjectDefault(write, toDelete, toKeep, projectRoot) {
|
|
172
|
+
write('\n');
|
|
173
|
+
write(`Project: ${projectRoot}\n\n`);
|
|
174
|
+
if (toDelete.length === 0) {
|
|
175
|
+
write('Nothing to remove — runtime state is already absent.\n\n');
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
write('This will remove (rebuildable runtime state only):\n');
|
|
179
|
+
for (const t of toDelete) {
|
|
180
|
+
write(` - ${t.path}${t.kind === 'dir' ? '/' : ''} (${formatSize(t.sizeBytes)})\n`);
|
|
181
|
+
if (t.bucket === 'runtime') {
|
|
182
|
+
write(' sessions database, cache, logs, baselines\n');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
write('\n');
|
|
186
|
+
}
|
|
187
|
+
if (toKeep.length > 0) {
|
|
188
|
+
write('These will be KEPT (your authored content):\n');
|
|
189
|
+
for (const t of toKeep) {
|
|
190
|
+
write(` ✓ ${formatKeepLine(t)}\n`);
|
|
191
|
+
}
|
|
192
|
+
write('\n To also remove your authored content, re-run with --purge.\n\n');
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
export function printProjectPurge(write, toDelete, projectRoot) {
|
|
196
|
+
write('\n');
|
|
197
|
+
write(`Project: ${projectRoot}\n\n`);
|
|
198
|
+
write('⚠ This removes EVERYTHING, including your authored content:\n\n');
|
|
199
|
+
for (const t of toDelete) {
|
|
200
|
+
write(` - ${t.path}${t.kind === 'dir' ? '/' : ''} (${formatSize(t.sizeBytes)})\n`);
|
|
201
|
+
}
|
|
202
|
+
write('\n ⚠ If your custom checks are not committed to git, you will\n');
|
|
203
|
+
write(' lose them. We recommend running `git status` first.\n\n');
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=targets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targets.js","sourceRoot":"","sources":["../../../src/commands/uninstall/targets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `opensip uninstall` — remove opensip-cli state
|
|
3
|
+
* from a user account and/or project.
|
|
4
|
+
*
|
|
5
|
+
* Two modes:
|
|
6
|
+
*
|
|
7
|
+
* • Default (no flag) — remove the user-level directory
|
|
8
|
+
* `~/.opensip-cli/`. Contract: this dir holds `config.yml` only
|
|
9
|
+
* (cloud API key + per-user defaults). Persistence and logging code
|
|
10
|
+
* throws if asked to write anywhere user-global, so the dir does
|
|
11
|
+
* not grow over time. Any pre-existing `sessions/`, `reports/`,
|
|
12
|
+
* `logs/`, or `fit/` subdirectories on disk are legacy cruft from
|
|
13
|
+
* earlier versions and are swept up by the same removal.
|
|
14
|
+
*
|
|
15
|
+
* • `--project [path]` — remove project-local state at `[path]` (or
|
|
16
|
+
* cwd if omitted): both `<path>/opensip-cli/` (user-authored
|
|
17
|
+
* checks + recipes plus the gitignored `.runtime/` cache) and
|
|
18
|
+
* `<path>/opensip-cli.config.yml`. Refuses to run if neither
|
|
19
|
+
* target exists at the resolved path, to avoid `rm -rf`-ing an
|
|
20
|
+
* unrelated directory.
|
|
21
|
+
*
|
|
22
|
+
* The recursive removal of `<path>/opensip-cli/` transitively
|
|
23
|
+
* sweeps up `.runtime/datastore.sqlite` and its `-wal`/`-shm` SQLite
|
|
24
|
+
* sidecars — no datastore-specific path needs to be
|
|
25
|
+
* enumerated here. Caveat for Windows: open file handles can block
|
|
26
|
+
* removal of WAL/SHM files; ensure no opensip-cli CLI process is
|
|
27
|
+
* active when running uninstall.
|
|
28
|
+
*
|
|
29
|
+
* Does NOT remove the npm global install — the running binary can't
|
|
30
|
+
* safely self-delete. Prints the exact next-step command for that.
|
|
31
|
+
*
|
|
32
|
+
* Flags:
|
|
33
|
+
* --project [path] Remove project-local state instead of user-level.
|
|
34
|
+
* --yes Skip confirmation prompt.
|
|
35
|
+
* --dry-run Print what would be removed; take no action.
|
|
36
|
+
*
|
|
37
|
+
* Result-shape contract (audit 2026-05-23 G5)
|
|
38
|
+
* -------------------------------------------
|
|
39
|
+
* `executeUninstall` returns a discriminated `UninstallDoneResult` whose
|
|
40
|
+
* `type === 'uninstall-done'` makes it a valid `CommandResult`. The
|
|
41
|
+
* trailing success / cancelled / dry-run / empty notice — previously
|
|
42
|
+
* raw-stdout writes that bypassed the theme — is rendered via Ink in
|
|
43
|
+
* `App.tsx`'s `case 'uninstall-done':` branch. The pre-confirmation
|
|
44
|
+
* target listing stays as a direct `write()` because it must appear
|
|
45
|
+
* BEFORE the readline confirmation prompt; same pattern as
|
|
46
|
+
* `configure.ts` printing the "current key" hint above the prompt.
|
|
47
|
+
*
|
|
48
|
+
* Module layout
|
|
49
|
+
* -------------
|
|
50
|
+
* - This file owns `executeUninstall` and removal orchestration.
|
|
51
|
+
* - `uninstall/targets.ts` owns Target collection + pre-prompt display.
|
|
52
|
+
*/
|
|
53
|
+
import type { UninstallDoneResult } from '@opensip-cli/contracts';
|
|
54
|
+
import type { ProjectContext } from '@opensip-cli/core';
|
|
55
|
+
export interface UninstallOptions {
|
|
56
|
+
readonly yes?: boolean;
|
|
57
|
+
readonly dryRun?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* If set, run in project mode and target this path. If `true`, use
|
|
60
|
+
* cwd. If `undefined`, run in user-level mode.
|
|
61
|
+
*/
|
|
62
|
+
readonly project?: string | true;
|
|
63
|
+
/** Override the user-level root dir (primarily for tests). */
|
|
64
|
+
readonly rootDir?: string;
|
|
65
|
+
/** Override cwd resolution for `--project` with no arg (tests). */
|
|
66
|
+
readonly cwd?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Resolved ProjectContext from pre-action-hook. Used as the primary
|
|
69
|
+
* source for `resolveProjectDir` when `--project` wasn't passed —
|
|
70
|
+
* without it, `uninstall` run from a subdir would target the wrong
|
|
71
|
+
* .runtime/.
|
|
72
|
+
*/
|
|
73
|
+
readonly projectContext?: ProjectContext;
|
|
74
|
+
/**
|
|
75
|
+
* When true, in project mode also remove user-authored content and the
|
|
76
|
+
* config file (DESTRUCTIVE). Default (false) only removes the
|
|
77
|
+
* rebuildable .runtime/ subtree, preserving custom checks/recipes/
|
|
78
|
+
* scenarios/config. `--purge` is the explicit opt-in for the old
|
|
79
|
+
* destructive behavior.
|
|
80
|
+
*/
|
|
81
|
+
readonly purge?: boolean;
|
|
82
|
+
/** Override stdout (primarily for tests). */
|
|
83
|
+
readonly write?: (s: string) => void;
|
|
84
|
+
/** Override the confirmation prompt (primarily for tests). */
|
|
85
|
+
readonly prompt?: (question: string) => Promise<string>;
|
|
86
|
+
}
|
|
87
|
+
export declare function executeUninstall(opts?: UninstallOptions): Promise<UninstallDoneResult>;
|
|
88
|
+
//# sourceMappingURL=uninstall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAkBH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACzD;AA6FD,wBAAsB,gBAAgB,CAAC,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA6ChG"}
|