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,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* plugin/domain-resolution — pure validation + routing logic for the
|
|
3
|
+
* `plugin add/remove/sync` commands.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from `commands/plugin.ts` to keep that file focused on the
|
|
6
|
+
* command bodies. Everything here decides WHICH host dir / domain a spec
|
|
7
|
+
* targets — it reads package markers but performs no install. The
|
|
8
|
+
* plugin-supporting domains are NOT hardcoded: they come from the
|
|
9
|
+
* registered tools' `pluginLayout` descriptors (threaded in as
|
|
10
|
+
* `PluginLayout[]`), so the kernel stays tool-agnostic and the tools
|
|
11
|
+
* remain the single source of truth (ADR-0009 corollary 1).
|
|
12
|
+
*/
|
|
13
|
+
import { type PluginLayout } from '@opensip-cli/core';
|
|
14
|
+
/**
|
|
15
|
+
* Pseudo-domain for full Tool plugins (whole subcommands). Distinct from
|
|
16
|
+
* the fit/sim plugin DOMAINS (which are project-committed + listed in
|
|
17
|
+
* `plugins.<domain>` config): a Tool plugin auto-discovers by its
|
|
18
|
+
* `opensipTools.kind: "tool"` marker, needs NO config entry, and installs
|
|
19
|
+
* user-global by default (`~/.opensip-cli/plugins/tool`) so the
|
|
20
|
+
* subcommand is available in every project — or project-local
|
|
21
|
+
* (`.runtime/plugins/tool`) with `--project`.
|
|
22
|
+
*/
|
|
23
|
+
export declare const TOOL_DOMAIN = "tool";
|
|
24
|
+
/** The set of plugin-supporting domain names from the contributed layouts. */
|
|
25
|
+
export declare function domainNames(layouts: readonly PluginLayout[]): string[];
|
|
26
|
+
/**
|
|
27
|
+
* Resolve the target domain, rejecting arbitrary strings from --domain.
|
|
28
|
+
* A bare cast would let a caller pass '../../etc' and drive path
|
|
29
|
+
* construction outside opensip-cli/.runtime/.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveDomain(override: string | undefined, packageName: string, domains: readonly string[]): string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Decide whether `plugin add/remove <spec>` targets a Tool plugin:
|
|
34
|
+
* explicit `--domain tool`, or (when no `--domain` is given) a detected
|
|
35
|
+
* `kind: "tool"` marker. An explicit fit/sim `--domain` is honoured as-is.
|
|
36
|
+
*/
|
|
37
|
+
export declare function isToolTarget(domainOverride: string | undefined, spec: string, cwd: string): boolean;
|
|
38
|
+
//# sourceMappingURL=domain-resolution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-resolution.d.ts","sourceRoot":"","sources":["../../../src/commands/plugin/domain-resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIxE;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,SAAS,CAAC;AAElC,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,EAAE,CAEtE;AAaD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,MAAM,GAAG,SAAS,CAGpB;AAqCD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,OAAO,CAIT"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* plugin/domain-resolution — pure validation + routing logic for the
|
|
3
|
+
* `plugin add/remove/sync` commands.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from `commands/plugin.ts` to keep that file focused on the
|
|
6
|
+
* command bodies. Everything here decides WHICH host dir / domain a spec
|
|
7
|
+
* targets — it reads package markers but performs no install. The
|
|
8
|
+
* plugin-supporting domains are NOT hardcoded: they come from the
|
|
9
|
+
* registered tools' `pluginLayout` descriptors (threaded in as
|
|
10
|
+
* `PluginLayout[]`), so the kernel stays tool-agnostic and the tools
|
|
11
|
+
* remain the single source of truth (ADR-0009 corollary 1).
|
|
12
|
+
*/
|
|
13
|
+
import { execFileSync } from 'node:child_process';
|
|
14
|
+
import { isAbsolute, join } from 'node:path';
|
|
15
|
+
import { readDeclaredKind } from '@opensip-cli/core';
|
|
16
|
+
import { extractNameFromSpec } from './host-dir.js';
|
|
17
|
+
/**
|
|
18
|
+
* Pseudo-domain for full Tool plugins (whole subcommands). Distinct from
|
|
19
|
+
* the fit/sim plugin DOMAINS (which are project-committed + listed in
|
|
20
|
+
* `plugins.<domain>` config): a Tool plugin auto-discovers by its
|
|
21
|
+
* `opensipTools.kind: "tool"` marker, needs NO config entry, and installs
|
|
22
|
+
* user-global by default (`~/.opensip-cli/plugins/tool`) so the
|
|
23
|
+
* subcommand is available in every project — or project-local
|
|
24
|
+
* (`.runtime/plugins/tool`) with `--project`.
|
|
25
|
+
*/
|
|
26
|
+
export const TOOL_DOMAIN = 'tool';
|
|
27
|
+
/** The set of plugin-supporting domain names from the contributed layouts. */
|
|
28
|
+
export function domainNames(layouts) {
|
|
29
|
+
return layouts.map((l) => l.domain);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Infer a target domain from a package name when --domain is omitted: the
|
|
33
|
+
* first declared domain whose name appears as a word in the package name,
|
|
34
|
+
* else the first declared domain. Domain names come from trusted
|
|
35
|
+
* first-party layouts, so building a RegExp from them is safe.
|
|
36
|
+
*/
|
|
37
|
+
function inferDomain(packageName, domains) {
|
|
38
|
+
const match = domains.find((d) => new RegExp(String.raw `\b${d}\b`).test(packageName));
|
|
39
|
+
return match ?? domains[0];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the target domain, rejecting arbitrary strings from --domain.
|
|
43
|
+
* A bare cast would let a caller pass '../../etc' and drive path
|
|
44
|
+
* construction outside opensip-cli/.runtime/.
|
|
45
|
+
*/
|
|
46
|
+
export function resolveDomain(override, packageName, domains) {
|
|
47
|
+
if (override === undefined)
|
|
48
|
+
return inferDomain(packageName, domains);
|
|
49
|
+
return domains.includes(override) ? override : undefined;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Detect a package's `opensipTools.kind` BEFORE installing, so `plugin add`
|
|
53
|
+
* can route a Tool plugin to its host dir rather than a fit/sim domain.
|
|
54
|
+
*
|
|
55
|
+
* - Local-path specs (`.`/`/`/`file:`): read the target's package.json
|
|
56
|
+
* directly — free and offline.
|
|
57
|
+
* - Registry specs: `npm view <name> opensipTools.kind` (one network
|
|
58
|
+
* call; `plugin add` is already online for the install).
|
|
59
|
+
*
|
|
60
|
+
* Returns undefined when undetectable (offline, private registry, no
|
|
61
|
+
* marker) — the caller then falls back to fit/sim domain inference. The raw
|
|
62
|
+
* declared kind is returned as a string (the only thing the caller checks is
|
|
63
|
+
* `=== 'tool'`); domain markers are no longer a compiled-in host union.
|
|
64
|
+
*/
|
|
65
|
+
function detectPluginKind(spec, cwd) {
|
|
66
|
+
if (spec.startsWith('/') || spec.startsWith('.') || spec.startsWith('file:')) {
|
|
67
|
+
const raw = spec.startsWith('file:') ? spec.slice('file:'.length) : spec;
|
|
68
|
+
return readDeclaredKind(isAbsolute(raw) ? raw : join(cwd, raw));
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const name = extractNameFromSpec(spec) ?? spec;
|
|
72
|
+
const out = execFileSync('npm', ['view', name, 'opensipTools.kind'], {
|
|
73
|
+
cwd,
|
|
74
|
+
encoding: 'utf8',
|
|
75
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
76
|
+
})
|
|
77
|
+
.toString()
|
|
78
|
+
.trim();
|
|
79
|
+
return out === '' ? undefined : out;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// @fitness-ignore-next-line error-handling-quality -- `npm view` failure (offline, private registry, or no such package) means the kind is undetectable; returning undefined routes the caller to fit/sim domain inference — the documented fallback, not a swallowed error.
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Decide whether `plugin add/remove <spec>` targets a Tool plugin:
|
|
88
|
+
* explicit `--domain tool`, or (when no `--domain` is given) a detected
|
|
89
|
+
* `kind: "tool"` marker. An explicit fit/sim `--domain` is honoured as-is.
|
|
90
|
+
*/
|
|
91
|
+
export function isToolTarget(domainOverride, spec, cwd) {
|
|
92
|
+
if (domainOverride === TOOL_DOMAIN)
|
|
93
|
+
return true;
|
|
94
|
+
if (domainOverride !== undefined)
|
|
95
|
+
return false;
|
|
96
|
+
return detectPluginKind(spec, cwd) === 'tool';
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=domain-resolution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-resolution.js","sourceRoot":"","sources":["../../../src/commands/plugin/domain-resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAqB,MAAM,mBAAmB,CAAC;AAExE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC;AAElC,8EAA8E;AAC9E,MAAM,UAAU,WAAW,CAAC,OAAgC;IAC1D,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,WAAmB,EAAE,OAA0B;IAClE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IACtF,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,QAA4B,EAC5B,WAAmB,EACnB,OAA0B;IAE1B,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACrE,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,gBAAgB,CAAC,IAAY,EAAE,GAAW;IACjD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7E,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzE,OAAO,gBAAgB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;QAC/C,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,mBAAmB,CAAC,EAAE;YACnE,GAAG;YACH,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC;aACC,QAAQ,EAAE;aACV,IAAI,EAAE,CAAC;QACV,OAAO,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,6QAA6Q;QAC7Q,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,cAAkC,EAClC,IAAY,EACZ,GAAW;IAEX,IAAI,cAAc,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAChD,IAAI,cAAc,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC/C,OAAO,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,MAAM,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Plugin host directory + installed-package introspection.
|
|
3
|
+
*
|
|
4
|
+
* Each plugin domain owns a `node_modules` tree under
|
|
5
|
+
* `<project>/opensip-cli/.runtime/plugins/<domain>/`. This module
|
|
6
|
+
* creates the host package.json, peeks at installed packages to
|
|
7
|
+
* resolve real package names (for local-path specs that don't carry a
|
|
8
|
+
* name), and walks peerDependencies for auto-install.
|
|
9
|
+
*
|
|
10
|
+
* Extracted from `commands/plugin.ts` so the install/uninstall flows
|
|
11
|
+
* there stay focused on Commander + npm orchestration.
|
|
12
|
+
*/
|
|
13
|
+
/** Filename of the host package.json that pins plugin installs. */
|
|
14
|
+
export declare const HOST_PACKAGE_JSON = "package.json";
|
|
15
|
+
/**
|
|
16
|
+
* Guard against argv-injection through npm. execFileSync doesn't spawn
|
|
17
|
+
* a shell, so shell metacharacters are safe, but any arg starting with
|
|
18
|
+
* '-' would be consumed by npm as a flag (e.g. '-g', '--prefix=/etc').
|
|
19
|
+
*/
|
|
20
|
+
export declare function isSafeNpmSpec(spec: string): boolean;
|
|
21
|
+
/** Create the host package.json (if absent) for a plugin host dir + return the dir. */
|
|
22
|
+
/** Create (if absent) a plugin host dir + its host package.json; returns `dir`. */
|
|
23
|
+
export declare function ensureHostDir(dir: string, domain: string): string;
|
|
24
|
+
/** Project-local plugin host dir: `<project>/opensip-cli/.runtime/plugins/<domain>`. */
|
|
25
|
+
export declare function ensurePluginHostDir(domain: string, cwd: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* User-global plugin host dir: `~/.opensip-cli/plugins/<domain>`. Used by
|
|
28
|
+
* the `tool` domain so a `plugin add <tool>` makes the subcommand available
|
|
29
|
+
* across every project (the cross-project analogue of `npm i -g`).
|
|
30
|
+
*/
|
|
31
|
+
export declare function ensureUserPluginHostDir(domain: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* After installing a plugin, look at its peerDependencies and install
|
|
34
|
+
* any missing ones into the same plugin directory. Best-effort: missing
|
|
35
|
+
* peers produce no error here, the loader will surface a clear error if
|
|
36
|
+
* the plugin can't resolve its imports.
|
|
37
|
+
*/
|
|
38
|
+
export declare function installMissingPeers(dir: string, requestedSpec: string, depsBefore: Set<string>): void;
|
|
39
|
+
export declare function findInstalledName(dir: string, requestedSpec: string, depsBefore: Set<string>): string | undefined;
|
|
40
|
+
export declare function readHostDependencies(dir: string): Set<string>;
|
|
41
|
+
export declare function extractNameFromSpec(spec: string): string | undefined;
|
|
42
|
+
//# sourceMappingURL=host-dir.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-dir.d.ts","sourceRoot":"","sources":["../../../src/commands/plugin/host-dir.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAQH,mEAAmE;AACnE,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAInD;AAED,uFAAuF;AACvF,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAoBjE;AAED,wFAAwF;AACxF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GACtB,IAAI,CAsBN;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GACtB,MAAM,GAAG,SAAS,CAEpB;AA2BD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAG7D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAapE"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// @fitness-ignore-file error-handling-quality -- package.json walks / npm-install probes where unreadable/malformed entries mean "not installable" / "not a candidate" — same as absent; npm errors already stream to stderr via inherited stdio.
|
|
2
|
+
// @fitness-ignore-file unbounded-memory -- reads package.json files; bounded by standard npm package metadata shape.
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Plugin host directory + installed-package introspection.
|
|
5
|
+
*
|
|
6
|
+
* Each plugin domain owns a `node_modules` tree under
|
|
7
|
+
* `<project>/opensip-cli/.runtime/plugins/<domain>/`. This module
|
|
8
|
+
* creates the host package.json, peeks at installed packages to
|
|
9
|
+
* resolve real package names (for local-path specs that don't carry a
|
|
10
|
+
* name), and walks peerDependencies for auto-install.
|
|
11
|
+
*
|
|
12
|
+
* Extracted from `commands/plugin.ts` so the install/uninstall flows
|
|
13
|
+
* there stay focused on Commander + npm orchestration.
|
|
14
|
+
*/
|
|
15
|
+
import { execFileSync } from 'node:child_process';
|
|
16
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { resolveProjectPaths, resolveUserPaths } from '@opensip-cli/core';
|
|
19
|
+
/** Filename of the host package.json that pins plugin installs. */
|
|
20
|
+
export const HOST_PACKAGE_JSON = 'package.json';
|
|
21
|
+
/**
|
|
22
|
+
* Guard against argv-injection through npm. execFileSync doesn't spawn
|
|
23
|
+
* a shell, so shell metacharacters are safe, but any arg starting with
|
|
24
|
+
* '-' would be consumed by npm as a flag (e.g. '-g', '--prefix=/etc').
|
|
25
|
+
*/
|
|
26
|
+
export function isSafeNpmSpec(spec) {
|
|
27
|
+
if (spec.length === 0)
|
|
28
|
+
return false;
|
|
29
|
+
if (spec.startsWith('-'))
|
|
30
|
+
return false;
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
/** Create the host package.json (if absent) for a plugin host dir + return the dir. */
|
|
34
|
+
/** Create (if absent) a plugin host dir + its host package.json; returns `dir`. */
|
|
35
|
+
export function ensureHostDir(dir, domain) {
|
|
36
|
+
mkdirSync(dir, { recursive: true });
|
|
37
|
+
const pkgJsonPath = join(dir, HOST_PACKAGE_JSON);
|
|
38
|
+
if (!existsSync(pkgJsonPath)) {
|
|
39
|
+
writeFileSync(pkgJsonPath, JSON.stringify({
|
|
40
|
+
name: `opensip-cli-${domain}-plugins`,
|
|
41
|
+
version: '0.0.0',
|
|
42
|
+
private: true,
|
|
43
|
+
type: 'module',
|
|
44
|
+
dependencies: {},
|
|
45
|
+
}, null, 2));
|
|
46
|
+
}
|
|
47
|
+
return dir;
|
|
48
|
+
}
|
|
49
|
+
/** Project-local plugin host dir: `<project>/opensip-cli/.runtime/plugins/<domain>`. */
|
|
50
|
+
export function ensurePluginHostDir(domain, cwd) {
|
|
51
|
+
return ensureHostDir(resolveProjectPaths(cwd).pluginsDir(domain), domain);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* User-global plugin host dir: `~/.opensip-cli/plugins/<domain>`. Used by
|
|
55
|
+
* the `tool` domain so a `plugin add <tool>` makes the subcommand available
|
|
56
|
+
* across every project (the cross-project analogue of `npm i -g`).
|
|
57
|
+
*/
|
|
58
|
+
export function ensureUserPluginHostDir(domain) {
|
|
59
|
+
return ensureHostDir(resolveUserPaths().pluginsDir(domain), domain);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* After installing a plugin, look at its peerDependencies and install
|
|
63
|
+
* any missing ones into the same plugin directory. Best-effort: missing
|
|
64
|
+
* peers produce no error here, the loader will surface a clear error if
|
|
65
|
+
* the plugin can't resolve its imports.
|
|
66
|
+
*/
|
|
67
|
+
export function installMissingPeers(dir, requestedSpec, depsBefore) {
|
|
68
|
+
const installed = findInstalledPackage(dir, requestedSpec, depsBefore);
|
|
69
|
+
if (!installed)
|
|
70
|
+
return;
|
|
71
|
+
const peerDeps = installed.peerDependencies ?? {};
|
|
72
|
+
const installedAtRoot = new Set(safeReaddirScopedAndFlat(join(dir, 'node_modules')));
|
|
73
|
+
const missing = Object.entries(peerDeps).filter(([name]) => !installedAtRoot.has(name));
|
|
74
|
+
if (missing.length === 0)
|
|
75
|
+
return;
|
|
76
|
+
for (const [name, range] of missing) {
|
|
77
|
+
if (!isSafeNpmSpec(name))
|
|
78
|
+
continue;
|
|
79
|
+
if (typeof range !== 'string' || !isSafeNpmSpec(range))
|
|
80
|
+
continue;
|
|
81
|
+
try {
|
|
82
|
+
execFileSync('npm', ['install', '--ignore-scripts', '--no-save', `${name}@${range}`], {
|
|
83
|
+
cwd: dir,
|
|
84
|
+
stdio: ['ignore', process.stderr, process.stderr],
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Loader will surface unresolved imports; swallow here.
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export function findInstalledName(dir, requestedSpec, depsBefore) {
|
|
93
|
+
return findInstalledPackage(dir, requestedSpec, depsBefore)?.name;
|
|
94
|
+
}
|
|
95
|
+
function findInstalledPackage(dir, requestedSpec, depsBefore) {
|
|
96
|
+
const nodeModulesDir = join(dir, 'node_modules');
|
|
97
|
+
if (!existsSync(nodeModulesDir))
|
|
98
|
+
return undefined;
|
|
99
|
+
const namedSpec = extractNameFromSpec(requestedSpec);
|
|
100
|
+
if (namedSpec) {
|
|
101
|
+
const pkg = readPackageJson(join(nodeModulesDir, namedSpec, HOST_PACKAGE_JSON));
|
|
102
|
+
if (pkg)
|
|
103
|
+
return pkg;
|
|
104
|
+
}
|
|
105
|
+
// Local-path installs: the new dep key is whichever entry is in the
|
|
106
|
+
// host package.json now that wasn't there before.
|
|
107
|
+
const depsAfter = readHostDependencies(dir);
|
|
108
|
+
for (const name of depsAfter) {
|
|
109
|
+
if (depsBefore.has(name))
|
|
110
|
+
continue;
|
|
111
|
+
const pkg = readPackageJson(join(nodeModulesDir, name, HOST_PACKAGE_JSON));
|
|
112
|
+
if (pkg?.name === name)
|
|
113
|
+
return pkg;
|
|
114
|
+
}
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
export function readHostDependencies(dir) {
|
|
118
|
+
const hostPkg = readPackageJson(join(dir, HOST_PACKAGE_JSON));
|
|
119
|
+
return new Set(Object.keys(hostPkg?.dependencies ?? {}));
|
|
120
|
+
}
|
|
121
|
+
export function extractNameFromSpec(spec) {
|
|
122
|
+
if (spec.startsWith('/') || spec.startsWith('.') || spec.startsWith('file:'))
|
|
123
|
+
return undefined;
|
|
124
|
+
if (spec.startsWith('@')) {
|
|
125
|
+
const withoutScope = spec.slice(1);
|
|
126
|
+
const slashIdx = withoutScope.indexOf('/');
|
|
127
|
+
if (slashIdx === -1)
|
|
128
|
+
return undefined;
|
|
129
|
+
const rest = withoutScope.slice(slashIdx + 1);
|
|
130
|
+
const atIdx = rest.indexOf('@');
|
|
131
|
+
const name = atIdx === -1 ? rest : rest.slice(0, atIdx);
|
|
132
|
+
return `@${withoutScope.slice(0, slashIdx)}/${name}`;
|
|
133
|
+
}
|
|
134
|
+
const atIdx = spec.indexOf('@');
|
|
135
|
+
return atIdx === -1 ? spec : spec.slice(0, atIdx);
|
|
136
|
+
}
|
|
137
|
+
function readPackageJson(path) {
|
|
138
|
+
if (!existsSync(path))
|
|
139
|
+
return undefined;
|
|
140
|
+
try {
|
|
141
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function safeReaddirScopedAndFlat(nodeModulesDir) {
|
|
148
|
+
if (!existsSync(nodeModulesDir))
|
|
149
|
+
return [];
|
|
150
|
+
const out = [];
|
|
151
|
+
for (const entry of readdirSync(nodeModulesDir)) {
|
|
152
|
+
if (entry.startsWith('@')) {
|
|
153
|
+
const scopeDir = join(nodeModulesDir, entry);
|
|
154
|
+
try {
|
|
155
|
+
for (const scoped of readdirSync(scopeDir))
|
|
156
|
+
out.push(`${entry}/${scoped}`);
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
/* unreadable scope */
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else if (!entry.startsWith('.')) {
|
|
163
|
+
out.push(entry);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return out;
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=host-dir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-dir.js","sourceRoot":"","sources":["../../../src/commands/plugin/host-dir.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* plugin-host-ops — host-mutation helpers for the `plugin` command.
|
|
3
|
+
*
|
|
4
|
+
* The npm install/uninstall primitives and the Tool-plugin add/remove
|
|
5
|
+
* wrappers that mutate a plugin host dir. Extracted from `plugin.ts` so the
|
|
6
|
+
* command bodies (`pluginList`/`pluginAdd`/`pluginRemove`/`pluginSync`) stay
|
|
7
|
+
* focused on argument validation and config wiring; this module owns the
|
|
8
|
+
* side-effecting npm + host-dir mutation.
|
|
9
|
+
*/
|
|
10
|
+
import type { PluginResult } from '@opensip-cli/contracts';
|
|
11
|
+
export { editPluginList } from './plugin/config-edit.js';
|
|
12
|
+
/** Outcome of an npm install into a host dir: the resolved installed name, or an error message. */
|
|
13
|
+
export type InstallOutcome = {
|
|
14
|
+
readonly ok: true;
|
|
15
|
+
readonly installedName: string;
|
|
16
|
+
} | {
|
|
17
|
+
readonly ok: false;
|
|
18
|
+
readonly error: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* `npm install --ignore-scripts <spec>` into a plugin host dir, then
|
|
22
|
+
* resolve the real installed name and auto-install peers. Shared by the
|
|
23
|
+
* fit/sim domain path and the Tool-plugin path.
|
|
24
|
+
*
|
|
25
|
+
* --ignore-scripts: plugins run via dynamic import() at tool time; they
|
|
26
|
+
* don't legitimately need install-time code execution. Blocks supply-chain
|
|
27
|
+
* attacks via postinstall hooks. npm's stdout is routed to stderr so JSON
|
|
28
|
+
* renderers (which own process stdout) are not contaminated.
|
|
29
|
+
*/
|
|
30
|
+
export declare function npmInstallIntoHost(dir: string, packageName: string): InstallOutcome;
|
|
31
|
+
/**
|
|
32
|
+
* Install a Tool plugin into its host dir (user-global by default,
|
|
33
|
+
* project-local with `--project`). No `plugins.<domain>` config entry —
|
|
34
|
+
* Tool plugins auto-discover by their `kind: "tool"` marker.
|
|
35
|
+
*/
|
|
36
|
+
export declare function addToolPlugin(packageName: string, cwd: string, project: boolean): PluginResult;
|
|
37
|
+
/** npm-uninstall a package from a host dir. Pure of config concerns. */
|
|
38
|
+
export declare function npmUninstallFromHost(dir: string, packageName: string): boolean;
|
|
39
|
+
/** Remove a Tool plugin from its host dir (user-global by default, --project otherwise). */
|
|
40
|
+
export declare function removeToolPlugin(packageName: string, cwd: string, project: boolean): PluginResult;
|
|
41
|
+
//# sourceMappingURL=plugin-host-ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-host-ops.d.ts","sourceRoot":"","sources":["../../src/commands/plugin-host-ops.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AAkBH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAI3D,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAUzD,mGAAmG;AACnG,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,CAwBnF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,YAAY,CAS9F;AAED,wEAAwE;AACxE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAU9E;AAED,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,YAAY,CAsBjG"}
|
|
@@ -0,0 +1,114 @@
|
|
|
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-host-ops — host-mutation helpers for the `plugin` command.
|
|
4
|
+
*
|
|
5
|
+
* The npm install/uninstall primitives and the Tool-plugin add/remove
|
|
6
|
+
* wrappers that mutate a plugin host dir. Extracted from `plugin.ts` so the
|
|
7
|
+
* command bodies (`pluginList`/`pluginAdd`/`pluginRemove`/`pluginSync`) stay
|
|
8
|
+
* focused on argument validation and config wiring; this module owns the
|
|
9
|
+
* side-effecting npm + host-dir mutation.
|
|
10
|
+
*/
|
|
11
|
+
import { execFileSync } from 'node:child_process';
|
|
12
|
+
import { existsSync } from 'node:fs';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { resolveProjectPaths, resolveUserPaths } from '@opensip-cli/core';
|
|
15
|
+
import { TOOL_DOMAIN } from './plugin/domain-resolution.js';
|
|
16
|
+
import { ensurePluginHostDir, ensureUserPluginHostDir, findInstalledName, HOST_PACKAGE_JSON, installMissingPeers, readHostDependencies, } from './plugin/host-dir.js';
|
|
17
|
+
// Re-exported so the test hook (`__test.editPluginList`) and any host-ops
|
|
18
|
+
// consumer have a single import home for the host-mutation surface.
|
|
19
|
+
export { editPluginList } from './plugin/config-edit.js';
|
|
20
|
+
/**
|
|
21
|
+
* CommandResult discriminator literals. `as const` keeps the literal type
|
|
22
|
+
* (so the PluginResult union still narrows) while satisfying
|
|
23
|
+
* sonarjs/no-duplicate-string — no scattered eslint-disable needed.
|
|
24
|
+
*/
|
|
25
|
+
const PLUGIN_ADD = 'plugin-add';
|
|
26
|
+
const PLUGIN_REMOVE = 'plugin-remove';
|
|
27
|
+
/**
|
|
28
|
+
* `npm install --ignore-scripts <spec>` into a plugin host dir, then
|
|
29
|
+
* resolve the real installed name and auto-install peers. Shared by the
|
|
30
|
+
* fit/sim domain path and the Tool-plugin path.
|
|
31
|
+
*
|
|
32
|
+
* --ignore-scripts: plugins run via dynamic import() at tool time; they
|
|
33
|
+
* don't legitimately need install-time code execution. Blocks supply-chain
|
|
34
|
+
* attacks via postinstall hooks. npm's stdout is routed to stderr so JSON
|
|
35
|
+
* renderers (which own process stdout) are not contaminated.
|
|
36
|
+
*/
|
|
37
|
+
export function npmInstallIntoHost(dir, packageName) {
|
|
38
|
+
const depsBefore = readHostDependencies(dir);
|
|
39
|
+
try {
|
|
40
|
+
execFileSync('npm', ['install', '--ignore-scripts', packageName], {
|
|
41
|
+
cwd: dir,
|
|
42
|
+
stdio: ['ignore', process.stderr, process.stderr],
|
|
43
|
+
});
|
|
44
|
+
const resolvedName = findInstalledName(dir, packageName, depsBefore);
|
|
45
|
+
const isLocalPathSpec = packageName.startsWith('/') || packageName.startsWith('.') || packageName.startsWith('file:');
|
|
46
|
+
if (!resolvedName && isLocalPathSpec) {
|
|
47
|
+
return {
|
|
48
|
+
ok: false,
|
|
49
|
+
error: `Installed '${packageName}' but could not resolve the installed package name from package.json. The install was not recorded; remove and retry.`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
installMissingPeers(dir, packageName, depsBefore);
|
|
53
|
+
return { ok: true, installedName: resolvedName ?? packageName };
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
error: `Failed to add ${packageName}: ${error instanceof Error ? error.message : String(error)}`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Install a Tool plugin into its host dir (user-global by default,
|
|
64
|
+
* project-local with `--project`). No `plugins.<domain>` config entry —
|
|
65
|
+
* Tool plugins auto-discover by their `kind: "tool"` marker.
|
|
66
|
+
*/
|
|
67
|
+
export function addToolPlugin(packageName, cwd, project) {
|
|
68
|
+
const dir = project
|
|
69
|
+
? ensurePluginHostDir(TOOL_DOMAIN, cwd)
|
|
70
|
+
: ensureUserPluginHostDir(TOOL_DOMAIN);
|
|
71
|
+
const outcome = npmInstallIntoHost(dir, packageName);
|
|
72
|
+
if (!outcome.ok) {
|
|
73
|
+
return { type: PLUGIN_ADD, packageName, success: false, error: outcome.error };
|
|
74
|
+
}
|
|
75
|
+
return { type: PLUGIN_ADD, packageName: outcome.installedName, success: true };
|
|
76
|
+
}
|
|
77
|
+
/** npm-uninstall a package from a host dir. Pure of config concerns. */
|
|
78
|
+
export function npmUninstallFromHost(dir, packageName) {
|
|
79
|
+
try {
|
|
80
|
+
execFileSync('npm', ['uninstall', packageName], {
|
|
81
|
+
cwd: dir,
|
|
82
|
+
stdio: ['ignore', process.stderr, process.stderr],
|
|
83
|
+
});
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/** Remove a Tool plugin from its host dir (user-global by default, --project otherwise). */
|
|
91
|
+
export function removeToolPlugin(packageName, cwd, project) {
|
|
92
|
+
const dir = project
|
|
93
|
+
? resolveProjectPaths(cwd).pluginsDir(TOOL_DOMAIN)
|
|
94
|
+
: resolveUserPaths().pluginsDir(TOOL_DOMAIN);
|
|
95
|
+
if (!existsSync(join(dir, HOST_PACKAGE_JSON))) {
|
|
96
|
+
return {
|
|
97
|
+
type: PLUGIN_REMOVE,
|
|
98
|
+
packageName,
|
|
99
|
+
success: false,
|
|
100
|
+
error: `No tool plugins installed in ${dir}`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (!npmUninstallFromHost(dir, packageName)) {
|
|
104
|
+
return {
|
|
105
|
+
type: PLUGIN_REMOVE,
|
|
106
|
+
packageName,
|
|
107
|
+
success: false,
|
|
108
|
+
error: `Failed to remove ${packageName}`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
// No config entry to clean up — tool plugins auto-discover by marker.
|
|
112
|
+
return { type: PLUGIN_REMOVE, packageName, success: true };
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=plugin-host-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-host-ops.js","sourceRoot":"","sources":["../../src/commands/plugin-host-ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* plugin command — manage project-local npm-installed plugins.
|
|
3
|
+
*
|
|
4
|
+
* Layout (no user-global plugin dir):
|
|
5
|
+
*
|
|
6
|
+
* <project>/opensip-cli/.runtime/plugins/<domain>/
|
|
7
|
+
* ├── package.json — host package; "dependencies" is the
|
|
8
|
+
* │ plugin install state for this domain
|
|
9
|
+
* └── node_modules/ — npm-installed plugin packages
|
|
10
|
+
*
|
|
11
|
+
* <project>/opensip-cli.config.yml
|
|
12
|
+
* plugins:
|
|
13
|
+
* fit:
|
|
14
|
+
* - "@org/fitness-checks" — declares which installed packages
|
|
15
|
+
* discovery should LOAD. Required;
|
|
16
|
+
* discovery does not auto-load every
|
|
17
|
+
* installed package (silent loads
|
|
18
|
+
* would surprise users).
|
|
19
|
+
*
|
|
20
|
+
* `plugin add <pkg>` is the one-step install: writes the package to
|
|
21
|
+
* .runtime/plugins/<domain>/node_modules AND adds it to plugins.<domain>
|
|
22
|
+
* in the project config. After: `opensip fit` loads it on next run.
|
|
23
|
+
*
|
|
24
|
+
* `plugin remove <pkg>` is the inverse: removes from node_modules AND
|
|
25
|
+
* deletes from plugins.<domain>.
|
|
26
|
+
*
|
|
27
|
+
* `plugin list` walks .runtime/plugins/<domain>/node_modules + the
|
|
28
|
+
* config to show what's installed and what's currently loaded.
|
|
29
|
+
*
|
|
30
|
+
* `plugin sync` is the post-clone bootstrap: reads plugins.<domain> from
|
|
31
|
+
* the config and `npm install`s everything declared. Used by CI and
|
|
32
|
+
* by users who clone a repo with custom plugins.
|
|
33
|
+
*
|
|
34
|
+
* Module layout
|
|
35
|
+
* -------------
|
|
36
|
+
* - This file owns the `plugin {list,add,remove,sync}` command bodies.
|
|
37
|
+
* - `plugin/config-edit.ts` — YAML round-trip edits to plugins.<domain>.
|
|
38
|
+
* - `plugin/domain-resolution.ts` — TOOL_DOMAIN + the pure validation
|
|
39
|
+
* logic that routes a spec to a domain / Tool host dir (no install).
|
|
40
|
+
* - `plugin/host-dir.ts` — host package.json creation + installed-
|
|
41
|
+
* package introspection (incl. peer-dependency auto-install).
|
|
42
|
+
*/
|
|
43
|
+
import { type PluginLayout, type ToolProvenance } from '@opensip-cli/core';
|
|
44
|
+
import { editPluginList } from './plugin-host-ops.js';
|
|
45
|
+
import type { PluginResult } from '@opensip-cli/contracts';
|
|
46
|
+
/** Options shared by `plugin add`/`remove` for Tool-plugin scope selection. */
|
|
47
|
+
export interface PluginScopeOpts {
|
|
48
|
+
/** Install/remove a Tool plugin in the project-local host dir instead of user-global. */
|
|
49
|
+
readonly project?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Test-only export for the YAML-driven config edit so unit tests can
|
|
53
|
+
* exercise the round-trip behaviour without spawning npm. Intentionally
|
|
54
|
+
* not part of the public CLI API surface.
|
|
55
|
+
*/
|
|
56
|
+
export declare const __test: {
|
|
57
|
+
editPluginList: typeof editPluginList;
|
|
58
|
+
};
|
|
59
|
+
export declare function pluginList(cwd?: string, layouts?: readonly PluginLayout[], toolProvenance?: readonly ToolProvenance[]): Promise<PluginResult>;
|
|
60
|
+
/**
|
|
61
|
+
* Install a plugin AND add it to the project config in one step.
|
|
62
|
+
*
|
|
63
|
+
* Without the config update, the package wouldn't get loaded — making
|
|
64
|
+
* "install" alone always incomplete. Single-step is the only sensible
|
|
65
|
+
* default.
|
|
66
|
+
*/
|
|
67
|
+
export declare function pluginAdd(packageName: string | undefined, cwd?: string, domainOverride?: string, layouts?: readonly PluginLayout[], scope?: PluginScopeOpts): Promise<PluginResult>;
|
|
68
|
+
export declare function pluginRemove(packageName: string | undefined, cwd?: string, domainOverride?: string, layouts?: readonly PluginLayout[], scope?: PluginScopeOpts): Promise<PluginResult>;
|
|
69
|
+
/**
|
|
70
|
+
* Install every plugin declared in `plugins.<domain>` for a given
|
|
71
|
+
* domain (or all domains when none specified). Idempotent — re-running
|
|
72
|
+
* after `git pull` updates the install state.
|
|
73
|
+
*
|
|
74
|
+
* The post-clone story: a developer clones a repo with declared
|
|
75
|
+
* plugins, runs `opensip plugin sync`, and the
|
|
76
|
+
* .runtime/plugins/<domain>/node_modules trees are populated. Without
|
|
77
|
+
* this, the first `opensip fit` would warn about every declared
|
|
78
|
+
* plugin being uninstalled.
|
|
79
|
+
*/
|
|
80
|
+
export declare function pluginSync(cwd?: string, domainOverride?: string, layouts?: readonly PluginLayout[]): Promise<PluginResult>;
|
|
81
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/commands/plugin.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAMH,OAAO,EAKL,KAAK,YAAY,EACjB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAU3B,OAAO,EAEL,cAAc,EAIf,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAc,YAAY,EAAa,MAAM,wBAAwB,CAAC;AAUlF,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,yFAAyF;IACzF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM;;CAAqB,CAAC;AAMzC,wBAAsB,UAAU,CAC9B,GAAG,GAAE,MAAsB,EAC3B,OAAO,GAAE,SAAS,YAAY,EAAO,EAGrC,cAAc,GAAE,SAAS,cAAc,EAAO,GAC7C,OAAO,CAAC,YAAY,CAAC,CA2CvB;AAUD;;;;;;GAMG;AAEH,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,GAAG,GAAE,MAAsB,EAC3B,cAAc,CAAC,EAAE,MAAM,EACvB,OAAO,GAAE,SAAS,YAAY,EAAO,EACrC,KAAK,GAAE,eAAoB,GAC1B,OAAO,CAAC,YAAY,CAAC,CA6CvB;AAOD,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,GAAG,GAAE,MAAsB,EAC3B,cAAc,CAAC,EAAE,MAAM,EACvB,OAAO,GAAE,SAAS,YAAY,EAAO,EACrC,KAAK,GAAE,eAAoB,GAC1B,OAAO,CAAC,YAAY,CAAC,CA0DvB;AAMD;;;;;;;;;;GAUG;AAKH,wBAAsB,UAAU,CAC9B,GAAG,GAAE,MAAsB,EAC3B,cAAc,CAAC,EAAE,MAAM,EACvB,OAAO,GAAE,SAAS,YAAY,EAAO,GACpC,OAAO,CAAC,YAAY,CAAC,CA4CvB"}
|