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,287 @@
|
|
|
1
|
+
// @fitness-ignore-file error-handling-quality -- npm install failures already stream to stderr via inherited stdio (downstream loader surfaces unresolved imports), and the package.json / node_modules walks are probes where unreadable/malformed entries mean "not installable" or "not a candidate" — same as absent.
|
|
2
|
+
/**
|
|
3
|
+
* plugin command — manage project-local npm-installed plugins.
|
|
4
|
+
*
|
|
5
|
+
* Layout (no user-global plugin dir):
|
|
6
|
+
*
|
|
7
|
+
* <project>/opensip-cli/.runtime/plugins/<domain>/
|
|
8
|
+
* ├── package.json — host package; "dependencies" is the
|
|
9
|
+
* │ plugin install state for this domain
|
|
10
|
+
* └── node_modules/ — npm-installed plugin packages
|
|
11
|
+
*
|
|
12
|
+
* <project>/opensip-cli.config.yml
|
|
13
|
+
* plugins:
|
|
14
|
+
* fit:
|
|
15
|
+
* - "@org/fitness-checks" — declares which installed packages
|
|
16
|
+
* discovery should LOAD. Required;
|
|
17
|
+
* discovery does not auto-load every
|
|
18
|
+
* installed package (silent loads
|
|
19
|
+
* would surprise users).
|
|
20
|
+
*
|
|
21
|
+
* `plugin add <pkg>` is the one-step install: writes the package to
|
|
22
|
+
* .runtime/plugins/<domain>/node_modules AND adds it to plugins.<domain>
|
|
23
|
+
* in the project config. After: `opensip fit` loads it on next run.
|
|
24
|
+
*
|
|
25
|
+
* `plugin remove <pkg>` is the inverse: removes from node_modules AND
|
|
26
|
+
* deletes from plugins.<domain>.
|
|
27
|
+
*
|
|
28
|
+
* `plugin list` walks .runtime/plugins/<domain>/node_modules + the
|
|
29
|
+
* config to show what's installed and what's currently loaded.
|
|
30
|
+
*
|
|
31
|
+
* `plugin sync` is the post-clone bootstrap: reads plugins.<domain> from
|
|
32
|
+
* the config and `npm install`s everything declared. Used by CI and
|
|
33
|
+
* by users who clone a repo with custom plugins.
|
|
34
|
+
*
|
|
35
|
+
* Module layout
|
|
36
|
+
* -------------
|
|
37
|
+
* - This file owns the `plugin {list,add,remove,sync}` command bodies.
|
|
38
|
+
* - `plugin/config-edit.ts` — YAML round-trip edits to plugins.<domain>.
|
|
39
|
+
* - `plugin/domain-resolution.ts` — TOOL_DOMAIN + the pure validation
|
|
40
|
+
* logic that routes a spec to a domain / Tool host dir (no install).
|
|
41
|
+
* - `plugin/host-dir.ts` — host package.json creation + installed-
|
|
42
|
+
* package introspection (incl. peer-dependency auto-install).
|
|
43
|
+
*/
|
|
44
|
+
import { execFileSync } from 'node:child_process';
|
|
45
|
+
import { existsSync } from 'node:fs';
|
|
46
|
+
import { join } from 'node:path';
|
|
47
|
+
import { discoverPackagesInNodeModules, readProjectPluginsList, resolveProjectPaths, resolveUserPaths, } from '@opensip-cli/core';
|
|
48
|
+
import { addToConfigPluginList, removeFromConfigPluginList } from './plugin/config-edit.js';
|
|
49
|
+
import { domainNames, isToolTarget, resolveDomain, TOOL_DOMAIN, } from './plugin/domain-resolution.js';
|
|
50
|
+
import { ensurePluginHostDir, HOST_PACKAGE_JSON, isSafeNpmSpec } from './plugin/host-dir.js';
|
|
51
|
+
import { addToolPlugin, editPluginList, npmInstallIntoHost, npmUninstallFromHost, removeToolPlugin, } from './plugin-host-ops.js';
|
|
52
|
+
/**
|
|
53
|
+
* CommandResult discriminator literals. `as const` keeps the literal type
|
|
54
|
+
* (so the PluginResult union still narrows) while satisfying
|
|
55
|
+
* sonarjs/no-duplicate-string — no scattered eslint-disable needed.
|
|
56
|
+
*/
|
|
57
|
+
const PLUGIN_ADD = 'plugin-add';
|
|
58
|
+
const PLUGIN_REMOVE = 'plugin-remove';
|
|
59
|
+
/**
|
|
60
|
+
* Test-only export for the YAML-driven config edit so unit tests can
|
|
61
|
+
* exercise the round-trip behaviour without spawning npm. Intentionally
|
|
62
|
+
* not part of the public CLI API surface.
|
|
63
|
+
*/
|
|
64
|
+
export const __test = { editPluginList };
|
|
65
|
+
// =============================================================================
|
|
66
|
+
// COMMAND: plugin list
|
|
67
|
+
// =============================================================================
|
|
68
|
+
export async function pluginList(cwd = process.cwd(), layouts = [],
|
|
69
|
+
// The admitted-tool provenance for this run, read by the command handler from
|
|
70
|
+
// the entered RunScope and passed in (keeps this function pure). Default `[]`.
|
|
71
|
+
toolProvenance = []) {
|
|
72
|
+
const { discoverPlugins } = await import('@opensip-cli/core');
|
|
73
|
+
const plugins = [];
|
|
74
|
+
for (const layout of layouts) {
|
|
75
|
+
const found = discoverPlugins(layout, cwd);
|
|
76
|
+
for (const plugin of found) {
|
|
77
|
+
plugins.push({
|
|
78
|
+
domain: layout.domain,
|
|
79
|
+
namespace: plugin.namespace,
|
|
80
|
+
pluginType: plugin.type,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Tool plugins are not a fit/sim layout — they auto-discover by marker
|
|
85
|
+
// from the user-global host dir and (with --project) the project-local
|
|
86
|
+
// one. Dedup by name; a project-local pin shadows a user-global install.
|
|
87
|
+
const seenTools = new Set();
|
|
88
|
+
for (const dir of [
|
|
89
|
+
resolveProjectPaths(cwd).pluginsDir(TOOL_DOMAIN),
|
|
90
|
+
resolveUserPaths().pluginsDir(TOOL_DOMAIN),
|
|
91
|
+
]) {
|
|
92
|
+
for (const pkg of discoverPackagesInNodeModules(join(dir, 'node_modules'), 'tool')) {
|
|
93
|
+
if (seenTools.has(pkg.name))
|
|
94
|
+
continue;
|
|
95
|
+
seenTools.add(pkg.name);
|
|
96
|
+
plugins.push({ domain: TOOL_DOMAIN, namespace: pkg.name, pluginType: 'package' });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Additive provenance section (launch): the tools admitted through the
|
|
100
|
+
// compatibility gate this run — passed in by the command handler from the
|
|
101
|
+
// entered RunScope (`currentScope().toolProvenance`), NOT a disk re-scan.
|
|
102
|
+
// Surfaces source/identity/manifestHash for bundled/installed/project-local
|
|
103
|
+
// tools alongside the discovered fit/sim/tool plugin list above.
|
|
104
|
+
return {
|
|
105
|
+
type: 'plugin-list',
|
|
106
|
+
domains: [...domainsForList(layouts), TOOL_DOMAIN],
|
|
107
|
+
plugins,
|
|
108
|
+
totalCount: plugins.length,
|
|
109
|
+
toolProvenance,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function domainsForList(layouts) {
|
|
113
|
+
return layouts.map((layout) => layout.domain);
|
|
114
|
+
}
|
|
115
|
+
// =============================================================================
|
|
116
|
+
// COMMAND: plugin add <package>
|
|
117
|
+
// =============================================================================
|
|
118
|
+
/**
|
|
119
|
+
* Install a plugin AND add it to the project config in one step.
|
|
120
|
+
*
|
|
121
|
+
* Without the config update, the package wouldn't get loaded — making
|
|
122
|
+
* "install" alone always incomplete. Single-step is the only sensible
|
|
123
|
+
* default.
|
|
124
|
+
*/
|
|
125
|
+
// eslint-disable-next-line @typescript-eslint/require-await -- async to keep the Promise<PluginResult> contract; npm install is synchronous via execFileSync
|
|
126
|
+
export async function pluginAdd(packageName, cwd = process.cwd(), domainOverride, layouts = [], scope = {}) {
|
|
127
|
+
if (!packageName) {
|
|
128
|
+
return {
|
|
129
|
+
type: PLUGIN_ADD,
|
|
130
|
+
packageName: '',
|
|
131
|
+
success: false,
|
|
132
|
+
error: 'No package name provided. Usage: opensip plugin add <package-name>',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (!isSafeNpmSpec(packageName)) {
|
|
136
|
+
return {
|
|
137
|
+
type: PLUGIN_ADD,
|
|
138
|
+
packageName,
|
|
139
|
+
success: false,
|
|
140
|
+
error: `Invalid package spec '${packageName}' — must not start with '-' (would be interpreted as an npm flag)`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// Tool-plugin path: install into the user-global (or --project) tool host
|
|
144
|
+
// dir, no config entry (tools auto-discover by marker).
|
|
145
|
+
if (isToolTarget(domainOverride, packageName, cwd)) {
|
|
146
|
+
return addToolPlugin(packageName, cwd, scope.project === true);
|
|
147
|
+
}
|
|
148
|
+
// fit/sim domain path: install into the project-local domain host dir and
|
|
149
|
+
// record in plugins.<domain> so discovery loads it.
|
|
150
|
+
const domains = domainNames(layouts);
|
|
151
|
+
const domain = resolveDomain(domainOverride, packageName, domains);
|
|
152
|
+
if (!domain) {
|
|
153
|
+
return {
|
|
154
|
+
type: PLUGIN_ADD,
|
|
155
|
+
packageName,
|
|
156
|
+
success: false,
|
|
157
|
+
error: `Invalid --domain '${String(domainOverride)}' — expected one of: ${[...domains, TOOL_DOMAIN].join(', ')}`,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const dir = ensurePluginHostDir(domain, cwd);
|
|
161
|
+
const outcome = npmInstallIntoHost(dir, packageName);
|
|
162
|
+
if (!outcome.ok) {
|
|
163
|
+
return { type: PLUGIN_ADD, packageName, success: false, error: outcome.error };
|
|
164
|
+
}
|
|
165
|
+
// Update the project config so discovery actually loads it.
|
|
166
|
+
addToConfigPluginList(resolveProjectPaths(cwd).configFile, domain, outcome.installedName);
|
|
167
|
+
return { type: PLUGIN_ADD, packageName: outcome.installedName, success: true };
|
|
168
|
+
}
|
|
169
|
+
// =============================================================================
|
|
170
|
+
// COMMAND: plugin remove <package>
|
|
171
|
+
// =============================================================================
|
|
172
|
+
// eslint-disable-next-line @typescript-eslint/require-await -- async to keep the Promise<PluginResult> contract; npm uninstall is synchronous via execFileSync
|
|
173
|
+
export async function pluginRemove(packageName, cwd = process.cwd(), domainOverride, layouts = [], scope = {}) {
|
|
174
|
+
if (!packageName) {
|
|
175
|
+
return {
|
|
176
|
+
type: PLUGIN_REMOVE,
|
|
177
|
+
packageName: '',
|
|
178
|
+
success: false,
|
|
179
|
+
error: 'No package name provided. Usage: opensip plugin remove <package-name>',
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
if (!isSafeNpmSpec(packageName)) {
|
|
183
|
+
return {
|
|
184
|
+
type: PLUGIN_REMOVE,
|
|
185
|
+
packageName,
|
|
186
|
+
success: false,
|
|
187
|
+
error: `Invalid package spec '${packageName}' — must not start with '-' (would be interpreted as an npm flag)`,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
// Tool-plugin path: a tool removal targets the tool host dir directly.
|
|
191
|
+
// Detection by an installed package can't read a published marker, so the
|
|
192
|
+
// tool path is keyed on the explicit `--domain tool`.
|
|
193
|
+
if (domainOverride === TOOL_DOMAIN) {
|
|
194
|
+
return removeToolPlugin(packageName, cwd, scope.project === true);
|
|
195
|
+
}
|
|
196
|
+
const domains = domainNames(layouts);
|
|
197
|
+
const domain = resolveDomain(domainOverride, packageName, domains);
|
|
198
|
+
if (!domain) {
|
|
199
|
+
return {
|
|
200
|
+
type: PLUGIN_REMOVE,
|
|
201
|
+
packageName,
|
|
202
|
+
success: false,
|
|
203
|
+
error: `Invalid --domain '${String(domainOverride)}' — expected one of: ${[...domains, TOOL_DOMAIN].join(', ')}`,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
const paths = resolveProjectPaths(cwd);
|
|
207
|
+
const dir = paths.pluginsDir(domain);
|
|
208
|
+
if (!existsSync(join(dir, HOST_PACKAGE_JSON))) {
|
|
209
|
+
return {
|
|
210
|
+
type: PLUGIN_REMOVE,
|
|
211
|
+
packageName,
|
|
212
|
+
success: false,
|
|
213
|
+
error: `No plugins installed in ${domain}/`,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
if (!npmUninstallFromHost(dir, packageName)) {
|
|
217
|
+
return {
|
|
218
|
+
type: PLUGIN_REMOVE,
|
|
219
|
+
packageName,
|
|
220
|
+
success: false,
|
|
221
|
+
error: `Failed to remove ${packageName}`,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
removeFromConfigPluginList(paths.configFile, domain, packageName);
|
|
225
|
+
return { type: PLUGIN_REMOVE, packageName, success: true };
|
|
226
|
+
}
|
|
227
|
+
// =============================================================================
|
|
228
|
+
// COMMAND: plugin sync (post-clone bootstrap)
|
|
229
|
+
// =============================================================================
|
|
230
|
+
/**
|
|
231
|
+
* Install every plugin declared in `plugins.<domain>` for a given
|
|
232
|
+
* domain (or all domains when none specified). Idempotent — re-running
|
|
233
|
+
* after `git pull` updates the install state.
|
|
234
|
+
*
|
|
235
|
+
* The post-clone story: a developer clones a repo with declared
|
|
236
|
+
* plugins, runs `opensip plugin sync`, and the
|
|
237
|
+
* .runtime/plugins/<domain>/node_modules trees are populated. Without
|
|
238
|
+
* this, the first `opensip fit` would warn about every declared
|
|
239
|
+
* plugin being uninstalled.
|
|
240
|
+
*/
|
|
241
|
+
/* eslint-disable @typescript-eslint/require-await, sonarjs/cognitive-complexity --
|
|
242
|
+
* async preserves Promise<PluginResult> contract; complexity is the
|
|
243
|
+
* domain-loop × spec-loop × validate-then-install dispatch
|
|
244
|
+
*/
|
|
245
|
+
export async function pluginSync(cwd = process.cwd(), domainOverride, layouts = []) {
|
|
246
|
+
// pluginSync iterates the plugin-supporting domains contributed by the
|
|
247
|
+
// registered tools (their `pluginLayout.domain`). A --domain override
|
|
248
|
+
// narrows to one, but only if it is one of those domains — an arbitrary
|
|
249
|
+
// string must not drive path construction outside .runtime/plugins/.
|
|
250
|
+
const allDomains = domainNames(layouts);
|
|
251
|
+
const domains = domainOverride && allDomains.includes(domainOverride) ? [domainOverride] : allDomains;
|
|
252
|
+
const synced = [];
|
|
253
|
+
const errors = [];
|
|
254
|
+
for (const domain of domains) {
|
|
255
|
+
const declared = readProjectPluginsList(cwd, domain);
|
|
256
|
+
if (!declared || declared.length === 0)
|
|
257
|
+
continue;
|
|
258
|
+
const dir = ensurePluginHostDir(domain, cwd);
|
|
259
|
+
for (const spec of declared) {
|
|
260
|
+
if (!isSafeNpmSpec(spec)) {
|
|
261
|
+
errors.push(`${domain}: ignoring unsafe spec '${spec}'`);
|
|
262
|
+
synced.push({ domain, package: spec, installed: false });
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
execFileSync('npm', ['install', '--ignore-scripts', spec], {
|
|
267
|
+
cwd: dir,
|
|
268
|
+
stdio: ['ignore', process.stderr, process.stderr],
|
|
269
|
+
});
|
|
270
|
+
synced.push({ domain, package: spec, installed: true });
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
274
|
+
errors.push(`${domain}/${spec}: ${message}`);
|
|
275
|
+
synced.push({ domain, package: spec, installed: false });
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
type: 'plugin-sync',
|
|
281
|
+
synced,
|
|
282
|
+
...(errors.length > 0 ? { errors } : {}),
|
|
283
|
+
success: errors.length === 0,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/* eslint-enable @typescript-eslint/require-await, sonarjs/cognitive-complexity */
|
|
287
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/commands/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* render-outcome — the SINGLE serialization seam for a {@link CommandOutcome}
|
|
3
|
+
* (launch, north-star §5.5). This is the one place an outcome reaches a
|
|
4
|
+
* stream: `--json` writes the WHOLE outcome wrapper to stdout; human mode renders
|
|
5
|
+
* the inner payload (`.envelope` / `.data`) through the existing Ink/text renderer
|
|
6
|
+
* exactly as before.
|
|
7
|
+
*
|
|
8
|
+
* The three former JSON-emit sites — `cli.emitEnvelope`, `cli.emitJson`
|
|
9
|
+
* (cli-context), and `emitCommandResult` (mount-result-command) — all fold into
|
|
10
|
+
* this function via {@link assembleOutcome} builders, so the outer shape can never
|
|
11
|
+
* re-drift across commands. The `one-outcome-shape` guardrail (Phase 5) then fails
|
|
12
|
+
* CI on any stdout JSON write that bypasses this seam.
|
|
13
|
+
*
|
|
14
|
+
* The break: `--json` now nests the (byte-identical) envelope one level down under
|
|
15
|
+
* `.envelope` (run commands) / `.data` (everything else). Human output is
|
|
16
|
+
* unchanged — only the machine shape moves.
|
|
17
|
+
*
|
|
18
|
+
* RAW_STREAM mode ({@link renderRaw}): a command may declare `output:'raw-stream'`
|
|
19
|
+
* (e.g. `sessions show --raw`) to emit the bare inner payload WITHOUT the outer
|
|
20
|
+
* `CommandOutcome` wrapper — the smallest possible machine response for agents.
|
|
21
|
+
* That deliberately opts out of the one-outcome shape, so its single sanctioned
|
|
22
|
+
* write also lives HERE (the one stdout-JSON seam), reached via `cli.emitRaw`, not
|
|
23
|
+
* hand-rolled in each command body.
|
|
24
|
+
*/
|
|
25
|
+
import type { CommandOutcome, CommandResult } from '@opensip-cli/contracts';
|
|
26
|
+
export interface RenderOutcomeOptions {
|
|
27
|
+
/** True when `--json` was requested: serialize the whole outcome to stdout. */
|
|
28
|
+
readonly jsonRequested: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* The human renderer (Ink/text) for the inner payload. Only consulted in human
|
|
31
|
+
* mode; the JSON path never renders. Tools/host pass the context's `render`.
|
|
32
|
+
*/
|
|
33
|
+
readonly render: (result: CommandResult) => Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Render a {@link CommandOutcome}. In `--json` mode, the entire outcome is
|
|
37
|
+
* serialized (the machine consumer reads `.envelope` / `.data` / `.errors`). In
|
|
38
|
+
* human mode, the inner payload is rendered through the supplied renderer — the
|
|
39
|
+
* envelope or the `data` result, byte-identical to the legacy path; an outcome
|
|
40
|
+
* with neither (a pure error/bootstrap outcome) renders nothing here (its human
|
|
41
|
+
* presentation is owned by the error-render path).
|
|
42
|
+
*/
|
|
43
|
+
export declare function renderOutcome(outcome: CommandOutcome, opts: RenderOutcomeOptions): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* RAW_STREAM serialization seam (north-star §5.5, `output:'raw-stream'`). Writes
|
|
46
|
+
* a bare value as a single compact JSON line — the inner payload WITHOUT the
|
|
47
|
+
* `CommandOutcome` wrapper. This is the one sanctioned site for an
|
|
48
|
+
* intentionally-unwrapped machine response (the host binds it to `cli.emitRaw`),
|
|
49
|
+
* so no command body hand-rolls `process.stdout.write(JSON.stringify(...))`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function renderRaw(value: unknown): void;
|
|
52
|
+
//# sourceMappingURL=render-outcome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-outcome.d.ts","sourceRoot":"","sources":["../../src/commands/render-outcome.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAK5E,MAAM,WAAW,oBAAoB;IACnC,+EAA+E;IAC/E,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE9C"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* render-outcome — the SINGLE serialization seam for a {@link CommandOutcome}
|
|
3
|
+
* (launch, north-star §5.5). This is the one place an outcome reaches a
|
|
4
|
+
* stream: `--json` writes the WHOLE outcome wrapper to stdout; human mode renders
|
|
5
|
+
* the inner payload (`.envelope` / `.data`) through the existing Ink/text renderer
|
|
6
|
+
* exactly as before.
|
|
7
|
+
*
|
|
8
|
+
* The three former JSON-emit sites — `cli.emitEnvelope`, `cli.emitJson`
|
|
9
|
+
* (cli-context), and `emitCommandResult` (mount-result-command) — all fold into
|
|
10
|
+
* this function via {@link assembleOutcome} builders, so the outer shape can never
|
|
11
|
+
* re-drift across commands. The `one-outcome-shape` guardrail (Phase 5) then fails
|
|
12
|
+
* CI on any stdout JSON write that bypasses this seam.
|
|
13
|
+
*
|
|
14
|
+
* The break: `--json` now nests the (byte-identical) envelope one level down under
|
|
15
|
+
* `.envelope` (run commands) / `.data` (everything else). Human output is
|
|
16
|
+
* unchanged — only the machine shape moves.
|
|
17
|
+
*
|
|
18
|
+
* RAW_STREAM mode ({@link renderRaw}): a command may declare `output:'raw-stream'`
|
|
19
|
+
* (e.g. `sessions show --raw`) to emit the bare inner payload WITHOUT the outer
|
|
20
|
+
* `CommandOutcome` wrapper — the smallest possible machine response for agents.
|
|
21
|
+
* That deliberately opts out of the one-outcome shape, so its single sanctioned
|
|
22
|
+
* write also lives HERE (the one stdout-JSON seam), reached via `cli.emitRaw`, not
|
|
23
|
+
* hand-rolled in each command body.
|
|
24
|
+
*/
|
|
25
|
+
/** Pretty-print width matches the legacy `formatSignalJson` / `emitJson` writers. */
|
|
26
|
+
const JSON_INDENT = 2;
|
|
27
|
+
/**
|
|
28
|
+
* Render a {@link CommandOutcome}. In `--json` mode, the entire outcome is
|
|
29
|
+
* serialized (the machine consumer reads `.envelope` / `.data` / `.errors`). In
|
|
30
|
+
* human mode, the inner payload is rendered through the supplied renderer — the
|
|
31
|
+
* envelope or the `data` result, byte-identical to the legacy path; an outcome
|
|
32
|
+
* with neither (a pure error/bootstrap outcome) renders nothing here (its human
|
|
33
|
+
* presentation is owned by the error-render path).
|
|
34
|
+
*/
|
|
35
|
+
export async function renderOutcome(outcome, opts) {
|
|
36
|
+
if (opts.jsonRequested) {
|
|
37
|
+
process.stdout.write(JSON.stringify(outcome, null, JSON_INDENT) + '\n');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const inner = outcome.envelope ?? outcome.data;
|
|
41
|
+
if (inner !== undefined) {
|
|
42
|
+
await opts.render(inner);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* RAW_STREAM serialization seam (north-star §5.5, `output:'raw-stream'`). Writes
|
|
47
|
+
* a bare value as a single compact JSON line — the inner payload WITHOUT the
|
|
48
|
+
* `CommandOutcome` wrapper. This is the one sanctioned site for an
|
|
49
|
+
* intentionally-unwrapped machine response (the host binds it to `cli.emitRaw`),
|
|
50
|
+
* so no command body hand-rolls `process.stdout.write(JSON.stringify(...))`.
|
|
51
|
+
*/
|
|
52
|
+
export function renderRaw(value) {
|
|
53
|
+
process.stdout.write(JSON.stringify(value) + '\n');
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=render-outcome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-outcome.js","sourceRoot":"","sources":["../../src/commands/render-outcome.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,qFAAqF;AACrF,MAAM,WAAW,GAAG,CAAC,CAAC;AAYtB;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAuB,EACvB,IAA0B;IAE1B,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAC/C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,CAAC,MAAM,CAAC,KAAsB,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SessionReplayRegistry } from '../session-replay-registry.js';
|
|
2
|
+
import type { CliCommandsContext } from './shared.js';
|
|
3
|
+
import type { ToolShortId } from '@opensip-cli/core';
|
|
4
|
+
export interface ExecuteSessionShowOptions {
|
|
5
|
+
readonly replayRegistry?: SessionReplayRegistry;
|
|
6
|
+
readonly ref: string;
|
|
7
|
+
readonly tool?: ToolShortId;
|
|
8
|
+
readonly json?: boolean;
|
|
9
|
+
/** Agent ergonomics filters (from --filter, repeatable). See Phase 1 plan. */
|
|
10
|
+
readonly filters?: string[];
|
|
11
|
+
/** With json: request the inner payload (session + envelope + metadata) without outer wrapper. */
|
|
12
|
+
readonly raw?: boolean;
|
|
13
|
+
readonly render: CliCommandsContext['render'];
|
|
14
|
+
/** Success machine-output seam — wraps the value in a `CommandOutcome`. */
|
|
15
|
+
readonly emitJson: (value: unknown) => void;
|
|
16
|
+
/**
|
|
17
|
+
* RAW_STREAM seam — emits the bare, unwrapped payload (the `--raw` agent
|
|
18
|
+
* path). The host binds this to `ctx.emitRaw`; the actual stdout write lives
|
|
19
|
+
* in the single `renderRaw` seam, not here.
|
|
20
|
+
*/
|
|
21
|
+
readonly emitRaw: (value: unknown) => void;
|
|
22
|
+
/** Structured-error machine-output seam (launch, §5.5). */
|
|
23
|
+
readonly emitError: CliCommandsContext['emitError'];
|
|
24
|
+
readonly setExitCode: CliCommandsContext['setExitCode'];
|
|
25
|
+
}
|
|
26
|
+
export declare function executeSessionShow(opts: ExecuteSessionShowOptions): Promise<void>;
|
|
27
|
+
//# sourceMappingURL=session-show.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-show.d.ts","sourceRoot":"","sources":["../../src/commands/session-show.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,qBAAqB,CAAC;IAChD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,kGAAkG;IAClG,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC9C,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;IACpD,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;CACzD;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFvF"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { EXIT_CODES } from '@opensip-cli/contracts';
|
|
2
|
+
import { currentScope, SystemError } from '@opensip-cli/core';
|
|
3
|
+
import { resolveSession } from '@opensip-cli/session-store';
|
|
4
|
+
import { SessionReplayRegistry } from '../session-replay-registry.js';
|
|
5
|
+
export async function executeSessionShow(opts) {
|
|
6
|
+
const scope = currentScope();
|
|
7
|
+
if (!scope) {
|
|
8
|
+
throw new SystemError('executeSessionShow called before RunScope was entered. ' +
|
|
9
|
+
'All host command paths (including sessions show) must run inside an entered scope ' +
|
|
10
|
+
'(pre-action-hook constructs and enters; see host-planes-scope-seams-hygiene plan Phase 2).', { code: 'SYSTEM.SCOPE.NOT_ENTERED' });
|
|
11
|
+
}
|
|
12
|
+
const datastore = scope.datastore();
|
|
13
|
+
if (datastore == null) {
|
|
14
|
+
throw new SystemError('Datastore not available via scope for session show (project scope commands must have an open datastore thunk).', { code: 'SYSTEM.SCOPE.DATASTORE_UNAVAILABLE' });
|
|
15
|
+
}
|
|
16
|
+
const resolved = resolveSession(datastore, { ref: opts.ref, tool: opts.tool });
|
|
17
|
+
if (!resolved.ok) {
|
|
18
|
+
await emitSessionShowError(opts, resolved.reason, resolved.detail);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const contribution = (opts.replayRegistry ?? SessionReplayRegistry.empty()).get(resolved.session.tool);
|
|
22
|
+
if (contribution === undefined) {
|
|
23
|
+
await emitSessionShowError(opts, 'replay-unavailable', `session replay is not available for ${resolved.session.tool}`);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
let replay;
|
|
27
|
+
try {
|
|
28
|
+
replay = contribution.replaySession(resolved.session);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
// @handles — a corrupt/legacy stored payload is surfaced to the caller as a
|
|
32
|
+
// structured `decode-error` outcome (not swallowed); see emitSessionShowError.
|
|
33
|
+
await emitSessionShowError(opts, 'decode-error', error instanceof Error ? error.message : String(error));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Apply agent filters (Phase 1) *after* tool replay but before host emission.
|
|
37
|
+
// This keeps per-tool replays pure while enabling token-efficient, focused
|
|
38
|
+
// historical results for agents. The resulting envelope remains a valid
|
|
39
|
+
// (possibly filtered) SignalEnvelope.
|
|
40
|
+
const originalSignalCount = replay.envelope.signals.length;
|
|
41
|
+
const filteredReplay = opts.filters?.length
|
|
42
|
+
? applyFiltersToReplay(resolved.session, replay, opts.filters)
|
|
43
|
+
: replay;
|
|
44
|
+
if (opts.json === true) {
|
|
45
|
+
const jsonPayload = sessionShowJson(resolved.session, filteredReplay, opts.filters, originalSignalCount);
|
|
46
|
+
if (opts.raw) {
|
|
47
|
+
// Raw mode for agents: emit the core payload directly (bypassing the
|
|
48
|
+
// standard CommandOutcome {kind, status, data, ...} wrapper). This gives
|
|
49
|
+
// the smallest possible machine response containing the session metadata +
|
|
50
|
+
// (filtered) envelope + hints. The declared RAW_STREAM output mode for the
|
|
51
|
+
// 'sessions show' command spec (see host-subcommand-groups.ts) is backed by
|
|
52
|
+
// the host `emitRaw` seam — the actual stdout write lives in `renderRaw`,
|
|
53
|
+
// so this body routes through a documented seam, not a raw stdout bypass.
|
|
54
|
+
opts.emitRaw(jsonPayload);
|
|
55
|
+
opts.setExitCode(0);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
opts.emitJson(jsonPayload);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
await opts.render(sessionReplayResult(resolved.session, filteredReplay, opts.filters, originalSignalCount));
|
|
62
|
+
}
|
|
63
|
+
/** Sort rank for `top:N` severity ordering: high (0) before medium (1) before low (2). */
|
|
64
|
+
function severityRank(severity) {
|
|
65
|
+
if (severity === 'high')
|
|
66
|
+
return 0;
|
|
67
|
+
if (severity === 'medium')
|
|
68
|
+
return 1;
|
|
69
|
+
return 2;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Simple, host-side filter applicator for SignalEnvelope signals.
|
|
73
|
+
* errors-only => severity === 'high'
|
|
74
|
+
* warnings-only => severity === 'medium'
|
|
75
|
+
* top:<n> => take first N after severity sort (high, medium, low) + stable order
|
|
76
|
+
* Composable: errors-only + top:20 means top 20 errors.
|
|
77
|
+
*/
|
|
78
|
+
function applyFiltersToReplay(session, replay, filters) {
|
|
79
|
+
const envelope = replay.envelope;
|
|
80
|
+
let signals = [...envelope.signals];
|
|
81
|
+
const hasErrorsOnly = filters.some((f) => f === 'errors-only' || f === 'high');
|
|
82
|
+
const hasWarningsOnly = filters.some((f) => f === 'warnings-only' || f === 'medium');
|
|
83
|
+
if (hasErrorsOnly && !hasWarningsOnly) {
|
|
84
|
+
signals = signals.filter((s) => s.severity === 'high');
|
|
85
|
+
}
|
|
86
|
+
else if (hasWarningsOnly && !hasErrorsOnly) {
|
|
87
|
+
signals = signals.filter((s) => s.severity === 'medium');
|
|
88
|
+
}
|
|
89
|
+
// If both or neither, no severity filter (top will still apply).
|
|
90
|
+
// Apply top:N (last filter wins for simplicity; or take min if multiple).
|
|
91
|
+
const topFilter = filters.find((f) => f.startsWith('top:'));
|
|
92
|
+
if (topFilter) {
|
|
93
|
+
const n = Number.parseInt(topFilter.split(':')[1] || '0', 10);
|
|
94
|
+
if (Number.isFinite(n) && n > 0) {
|
|
95
|
+
// Re-sort for "top": high first, then medium, low, preserving original relative order.
|
|
96
|
+
signals = signals
|
|
97
|
+
.map((s, i) => ({ s, i }))
|
|
98
|
+
.sort((a, b) => {
|
|
99
|
+
const so = severityRank(a.s.severity) - severityRank(b.s.severity);
|
|
100
|
+
return so === 0 ? a.i - b.i : so;
|
|
101
|
+
})
|
|
102
|
+
.slice(0, n)
|
|
103
|
+
.map((x) => x.s);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const filteredEnvelope = { ...envelope, signals };
|
|
107
|
+
return {
|
|
108
|
+
...replay,
|
|
109
|
+
envelope: filteredEnvelope,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function agentFilterMeta(returnedSignalCount, filters, originalSignalCount) {
|
|
113
|
+
if (!filters?.length || originalSignalCount == null)
|
|
114
|
+
return {};
|
|
115
|
+
return { filtersApplied: filters, originalSignalCount, returnedSignalCount };
|
|
116
|
+
}
|
|
117
|
+
function sessionReplayResult(session, replay, filters, originalSignalCount) {
|
|
118
|
+
return {
|
|
119
|
+
type: 'session-replay',
|
|
120
|
+
session: {
|
|
121
|
+
id: session.id,
|
|
122
|
+
tool: session.tool,
|
|
123
|
+
startedAt: session.startedAt,
|
|
124
|
+
completedAt: session.completedAt,
|
|
125
|
+
...(session.recipe === undefined ? {} : { recipe: session.recipe }),
|
|
126
|
+
score: session.score,
|
|
127
|
+
passed: session.passed,
|
|
128
|
+
durationMs: session.durationMs,
|
|
129
|
+
},
|
|
130
|
+
envelope: replay.envelope,
|
|
131
|
+
fidelity: replay.fidelity,
|
|
132
|
+
...agentFilterMeta(replay.envelope.signals.length, filters, originalSignalCount),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function sessionShowJson(session, replay, filters, originalSignalCount) {
|
|
136
|
+
return {
|
|
137
|
+
session: {
|
|
138
|
+
id: session.id,
|
|
139
|
+
tool: session.tool,
|
|
140
|
+
startedAt: session.startedAt,
|
|
141
|
+
completedAt: session.completedAt,
|
|
142
|
+
recipe: session.recipe,
|
|
143
|
+
cwd: session.cwd,
|
|
144
|
+
score: session.score,
|
|
145
|
+
passed: session.passed,
|
|
146
|
+
durationMs: session.durationMs,
|
|
147
|
+
},
|
|
148
|
+
fidelity: replay.fidelity,
|
|
149
|
+
envelope: replay.envelope,
|
|
150
|
+
...agentFilterMeta(replay.envelope.signals.length, filters, originalSignalCount),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
async function emitSessionShowError(opts, reason, detail) {
|
|
154
|
+
if (opts.json === true) {
|
|
155
|
+
// emitError sets the exit code itself (process exit == reported outcome).
|
|
156
|
+
opts.emitError({ message: detail, exitCode: EXIT_CODES.CONFIGURATION_ERROR, code: reason });
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
opts.setExitCode(EXIT_CODES.CONFIGURATION_ERROR);
|
|
160
|
+
await opts.render({
|
|
161
|
+
type: 'error',
|
|
162
|
+
message: detail,
|
|
163
|
+
exitCode: EXIT_CODES.CONFIGURATION_ERROR,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=session-show.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-show.js","sourceRoot":"","sources":["../../src/commands/session-show.ts"],"names":[],"mappings":"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"}
|