@untangle-code/cli 0.0.0-stage → 0.1.1
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 +661 -0
- package/NOTICE +90 -0
- package/README.md +451 -2
- package/THIRD_PARTY_LICENSES.md +152 -0
- package/dist/cli/args.d.ts +48 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +167 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/command.d.ts +69 -0
- package/dist/cli/command.d.ts.map +1 -0
- package/dist/cli/command.js +82 -0
- package/dist/cli/command.js.map +1 -0
- package/dist/cli/deadline.d.ts +33 -0
- package/dist/cli/deadline.d.ts.map +1 -0
- package/dist/cli/deadline.js +49 -0
- package/dist/cli/deadline.js.map +1 -0
- package/dist/cli/embedder-deadline.d.ts +72 -0
- package/dist/cli/embedder-deadline.d.ts.map +1 -0
- package/dist/cli/embedder-deadline.js +117 -0
- package/dist/cli/embedder-deadline.js.map +1 -0
- package/dist/cli/exit.d.ts +71 -0
- package/dist/cli/exit.d.ts.map +1 -0
- package/dist/cli/exit.js +81 -0
- package/dist/cli/exit.js.map +1 -0
- package/dist/cli/graphs.d.ts +65 -0
- package/dist/cli/graphs.d.ts.map +1 -0
- package/dist/cli/graphs.js +108 -0
- package/dist/cli/graphs.js.map +1 -0
- package/dist/cli/index-freshness.d.ts +13 -0
- package/dist/cli/index-freshness.d.ts.map +1 -0
- package/dist/cli/index-freshness.js +226 -0
- package/dist/cli/index-freshness.js.map +1 -0
- package/dist/cli/index-refresh.d.ts +10 -0
- package/dist/cli/index-refresh.d.ts.map +1 -0
- package/dist/cli/index-refresh.js +76 -0
- package/dist/cli/index-refresh.js.map +1 -0
- package/dist/cli/index-state.d.ts +184 -0
- package/dist/cli/index-state.d.ts.map +1 -0
- package/dist/cli/index-state.js +852 -0
- package/dist/cli/index-state.js.map +1 -0
- package/dist/cli/io.d.ts +29 -0
- package/dist/cli/io.d.ts.map +1 -0
- package/dist/cli/io.js +42 -0
- package/dist/cli/io.js.map +1 -0
- package/dist/cli/language-support.d.ts +77 -0
- package/dist/cli/language-support.d.ts.map +1 -0
- package/dist/cli/language-support.js +152 -0
- package/dist/cli/language-support.js.map +1 -0
- package/dist/cli/renewing-lease.d.ts +26 -0
- package/dist/cli/renewing-lease.d.ts.map +1 -0
- package/dist/cli/renewing-lease.js +102 -0
- package/dist/cli/renewing-lease.js.map +1 -0
- package/dist/cli/search-graph-enrichment.d.ts +16 -0
- package/dist/cli/search-graph-enrichment.d.ts.map +1 -0
- package/dist/cli/search-graph-enrichment.js +428 -0
- package/dist/cli/search-graph-enrichment.js.map +1 -0
- package/dist/cli/system.d.ts +34 -0
- package/dist/cli/system.d.ts.map +1 -0
- package/dist/cli/system.js +89 -0
- package/dist/cli/system.js.map +1 -0
- package/dist/cli/vector-store-policy.d.ts +116 -0
- package/dist/cli/vector-store-policy.d.ts.map +1 -0
- package/dist/cli/vector-store-policy.js +160 -0
- package/dist/cli/vector-store-policy.js.map +1 -0
- package/dist/cli/version.d.ts +3 -0
- package/dist/cli/version.d.ts.map +1 -0
- package/dist/cli/version.js +3 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/cli/workspace.d.ts +105 -0
- package/dist/cli/workspace.d.ts.map +1 -0
- package/dist/cli/workspace.js +215 -0
- package/dist/cli/workspace.js.map +1 -0
- package/dist/commands/complexity.d.ts +72 -0
- package/dist/commands/complexity.d.ts.map +1 -0
- package/dist/commands/complexity.js +580 -0
- package/dist/commands/complexity.js.map +1 -0
- package/dist/commands/doctor.d.ts +66 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +764 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/doctor.languages.d.ts +37 -0
- package/dist/commands/doctor.languages.d.ts.map +1 -0
- package/dist/commands/doctor.languages.js +143 -0
- package/dist/commands/doctor.languages.js.map +1 -0
- package/dist/commands/doctor.storage.d.ts +17 -0
- package/dist/commands/doctor.storage.d.ts.map +1 -0
- package/dist/commands/doctor.storage.js +91 -0
- package/dist/commands/doctor.storage.js.map +1 -0
- package/dist/commands/extensions/add.d.ts +10 -0
- package/dist/commands/extensions/add.d.ts.map +1 -0
- package/dist/commands/extensions/add.js +213 -0
- package/dist/commands/extensions/add.js.map +1 -0
- package/dist/commands/extensions/configure.d.ts +5 -0
- package/dist/commands/extensions/configure.d.ts.map +1 -0
- package/dist/commands/extensions/configure.js +58 -0
- package/dist/commands/extensions/configure.js.map +1 -0
- package/dist/commands/extensions/container.d.ts +15 -0
- package/dist/commands/extensions/container.d.ts.map +1 -0
- package/dist/commands/extensions/container.js +135 -0
- package/dist/commands/extensions/container.js.map +1 -0
- package/dist/commands/extensions/context.d.ts +37 -0
- package/dist/commands/extensions/context.d.ts.map +1 -0
- package/dist/commands/extensions/context.js +72 -0
- package/dist/commands/extensions/context.js.map +1 -0
- package/dist/commands/extensions/enable.d.ts +6 -0
- package/dist/commands/extensions/enable.d.ts.map +1 -0
- package/dist/commands/extensions/enable.js +180 -0
- package/dist/commands/extensions/enable.js.map +1 -0
- package/dist/commands/extensions/environment.d.ts +74 -0
- package/dist/commands/extensions/environment.d.ts.map +1 -0
- package/dist/commands/extensions/environment.js +168 -0
- package/dist/commands/extensions/environment.js.map +1 -0
- package/dist/commands/extensions/feature-scan.d.ts +48 -0
- package/dist/commands/extensions/feature-scan.d.ts.map +1 -0
- package/dist/commands/extensions/feature-scan.js +156 -0
- package/dist/commands/extensions/feature-scan.js.map +1 -0
- package/dist/commands/extensions/invoke.d.ts +60 -0
- package/dist/commands/extensions/invoke.d.ts.map +1 -0
- package/dist/commands/extensions/invoke.js +275 -0
- package/dist/commands/extensions/invoke.js.map +1 -0
- package/dist/commands/extensions/list.d.ts +5 -0
- package/dist/commands/extensions/list.d.ts.map +1 -0
- package/dist/commands/extensions/list.js +125 -0
- package/dist/commands/extensions/list.js.map +1 -0
- package/dist/commands/extensions/logs.d.ts +5 -0
- package/dist/commands/extensions/logs.d.ts.map +1 -0
- package/dist/commands/extensions/logs.js +74 -0
- package/dist/commands/extensions/logs.js.map +1 -0
- package/dist/commands/extensions/provision.d.ts +36 -0
- package/dist/commands/extensions/provision.d.ts.map +1 -0
- package/dist/commands/extensions/provision.js +137 -0
- package/dist/commands/extensions/provision.js.map +1 -0
- package/dist/commands/extensions/remove.d.ts +5 -0
- package/dist/commands/extensions/remove.d.ts.map +1 -0
- package/dist/commands/extensions/remove.js +77 -0
- package/dist/commands/extensions/remove.js.map +1 -0
- package/dist/commands/extensions/render.d.ts +16 -0
- package/dist/commands/extensions/render.d.ts.map +1 -0
- package/dist/commands/extensions/render.js +25 -0
- package/dist/commands/extensions/render.js.map +1 -0
- package/dist/commands/extensions/run.d.ts +30 -0
- package/dist/commands/extensions/run.d.ts.map +1 -0
- package/dist/commands/extensions/run.js +292 -0
- package/dist/commands/extensions/run.js.map +1 -0
- package/dist/commands/extensions/secret-store.d.ts +15 -0
- package/dist/commands/extensions/secret-store.d.ts.map +1 -0
- package/dist/commands/extensions/secret-store.js +164 -0
- package/dist/commands/extensions/secret-store.js.map +1 -0
- package/dist/commands/extensions/setup.d.ts +17 -0
- package/dist/commands/extensions/setup.d.ts.map +1 -0
- package/dist/commands/extensions/setup.js +94 -0
- package/dist/commands/extensions/setup.js.map +1 -0
- package/dist/commands/extensions/source.d.ts +47 -0
- package/dist/commands/extensions/source.d.ts.map +1 -0
- package/dist/commands/extensions/source.js +142 -0
- package/dist/commands/extensions/source.js.map +1 -0
- package/dist/commands/extensions/state.d.ts +62 -0
- package/dist/commands/extensions/state.d.ts.map +1 -0
- package/dist/commands/extensions/state.js +177 -0
- package/dist/commands/extensions/state.js.map +1 -0
- package/dist/commands/extensions/status.d.ts +9 -0
- package/dist/commands/extensions/status.d.ts.map +1 -0
- package/dist/commands/extensions/status.js +239 -0
- package/dist/commands/extensions/status.js.map +1 -0
- package/dist/commands/extensions.d.ts +3 -0
- package/dist/commands/extensions.d.ts.map +1 -0
- package/dist/commands/extensions.js +223 -0
- package/dist/commands/extensions.js.map +1 -0
- package/dist/commands/flow/index.d.ts +3 -0
- package/dist/commands/flow/index.d.ts.map +1 -0
- package/dist/commands/flow/index.js +295 -0
- package/dist/commands/flow/index.js.map +1 -0
- package/dist/commands/flow/limits.d.ts +12 -0
- package/dist/commands/flow/limits.d.ts.map +1 -0
- package/dist/commands/flow/limits.js +13 -0
- package/dist/commands/flow/limits.js.map +1 -0
- package/dist/commands/flow/output.d.ts +8 -0
- package/dist/commands/flow/output.d.ts.map +1 -0
- package/dist/commands/flow/output.js +11 -0
- package/dist/commands/flow/output.js.map +1 -0
- package/dist/commands/flow/render.d.ts +51 -0
- package/dist/commands/flow/render.d.ts.map +1 -0
- package/dist/commands/flow/render.js +220 -0
- package/dist/commands/flow/render.js.map +1 -0
- package/dist/commands/flow/select.d.ts +31 -0
- package/dist/commands/flow/select.d.ts.map +1 -0
- package/dist/commands/flow/select.js +62 -0
- package/dist/commands/flow/select.js.map +1 -0
- package/dist/commands/graph/boundaries-input.d.ts +26 -0
- package/dist/commands/graph/boundaries-input.d.ts.map +1 -0
- package/dist/commands/graph/boundaries-input.js +54 -0
- package/dist/commands/graph/boundaries-input.js.map +1 -0
- package/dist/commands/graph/boundaries.d.ts +4 -0
- package/dist/commands/graph/boundaries.d.ts.map +1 -0
- package/dist/commands/graph/boundaries.js +141 -0
- package/dist/commands/graph/boundaries.js.map +1 -0
- package/dist/commands/graph/bounds.d.ts +16 -0
- package/dist/commands/graph/bounds.d.ts.map +1 -0
- package/dist/commands/graph/bounds.js +22 -0
- package/dist/commands/graph/bounds.js.map +1 -0
- package/dist/commands/graph/category-clusters.d.ts +20 -0
- package/dist/commands/graph/category-clusters.d.ts.map +1 -0
- package/dist/commands/graph/category-clusters.js +158 -0
- package/dist/commands/graph/category-clusters.js.map +1 -0
- package/dist/commands/graph/feature-3d.d.ts +22 -0
- package/dist/commands/graph/feature-3d.d.ts.map +1 -0
- package/dist/commands/graph/feature-3d.js +114 -0
- package/dist/commands/graph/feature-3d.js.map +1 -0
- package/dist/commands/graph/feature-clusters.d.ts +17 -0
- package/dist/commands/graph/feature-clusters.d.ts.map +1 -0
- package/dist/commands/graph/feature-clusters.js +94 -0
- package/dist/commands/graph/feature-clusters.js.map +1 -0
- package/dist/commands/graph/feature-html.d.ts +26 -0
- package/dist/commands/graph/feature-html.d.ts.map +1 -0
- package/dist/commands/graph/feature-html.js +314 -0
- package/dist/commands/graph/feature-html.js.map +1 -0
- package/dist/commands/graph/feature-map.d.ts +31 -0
- package/dist/commands/graph/feature-map.d.ts.map +1 -0
- package/dist/commands/graph/feature-map.js +217 -0
- package/dist/commands/graph/feature-map.js.map +1 -0
- package/dist/commands/graph/feature-model.d.ts +55 -0
- package/dist/commands/graph/feature-model.d.ts.map +1 -0
- package/dist/commands/graph/feature-model.js +167 -0
- package/dist/commands/graph/feature-model.js.map +1 -0
- package/dist/commands/graph/feature-untangle-motion.d.ts +33 -0
- package/dist/commands/graph/feature-untangle-motion.d.ts.map +1 -0
- package/dist/commands/graph/feature-untangle-motion.js +155 -0
- package/dist/commands/graph/feature-untangle-motion.js.map +1 -0
- package/dist/commands/graph/index.d.ts +3 -0
- package/dist/commands/graph/index.d.ts.map +1 -0
- package/dist/commands/graph/index.js +414 -0
- package/dist/commands/graph/index.js.map +1 -0
- package/dist/commands/graph/render.d.ts +63 -0
- package/dist/commands/graph/render.d.ts.map +1 -0
- package/dist/commands/graph/render.js +352 -0
- package/dist/commands/graph/render.js.map +1 -0
- package/dist/commands/graph/select.d.ts +34 -0
- package/dist/commands/graph/select.d.ts.map +1 -0
- package/dist/commands/graph/select.js +55 -0
- package/dist/commands/graph/select.js.map +1 -0
- package/dist/commands/index/index.d.ts +6 -0
- package/dist/commands/index/index.d.ts.map +1 -0
- package/dist/commands/index/index.js +461 -0
- package/dist/commands/index/index.js.map +1 -0
- package/dist/commands/index/render.d.ts +53 -0
- package/dist/commands/index/render.d.ts.map +1 -0
- package/dist/commands/index/render.js +205 -0
- package/dist/commands/index/render.js.map +1 -0
- package/dist/commands/index/target.d.ts +34 -0
- package/dist/commands/index/target.d.ts.map +1 -0
- package/dist/commands/index/target.js +97 -0
- package/dist/commands/index/target.js.map +1 -0
- package/dist/commands/index-watch.d.ts +30 -0
- package/dist/commands/index-watch.d.ts.map +1 -0
- package/dist/commands/index-watch.js +138 -0
- package/dist/commands/index-watch.js.map +1 -0
- package/dist/commands/init/command.d.ts +25 -0
- package/dist/commands/init/command.d.ts.map +1 -0
- package/dist/commands/init/command.js +198 -0
- package/dist/commands/init/command.js.map +1 -0
- package/dist/commands/init/config-draft.d.ts +48 -0
- package/dist/commands/init/config-draft.d.ts.map +1 -0
- package/dist/commands/init/config-draft.js +201 -0
- package/dist/commands/init/config-draft.js.map +1 -0
- package/dist/commands/init/diff.d.ts +33 -0
- package/dist/commands/init/diff.d.ts.map +1 -0
- package/dist/commands/init/diff.js +109 -0
- package/dist/commands/init/diff.js.map +1 -0
- package/dist/commands/init/http-probe.d.ts +26 -0
- package/dist/commands/init/http-probe.d.ts.map +1 -0
- package/dist/commands/init/http-probe.js +144 -0
- package/dist/commands/init/http-probe.js.map +1 -0
- package/dist/commands/init/ignore-rules.d.ts +70 -0
- package/dist/commands/init/ignore-rules.d.ts.map +1 -0
- package/dist/commands/init/ignore-rules.js +146 -0
- package/dist/commands/init/ignore-rules.js.map +1 -0
- package/dist/commands/init/index.d.ts +33 -0
- package/dist/commands/init/index.d.ts.map +1 -0
- package/dist/commands/init/index.js +32 -0
- package/dist/commands/init/index.js.map +1 -0
- package/dist/commands/init/integrations-apply.d.ts +50 -0
- package/dist/commands/init/integrations-apply.d.ts.map +1 -0
- package/dist/commands/init/integrations-apply.js +452 -0
- package/dist/commands/init/integrations-apply.js.map +1 -0
- package/dist/commands/init/integrations-plan.d.ts +68 -0
- package/dist/commands/init/integrations-plan.d.ts.map +1 -0
- package/dist/commands/init/integrations-plan.js +515 -0
- package/dist/commands/init/integrations-plan.js.map +1 -0
- package/dist/commands/init/integrations.d.ts +5 -0
- package/dist/commands/init/integrations.d.ts.map +1 -0
- package/dist/commands/init/integrations.js +4 -0
- package/dist/commands/init/integrations.js.map +1 -0
- package/dist/commands/init/languages.d.ts +55 -0
- package/dist/commands/init/languages.d.ts.map +1 -0
- package/dist/commands/init/languages.js +245 -0
- package/dist/commands/init/languages.js.map +1 -0
- package/dist/commands/init/product-context.d.ts +63 -0
- package/dist/commands/init/product-context.d.ts.map +1 -0
- package/dist/commands/init/product-context.js +390 -0
- package/dist/commands/init/product-context.js.map +1 -0
- package/dist/commands/init/render.d.ts +38 -0
- package/dist/commands/init/render.d.ts.map +1 -0
- package/dist/commands/init/render.js +501 -0
- package/dist/commands/init/render.js.map +1 -0
- package/dist/commands/init/report.d.ts +24 -0
- package/dist/commands/init/report.d.ts.map +1 -0
- package/dist/commands/init/report.js +163 -0
- package/dist/commands/init/report.js.map +1 -0
- package/dist/commands/init/run.d.ts +71 -0
- package/dist/commands/init/run.d.ts.map +1 -0
- package/dist/commands/init/run.js +253 -0
- package/dist/commands/init/run.js.map +1 -0
- package/dist/commands/init/services.d.ts +82 -0
- package/dist/commands/init/services.d.ts.map +1 -0
- package/dist/commands/init/services.js +209 -0
- package/dist/commands/init/services.js.map +1 -0
- package/dist/commands/init/storage.d.ts +8 -0
- package/dist/commands/init/storage.d.ts.map +1 -0
- package/dist/commands/init/storage.js +102 -0
- package/dist/commands/init/storage.js.map +1 -0
- package/dist/commands/init/toml.d.ts +65 -0
- package/dist/commands/init/toml.d.ts.map +1 -0
- package/dist/commands/init/toml.js +159 -0
- package/dist/commands/init/toml.js.map +1 -0
- package/dist/commands/init/topology.d.ts +54 -0
- package/dist/commands/init/topology.d.ts.map +1 -0
- package/dist/commands/init/topology.js +146 -0
- package/dist/commands/init/topology.js.map +1 -0
- package/dist/commands/init/types.d.ts +334 -0
- package/dist/commands/init/types.d.ts.map +1 -0
- package/dist/commands/init/types.js +31 -0
- package/dist/commands/init/types.js.map +1 -0
- package/dist/commands/init/wizard-terminal.d.ts +36 -0
- package/dist/commands/init/wizard-terminal.d.ts.map +1 -0
- package/dist/commands/init/wizard-terminal.js +163 -0
- package/dist/commands/init/wizard-terminal.js.map +1 -0
- package/dist/commands/init/wizard.d.ts +25 -0
- package/dist/commands/init/wizard.d.ts.map +1 -0
- package/dist/commands/init/wizard.js +358 -0
- package/dist/commands/init/wizard.js.map +1 -0
- package/dist/commands/mcp.d.ts +4 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +111 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/product-test-runner.d.ts +4 -0
- package/dist/commands/product-test-runner.d.ts.map +1 -0
- package/dist/commands/product-test-runner.js +85 -0
- package/dist/commands/product-test-runner.js.map +1 -0
- package/dist/commands/product.d.ts +16 -0
- package/dist/commands/product.d.ts.map +1 -0
- package/dist/commands/product.js +262 -0
- package/dist/commands/product.js.map +1 -0
- package/dist/commands/query.d.ts +114 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +783 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/scan.d.ts +10 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +302 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/sdd.d.ts +24 -0
- package/dist/commands/sdd.d.ts.map +1 -0
- package/dist/commands/sdd.js +195 -0
- package/dist/commands/sdd.js.map +1 -0
- package/dist/commands/unavailable.d.ts +40 -0
- package/dist/commands/unavailable.d.ts.map +1 -0
- package/dist/commands/unavailable.js +73 -0
- package/dist/commands/unavailable.js.map +1 -0
- package/dist/commands/watch/analyze.d.ts +69 -0
- package/dist/commands/watch/analyze.d.ts.map +1 -0
- package/dist/commands/watch/analyze.js +402 -0
- package/dist/commands/watch/analyze.js.map +1 -0
- package/dist/commands/watch/cli.d.ts +8 -0
- package/dist/commands/watch/cli.d.ts.map +1 -0
- package/dist/commands/watch/cli.js +97 -0
- package/dist/commands/watch/cli.js.map +1 -0
- package/dist/commands/watch/delta.d.ts +46 -0
- package/dist/commands/watch/delta.d.ts.map +1 -0
- package/dist/commands/watch/delta.js +170 -0
- package/dist/commands/watch/delta.js.map +1 -0
- package/dist/commands/watch/events.d.ts +214 -0
- package/dist/commands/watch/events.d.ts.map +1 -0
- package/dist/commands/watch/events.js +13 -0
- package/dist/commands/watch/events.js.map +1 -0
- package/dist/commands/watch/index.d.ts +19 -0
- package/dist/commands/watch/index.d.ts.map +1 -0
- package/dist/commands/watch/index.js +15 -0
- package/dist/commands/watch/index.js.map +1 -0
- package/dist/commands/watch/options.d.ts +43 -0
- package/dist/commands/watch/options.d.ts.map +1 -0
- package/dist/commands/watch/options.js +193 -0
- package/dist/commands/watch/options.js.map +1 -0
- package/dist/commands/watch/render.d.ts +26 -0
- package/dist/commands/watch/render.d.ts.map +1 -0
- package/dist/commands/watch/render.js +175 -0
- package/dist/commands/watch/render.js.map +1 -0
- package/dist/commands/watch/run.d.ts +14 -0
- package/dist/commands/watch/run.d.ts.map +1 -0
- package/dist/commands/watch/run.js +460 -0
- package/dist/commands/watch/run.js.map +1 -0
- package/dist/commands/watch/runtime.d.ts +67 -0
- package/dist/commands/watch/runtime.d.ts.map +1 -0
- package/dist/commands/watch/runtime.js +149 -0
- package/dist/commands/watch/runtime.js.map +1 -0
- package/dist/commands/watch-command.d.ts +3 -0
- package/dist/commands/watch-command.d.ts.map +1 -0
- package/dist/commands/watch-command.js +273 -0
- package/dist/commands/watch-command.js.map +1 -0
- package/dist/entry-point.d.ts +11 -0
- package/dist/entry-point.d.ts.map +1 -0
- package/dist/entry-point.js +65 -0
- package/dist/entry-point.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +245 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/boundaries-schema.d.ts +262 -0
- package/dist/mcp/boundaries-schema.d.ts.map +1 -0
- package/dist/mcp/boundaries-schema.js +183 -0
- package/dist/mcp/boundaries-schema.js.map +1 -0
- package/dist/mcp/default-runtime.d.ts +16 -0
- package/dist/mcp/default-runtime.d.ts.map +1 -0
- package/dist/mcp/default-runtime.js +718 -0
- package/dist/mcp/default-runtime.js.map +1 -0
- package/dist/mcp/envelope.d.ts +13 -0
- package/dist/mcp/envelope.d.ts.map +1 -0
- package/dist/mcp/envelope.js +29 -0
- package/dist/mcp/envelope.js.map +1 -0
- package/dist/mcp/index.d.ts +8 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +8 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/output-schemas.d.ts +5928 -0
- package/dist/mcp/output-schemas.d.ts.map +1 -0
- package/dist/mcp/output-schemas.js +2814 -0
- package/dist/mcp/output-schemas.js.map +1 -0
- package/dist/mcp/path-sandbox.d.ts +35 -0
- package/dist/mcp/path-sandbox.d.ts.map +1 -0
- package/dist/mcp/path-sandbox.js +128 -0
- package/dist/mcp/path-sandbox.js.map +1 -0
- package/dist/mcp/server.d.ts +155 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +257 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/stdio.d.ts +20 -0
- package/dist/mcp/stdio.d.ts.map +1 -0
- package/dist/mcp/stdio.js +71 -0
- package/dist/mcp/stdio.js.map +1 -0
- package/dist/mcp/tools.d.ts +355 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +319 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/types.d.ts +15 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +45 -0
- package/dist/mcp/types.js.map +1 -0
- package/package.json +99 -3
- package/src/cli/args.ts +231 -0
- package/src/cli/command.ts +146 -0
- package/src/cli/deadline.ts +56 -0
- package/src/cli/embedder-deadline.ts +187 -0
- package/src/cli/exit.ts +94 -0
- package/src/cli/graphs.ts +191 -0
- package/src/cli/index-freshness.ts +303 -0
- package/src/cli/index-refresh.ts +125 -0
- package/src/cli/index-state.ts +1217 -0
- package/src/cli/io.ts +56 -0
- package/src/cli/language-support.ts +203 -0
- package/src/cli/renewing-lease.ts +121 -0
- package/src/cli/search-graph-enrichment.ts +639 -0
- package/src/cli/system.ts +94 -0
- package/src/cli/vector-store-policy.ts +213 -0
- package/src/cli/version.ts +2 -0
- package/src/cli/workspace.ts +324 -0
- package/src/commands/complexity.ts +776 -0
- package/src/commands/doctor.languages.ts +187 -0
- package/src/commands/doctor.storage.ts +124 -0
- package/src/commands/doctor.ts +946 -0
- package/src/commands/extensions/add.ts +312 -0
- package/src/commands/extensions/configure.ts +82 -0
- package/src/commands/extensions/container.ts +209 -0
- package/src/commands/extensions/context.ts +109 -0
- package/src/commands/extensions/enable.ts +237 -0
- package/src/commands/extensions/environment.ts +218 -0
- package/src/commands/extensions/feature-scan.ts +232 -0
- package/src/commands/extensions/invoke.ts +368 -0
- package/src/commands/extensions/list.ts +158 -0
- package/src/commands/extensions/logs.ts +104 -0
- package/src/commands/extensions/provision.ts +206 -0
- package/src/commands/extensions/remove.ts +110 -0
- package/src/commands/extensions/render.ts +32 -0
- package/src/commands/extensions/run.ts +386 -0
- package/src/commands/extensions/secret-store.ts +223 -0
- package/src/commands/extensions/setup.ts +140 -0
- package/src/commands/extensions/source.ts +189 -0
- package/src/commands/extensions/state.ts +252 -0
- package/src/commands/extensions/status.ts +320 -0
- package/src/commands/extensions.ts +280 -0
- package/src/commands/flow/index.ts +402 -0
- package/src/commands/flow/limits.ts +14 -0
- package/src/commands/flow/output.ts +16 -0
- package/src/commands/flow/render.ts +318 -0
- package/src/commands/flow/select.ts +101 -0
- package/src/commands/graph/boundaries-input.ts +63 -0
- package/src/commands/graph/boundaries.ts +182 -0
- package/src/commands/graph/bounds.ts +25 -0
- package/src/commands/graph/category-clusters.ts +194 -0
- package/src/commands/graph/feature-3d.ts +141 -0
- package/src/commands/graph/feature-clusters.ts +125 -0
- package/src/commands/graph/feature-html.ts +336 -0
- package/src/commands/graph/feature-map.ts +270 -0
- package/src/commands/graph/feature-model.ts +234 -0
- package/src/commands/graph/feature-untangle-motion.ts +192 -0
- package/src/commands/graph/index.ts +562 -0
- package/src/commands/graph/render.ts +503 -0
- package/src/commands/graph/select.ts +77 -0
- package/src/commands/index/index.ts +595 -0
- package/src/commands/index/render.ts +325 -0
- package/src/commands/index/target.ts +136 -0
- package/src/commands/index-watch.ts +206 -0
- package/src/commands/init/command.ts +238 -0
- package/src/commands/init/config-draft.ts +235 -0
- package/src/commands/init/diff.ts +117 -0
- package/src/commands/init/http-probe.ts +150 -0
- package/src/commands/init/ignore-rules.ts +170 -0
- package/src/commands/init/index.ts +63 -0
- package/src/commands/init/integrations-apply.ts +618 -0
- package/src/commands/init/integrations-plan.ts +634 -0
- package/src/commands/init/integrations.ts +8 -0
- package/src/commands/init/languages.ts +320 -0
- package/src/commands/init/product-context.ts +576 -0
- package/src/commands/init/render.ts +598 -0
- package/src/commands/init/report.ts +204 -0
- package/src/commands/init/run.ts +349 -0
- package/src/commands/init/services.ts +271 -0
- package/src/commands/init/storage.ts +136 -0
- package/src/commands/init/toml.ts +174 -0
- package/src/commands/init/topology.ts +192 -0
- package/src/commands/init/types.ts +366 -0
- package/src/commands/init/wizard-terminal.ts +206 -0
- package/src/commands/init/wizard.ts +450 -0
- package/src/commands/mcp.ts +123 -0
- package/src/commands/product-test-runner.ts +80 -0
- package/src/commands/product.ts +331 -0
- package/src/commands/query.ts +1032 -0
- package/src/commands/scan.ts +360 -0
- package/src/commands/sdd.ts +243 -0
- package/src/commands/unavailable.ts +92 -0
- package/src/commands/watch/README.md +160 -0
- package/src/commands/watch/analyze.ts +600 -0
- package/src/commands/watch/cli.ts +108 -0
- package/src/commands/watch/delta.ts +186 -0
- package/src/commands/watch/events.ts +235 -0
- package/src/commands/watch/index.ts +53 -0
- package/src/commands/watch/options.ts +234 -0
- package/src/commands/watch/render.ts +240 -0
- package/src/commands/watch/run.ts +553 -0
- package/src/commands/watch/runtime.ts +167 -0
- package/src/commands/watch-command.ts +294 -0
- package/src/entry-point.ts +67 -0
- package/src/index.ts +291 -0
- package/src/mcp/boundaries-schema.ts +193 -0
- package/src/mcp/default-runtime.ts +1034 -0
- package/src/mcp/envelope.ts +57 -0
- package/src/mcp/index.ts +28 -0
- package/src/mcp/output-schemas.ts +3071 -0
- package/src/mcp/path-sandbox.ts +156 -0
- package/src/mcp/server.ts +358 -0
- package/src/mcp/stdio.ts +92 -0
- package/src/mcp/tools.ts +563 -0
- package/src/mcp/types.ts +66 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `untangle extensions status [<id>]`
|
|
3
|
+
*
|
|
4
|
+
* The read-only view of the two promises B29 makes: every extension runs
|
|
5
|
+
* behind a license gate, and every container image is pinned to a complete
|
|
6
|
+
* digest. Both were already enforced — the gate before any process start, the
|
|
7
|
+
* pin as a validation rule and as `EXTENSION_IMAGE_MISMATCH` at run time —
|
|
8
|
+
* but only ever at the moment of a run. A guarantee nobody can inspect is
|
|
9
|
+
* hard to trust and easy to break unnoticed, so this command shows the pin
|
|
10
|
+
* the runtime would enforce, the gate that stands in front of it, the
|
|
11
|
+
* endpoint that would be contacted, and what the last run did.
|
|
12
|
+
*
|
|
13
|
+
* What it does NOT do is start anything the gate has not cleared. `detect`
|
|
14
|
+
* looks harmless but is not: a version query starts the foreign program, an
|
|
15
|
+
* endpoint probe talks to the foreign service. The runtime therefore refuses
|
|
16
|
+
* both while the gate is open (X5), and this command inherits that refusal
|
|
17
|
+
* rather than re-implementing it. Containers are never started or pulled here
|
|
18
|
+
* under any circumstances (X1); without a container runtime probe the running
|
|
19
|
+
* digest is reported as unknown, with the reason, instead of being quietly
|
|
20
|
+
* omitted (E4).
|
|
21
|
+
*
|
|
22
|
+
* Secrets never appear. Their VALUES are passed to the runtime only so it can
|
|
23
|
+
* redact them from probe output; what the report shows is which required
|
|
24
|
+
* secret is missing, by name and environment variable.
|
|
25
|
+
*/
|
|
26
|
+
import {
|
|
27
|
+
buildHttpAuthHeaders,
|
|
28
|
+
createFetchHttpRunner,
|
|
29
|
+
createNodeProcessRunner,
|
|
30
|
+
defaultProcessLimits,
|
|
31
|
+
detectExtension,
|
|
32
|
+
type ExtensionHealthV1,
|
|
33
|
+
type LicenseGateDecisionV1,
|
|
34
|
+
type LoadedExtensionV1,
|
|
35
|
+
} from "@untangle-code/extension-runtime";
|
|
36
|
+
|
|
37
|
+
import { type ParsedArgs } from "../../cli/args.js";
|
|
38
|
+
import { EXIT, OperationalError } from "../../cli/exit.js";
|
|
39
|
+
import { line, type Io } from "../../cli/io.js";
|
|
40
|
+
|
|
41
|
+
import { createContainerCli } from "./container.js";
|
|
42
|
+
import { explainMissing, findExtension, gateFor, loadExtensionContext } from "./context.js";
|
|
43
|
+
import type { ExtensionEnvironmentV1 } from "./environment.js";
|
|
44
|
+
import { emitJson, renderTable } from "./render.js";
|
|
45
|
+
import { resolveSecretEnvironment } from "./secret-store.js";
|
|
46
|
+
import type { LastRunRecordV1 } from "./state.js";
|
|
47
|
+
|
|
48
|
+
export interface StatusDeps {
|
|
49
|
+
/** Injected in tests so no unit test opens a socket. */
|
|
50
|
+
fetchImpl?: typeof fetch;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** The manifest pin (X6) — `null` when the extension is not container-invoked. */
|
|
54
|
+
interface ImagePinV1 {
|
|
55
|
+
image: string;
|
|
56
|
+
digest: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface StatusRowV1 {
|
|
60
|
+
id: string;
|
|
61
|
+
displayName: string;
|
|
62
|
+
category: string;
|
|
63
|
+
invocation: string[];
|
|
64
|
+
enabled: boolean;
|
|
65
|
+
license: {
|
|
66
|
+
spdxId: string;
|
|
67
|
+
usageRestriction: string;
|
|
68
|
+
gate: LicenseGateDecisionV1;
|
|
69
|
+
};
|
|
70
|
+
pin: ImagePinV1 | null;
|
|
71
|
+
health: ExtensionHealthV1;
|
|
72
|
+
/** Required secrets that are not set here — reported, not fatal. */
|
|
73
|
+
missingSecrets: string[];
|
|
74
|
+
manifestPath: string;
|
|
75
|
+
origin: string;
|
|
76
|
+
lastRun?: LastRunRecordV1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export async function runStatus(
|
|
80
|
+
environment: ExtensionEnvironmentV1,
|
|
81
|
+
args: ParsedArgs,
|
|
82
|
+
io: Io,
|
|
83
|
+
format: "text" | "json",
|
|
84
|
+
deps: StatusDeps = {},
|
|
85
|
+
): Promise<number> {
|
|
86
|
+
const context = await loadExtensionContext(environment);
|
|
87
|
+
const wanted = args.positionals[1];
|
|
88
|
+
|
|
89
|
+
let extensions: LoadedExtensionV1[];
|
|
90
|
+
if (wanted === undefined) {
|
|
91
|
+
extensions = [...context.discovery.extensions];
|
|
92
|
+
} else {
|
|
93
|
+
const found = findExtension(context, wanted);
|
|
94
|
+
if (found === null) {
|
|
95
|
+
throw new OperationalError(
|
|
96
|
+
explainMissing(context, wanted),
|
|
97
|
+
"Install it first: untangle extensions add --from=<path-or-url>",
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
extensions = [found];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const clock = environment.clock;
|
|
104
|
+
const processRunner = createNodeProcessRunner(clock);
|
|
105
|
+
// Nur INSPIZIEREN, nie starten: `status` ist eine Leseoperation (X1). Der
|
|
106
|
+
// laufende Digest ist damit erstmals wirklich beobachtet statt behauptet —
|
|
107
|
+
// bis Welle 12 gab es keine Sonde, und der Abgleich gegen den Pin blieb
|
|
108
|
+
// Vertragsevidenz.
|
|
109
|
+
const containerCli = createContainerCli({
|
|
110
|
+
processRunner,
|
|
111
|
+
limits: { ...defaultProcessLimits(), timeoutMs: 20_000 },
|
|
112
|
+
...(environment.env["UNTANGLE_CONTAINER_CLI"] === undefined
|
|
113
|
+
? {}
|
|
114
|
+
: { command: environment.env["UNTANGLE_CONTAINER_CLI"] }),
|
|
115
|
+
});
|
|
116
|
+
const runtimeDeps = {
|
|
117
|
+
clock,
|
|
118
|
+
random: environment.random,
|
|
119
|
+
processRunner,
|
|
120
|
+
httpRunner: createFetchHttpRunner(
|
|
121
|
+
(deps.fetchImpl ?? fetch) as Parameters<typeof createFetchHttpRunner>[0],
|
|
122
|
+
clock,
|
|
123
|
+
),
|
|
124
|
+
containerProbe: async (
|
|
125
|
+
extension: LoadedExtensionV1,
|
|
126
|
+
probeOptions: { signal?: AbortSignal } = {},
|
|
127
|
+
) => {
|
|
128
|
+
const runtime = await containerCli.available(probeOptions);
|
|
129
|
+
if (!runtime.available) {
|
|
130
|
+
return { available: false, detail: runtime.detail };
|
|
131
|
+
}
|
|
132
|
+
const state = await containerCli.inspect(extension.manifest, probeOptions);
|
|
133
|
+
return {
|
|
134
|
+
available: state.running && state.ownedByUntangle,
|
|
135
|
+
...(state.imageDigest === undefined ? {} : { imageDigest: state.imageDigest }),
|
|
136
|
+
detail: state.detail,
|
|
137
|
+
};
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const rows: StatusRowV1[] = [];
|
|
142
|
+
for (const extension of extensions) {
|
|
143
|
+
const manifest = extension.manifest;
|
|
144
|
+
const gate = gateFor(context, extension);
|
|
145
|
+
|
|
146
|
+
let effectiveEnv: Readonly<Record<string, string | undefined>> = environment.env;
|
|
147
|
+
try {
|
|
148
|
+
effectiveEnv = await resolveSecretEnvironment(environment, manifest);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
context.warnings.push(
|
|
151
|
+
`${manifest.id}: ${error instanceof Error ? error.message : "Cannot read credential configuration"}`,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
const secretValues: string[] = [];
|
|
155
|
+
const missingSecrets: string[] = [];
|
|
156
|
+
const secretEnv: Record<string, string> = {};
|
|
157
|
+
for (const secret of manifest.secrets) {
|
|
158
|
+
if (secret.setupOnly) continue;
|
|
159
|
+
const value = effectiveEnv[secret.envVar];
|
|
160
|
+
if (value === undefined || value === "") {
|
|
161
|
+
if (secret.required) {
|
|
162
|
+
missingSecrets.push(`${secret.name} (${secret.envVar})`);
|
|
163
|
+
}
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
secretEnv[secret.envVar] = value;
|
|
167
|
+
secretValues.push(value);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const httpHeaders = buildHttpAuthHeaders(manifest, effectiveEnv);
|
|
171
|
+
const health = await detectExtension(runtimeDeps, {
|
|
172
|
+
extension,
|
|
173
|
+
licenseGate: gate.tool.status,
|
|
174
|
+
...(Object.keys(httpHeaders).length === 0 ? {} : { httpHeaders }),
|
|
175
|
+
env: {
|
|
176
|
+
PATH: environment.env["PATH"] ?? "",
|
|
177
|
+
...(environment.env["HOME"] === undefined ? {} : { HOME: environment.env["HOME"] }),
|
|
178
|
+
...secretEnv,
|
|
179
|
+
},
|
|
180
|
+
secretValues,
|
|
181
|
+
...(manifest.http?.defaultUrl === undefined ? {} : { httpUrl: manifest.http.defaultUrl }),
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Der Digest gehoert zur EXTENSION, nicht zum Analyseweg. Ein Dienst wird
|
|
185
|
+
// als Container bereitgestellt und ueber HTTP befragt; `detect` betritt den
|
|
186
|
+
// Container-Zweig dann nie, und der Pin bliebe ungeprueft — obwohl genau
|
|
187
|
+
// dieser Container laeuft. Deshalb wird hier unabhaengig vom Aufrufmodus
|
|
188
|
+
// nachgesehen, sobald das Manifest einen Container beschreibt.
|
|
189
|
+
if (manifest.container !== undefined) {
|
|
190
|
+
const state = await containerCli.inspect(manifest);
|
|
191
|
+
if (state.ownedByUntangle && state.imageDigest !== undefined) {
|
|
192
|
+
health.imageDigest = state.imageDigest;
|
|
193
|
+
health.digestMatchesManifest = state.imageDigest === manifest.container.digest;
|
|
194
|
+
} else if (state.exists && !state.ownedByUntangle) {
|
|
195
|
+
health.unavailableReasons.push({ invocation: "container", detail: state.detail });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const lastRun = context.state.lastRuns[manifest.id];
|
|
200
|
+
rows.push({
|
|
201
|
+
id: manifest.id,
|
|
202
|
+
displayName: manifest.displayName,
|
|
203
|
+
category: manifest.category,
|
|
204
|
+
invocation: [...manifest.invocation],
|
|
205
|
+
enabled: context.state.enabled.includes(manifest.id),
|
|
206
|
+
license: {
|
|
207
|
+
spdxId: manifest.license.spdxId,
|
|
208
|
+
usageRestriction: manifest.license.usageRestriction,
|
|
209
|
+
gate,
|
|
210
|
+
},
|
|
211
|
+
pin:
|
|
212
|
+
manifest.container === undefined
|
|
213
|
+
? null
|
|
214
|
+
: { image: manifest.container.image, digest: manifest.container.digest },
|
|
215
|
+
health,
|
|
216
|
+
missingSecrets,
|
|
217
|
+
manifestPath: extension.manifestPath,
|
|
218
|
+
origin: extension.origin,
|
|
219
|
+
...(lastRun === undefined ? {} : { lastRun }),
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (format === "json") {
|
|
224
|
+
emitJson(io, {
|
|
225
|
+
command: "extensions status",
|
|
226
|
+
rootsScanned: context.discovery.rootsScanned,
|
|
227
|
+
projectRootsExcluded: environment.projectRoots,
|
|
228
|
+
extensions: rows,
|
|
229
|
+
rejected: context.discovery.rejected,
|
|
230
|
+
ignored: context.discovery.ignored,
|
|
231
|
+
warnings: context.warnings,
|
|
232
|
+
});
|
|
233
|
+
return EXIT.ok;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
renderText(io, rows, context.discovery.rootsScanned, context.warnings);
|
|
237
|
+
return EXIT.ok;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function renderText(
|
|
241
|
+
io: Io,
|
|
242
|
+
rows: readonly StatusRowV1[],
|
|
243
|
+
rootsScanned: readonly { root: string; exists: boolean }[],
|
|
244
|
+
warnings: readonly string[],
|
|
245
|
+
): void {
|
|
246
|
+
if (rows.length === 0) {
|
|
247
|
+
line(io, "no extensions installed.");
|
|
248
|
+
}
|
|
249
|
+
for (const row of rows) {
|
|
250
|
+
line(io, `${row.id} (${row.displayName})`);
|
|
251
|
+
for (const rendered of renderTable(
|
|
252
|
+
["FIELD", "VALUE"],
|
|
253
|
+
[
|
|
254
|
+
["enabled", row.enabled ? "yes" : "no"],
|
|
255
|
+
["invocation", row.invocation.join(", ")],
|
|
256
|
+
["available", row.health.available ? "yes" : "no"],
|
|
257
|
+
["effective mode", row.health.effectiveInvocation ?? "—"],
|
|
258
|
+
["tool version", row.health.toolVersion ?? "—"],
|
|
259
|
+
["endpoint", row.health.endpoint ?? "—"],
|
|
260
|
+
["binary", row.health.binaryPath ?? "—"],
|
|
261
|
+
["license", `${row.license.spdxId} (${row.license.usageRestriction})`],
|
|
262
|
+
["license gate", `${row.health.licenseGate} — ${row.license.gate.tool.reason}`],
|
|
263
|
+
["pinned image", row.pin === null ? "— (not container-invoked)" : row.pin.image],
|
|
264
|
+
["pinned digest", row.pin === null ? "—" : row.pin.digest],
|
|
265
|
+
["running digest", describeRunningDigest(row)],
|
|
266
|
+
["last run", describeLastRun(row.lastRun)],
|
|
267
|
+
[
|
|
268
|
+
"missing secrets",
|
|
269
|
+
row.missingSecrets.length === 0 ? "none" : row.missingSecrets.join(", "),
|
|
270
|
+
],
|
|
271
|
+
],
|
|
272
|
+
)) {
|
|
273
|
+
line(io, ` ${rendered}`);
|
|
274
|
+
}
|
|
275
|
+
for (const entry of row.license.gate.rulesets) {
|
|
276
|
+
line(io, ` ruleset ${entry.ruleset}: ${entry.status} — ${entry.reason}`);
|
|
277
|
+
}
|
|
278
|
+
for (const reason of row.health.unavailableReasons) {
|
|
279
|
+
line(io, ` unavailable via ${reason.invocation}: ${reason.detail}`);
|
|
280
|
+
}
|
|
281
|
+
for (const command of row.license.gate.acknowledgeCommands) {
|
|
282
|
+
line(io, ` to acknowledge: ${command}`);
|
|
283
|
+
}
|
|
284
|
+
line(io, ` manifest: ${row.manifestPath} (${row.origin})`);
|
|
285
|
+
line(io, "");
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
line(io, "roots searched (project directories are never searched):");
|
|
289
|
+
for (const root of rootsScanned) {
|
|
290
|
+
line(io, ` ${root.root}${root.exists ? "" : " (does not exist)"}`);
|
|
291
|
+
}
|
|
292
|
+
for (const warning of warnings) {
|
|
293
|
+
line(io, `warning: ${warning}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* A digest that could not be read is said to be unreadable, with the reason.
|
|
299
|
+
* "—" alone would look like "no container", which is a different statement.
|
|
300
|
+
*/
|
|
301
|
+
function describeRunningDigest(row: StatusRowV1): string {
|
|
302
|
+
if (row.pin === null) {
|
|
303
|
+
return "—";
|
|
304
|
+
}
|
|
305
|
+
if (row.health.imageDigest === undefined) {
|
|
306
|
+
return "unknown (nothing was started or pulled to find out)";
|
|
307
|
+
}
|
|
308
|
+
return `${row.health.imageDigest} (${row.health.digestMatchesManifest === true ? "matches the pin" : "DIFFERS from the pin"})`;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function describeLastRun(lastRun: LastRunRecordV1 | undefined): string {
|
|
312
|
+
if (lastRun === undefined) {
|
|
313
|
+
return "never run";
|
|
314
|
+
}
|
|
315
|
+
return (
|
|
316
|
+
`${lastRun.startedAt} ${lastRun.exitStatus}` +
|
|
317
|
+
`${lastRun.errorCode === undefined ? "" : ` (${lastRun.errorCode})`}` +
|
|
318
|
+
`, ${String(lastRun.findingsTotal)} findings`
|
|
319
|
+
);
|
|
320
|
+
}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `untangle extensions` — the analyzer-extension surface (WP-127).
|
|
3
|
+
*
|
|
4
|
+
* ## What this command group is, and what it deliberately is not
|
|
5
|
+
*
|
|
6
|
+
* Untangle ships the extension RUNTIME, the manifest schema and a small set
|
|
7
|
+
* of output-format parsers. It ships NO tool definitions. There is no list of
|
|
8
|
+
* known analyzers in this file, no branch that recognizes a vendor, no
|
|
9
|
+
* bundled manifest — Untangle understands output FORMATS (`sarif`,
|
|
10
|
+
* `junit-xml`, `generic-findings`, `generic-metrics`), and every
|
|
11
|
+
* tool-specific detail arrives as user data inside a manifest
|
|
12
|
+
* (extensions.md §17 "X9"; E2: no third-party product name in this source
|
|
13
|
+
* tree).
|
|
14
|
+
*
|
|
15
|
+
* That is not tidiness. It is what makes "optional" mean optional: if tool
|
|
16
|
+
* definitions shipped with the product, they would be part of the product
|
|
17
|
+
* even while switched off, and the license boundary that keeps AGPL code and
|
|
18
|
+
* source-available analyzers apart would run through this repository instead
|
|
19
|
+
* of around it.
|
|
20
|
+
*
|
|
21
|
+
* ## The security boundary you will notice first
|
|
22
|
+
*
|
|
23
|
+
* A manifest in the PROJECT directory is never loaded automatically. Only the
|
|
24
|
+
* user profile is searched (`~/.untangle/extensions/<id>/manifest.toml` and
|
|
25
|
+
* the OS data directory). A manifest is a description of how to start a
|
|
26
|
+
* program; if the working directory were a search path, `git clone` of a
|
|
27
|
+
* stranger's repository would be enough to place a program invocation in
|
|
28
|
+
* front of the runtime. `add --from <path inside a project>` therefore
|
|
29
|
+
* refuses unless the user types `--allow-project-local` in that very command.
|
|
30
|
+
*/
|
|
31
|
+
import type { FlagSpecs, ParsedArgs } from "../cli/args.js";
|
|
32
|
+
import { enumFlag } from "../cli/args.js";
|
|
33
|
+
import type { Command, CommandContext } from "../cli/command.js";
|
|
34
|
+
import { EXIT, UsageError } from "../cli/exit.js";
|
|
35
|
+
|
|
36
|
+
import { runAdd } from "./extensions/add.js";
|
|
37
|
+
import { runConfigure } from "./extensions/configure.js";
|
|
38
|
+
import { runDisable, runEnable } from "./extensions/enable.js";
|
|
39
|
+
import { createExtensionEnvironment } from "./extensions/environment.js";
|
|
40
|
+
import { runList } from "./extensions/list.js";
|
|
41
|
+
import { runLogs } from "./extensions/logs.js";
|
|
42
|
+
import { runRemove } from "./extensions/remove.js";
|
|
43
|
+
import { runRun } from "./extensions/run.js";
|
|
44
|
+
import { runStatus } from "./extensions/status.js";
|
|
45
|
+
|
|
46
|
+
const FLAGS: FlagSpecs = {
|
|
47
|
+
from: {
|
|
48
|
+
kind: "string",
|
|
49
|
+
placeholder: "URL|PATH",
|
|
50
|
+
describe: "add: manifest source. configure: private JSON file containing secret values.",
|
|
51
|
+
},
|
|
52
|
+
digest: {
|
|
53
|
+
kind: "string",
|
|
54
|
+
placeholder: "sha256:HEX",
|
|
55
|
+
describe: "add: expected manifest sha256. Required for a URL.",
|
|
56
|
+
},
|
|
57
|
+
"allow-project-local": {
|
|
58
|
+
kind: "boolean",
|
|
59
|
+
describe: "add: explicitly allow a path inside the project directory.",
|
|
60
|
+
},
|
|
61
|
+
force: {
|
|
62
|
+
kind: "boolean",
|
|
63
|
+
describe: "add: replace an installed extension with the same ID.",
|
|
64
|
+
},
|
|
65
|
+
"acknowledge-license": {
|
|
66
|
+
kind: "boolean",
|
|
67
|
+
describe: "add/enable: acknowledge the tool-license gate, not the ruleset gate.",
|
|
68
|
+
},
|
|
69
|
+
"acknowledge-ruleset": {
|
|
70
|
+
kind: "list",
|
|
71
|
+
placeholder: "ID",
|
|
72
|
+
describe: "add/enable: acknowledge exactly one ruleset. Repeatable.",
|
|
73
|
+
},
|
|
74
|
+
"revoke-license": {
|
|
75
|
+
kind: "boolean",
|
|
76
|
+
describe: "disable/remove: revoke the stored license acknowledgment.",
|
|
77
|
+
},
|
|
78
|
+
category: {
|
|
79
|
+
kind: "string",
|
|
80
|
+
placeholder: "C,...",
|
|
81
|
+
describe: "list: show only extensions in these categories.",
|
|
82
|
+
},
|
|
83
|
+
"enabled-only": {
|
|
84
|
+
kind: "boolean",
|
|
85
|
+
describe: "list: show only enabled extensions.",
|
|
86
|
+
},
|
|
87
|
+
yes: {
|
|
88
|
+
kind: "boolean",
|
|
89
|
+
describe: "run/setup: allow container provisioning and missing-credential setup (X1).",
|
|
90
|
+
},
|
|
91
|
+
tail: {
|
|
92
|
+
kind: "number",
|
|
93
|
+
placeholder: "N",
|
|
94
|
+
describe: "logs: number of trailing lines.",
|
|
95
|
+
defaultLabel: "200",
|
|
96
|
+
},
|
|
97
|
+
"remove-container": {
|
|
98
|
+
kind: "boolean",
|
|
99
|
+
describe: "disable: stop and remove only the owned container, verified by its labels.",
|
|
100
|
+
},
|
|
101
|
+
"remove-volumes": {
|
|
102
|
+
kind: "boolean",
|
|
103
|
+
describe: "disable: also remove named volumes. Destructive.",
|
|
104
|
+
},
|
|
105
|
+
workspace: {
|
|
106
|
+
kind: "string",
|
|
107
|
+
placeholder: "PATH",
|
|
108
|
+
describe: "run: root of the analyzed workspace.",
|
|
109
|
+
defaultLabel: "current directory",
|
|
110
|
+
},
|
|
111
|
+
target: {
|
|
112
|
+
kind: "string",
|
|
113
|
+
placeholder: "PATH",
|
|
114
|
+
describe: "run: analysis target inside the workspace.",
|
|
115
|
+
defaultLabel: "the workspace",
|
|
116
|
+
},
|
|
117
|
+
ruleset: {
|
|
118
|
+
kind: "string",
|
|
119
|
+
placeholder: "NAME",
|
|
120
|
+
describe: "run: effective ruleset; otherwise the manifest's defaultRuleset applies.",
|
|
121
|
+
},
|
|
122
|
+
url: {
|
|
123
|
+
kind: "string",
|
|
124
|
+
placeholder: "URL",
|
|
125
|
+
describe: "run: endpoint for invocation kind `http`.",
|
|
126
|
+
},
|
|
127
|
+
timeout: {
|
|
128
|
+
kind: "number",
|
|
129
|
+
placeholder: "MS",
|
|
130
|
+
describe: "run: execution time budget in milliseconds.",
|
|
131
|
+
defaultLabel: "900000",
|
|
132
|
+
},
|
|
133
|
+
"max-output-bytes": {
|
|
134
|
+
kind: "number",
|
|
135
|
+
placeholder: "N",
|
|
136
|
+
describe: "run: maximum collected tool-output bytes.",
|
|
137
|
+
},
|
|
138
|
+
format: {
|
|
139
|
+
kind: "string",
|
|
140
|
+
placeholder: "text|json",
|
|
141
|
+
describe: "Output format.",
|
|
142
|
+
defaultLabel: "text",
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Which flags each subcommand accepts.
|
|
148
|
+
*
|
|
149
|
+
* The parser validates flags against the union above; this table catches the
|
|
150
|
+
* rest. Without it, `untangle extensions list --from=x` would be silently
|
|
151
|
+
* accepted and silently ignored — precisely the kind of quiet skip E4
|
|
152
|
+
* forbids, one layer above the pipeline.
|
|
153
|
+
*/
|
|
154
|
+
const ALLOWED_FLAGS: Readonly<Record<string, readonly string[]>> = {
|
|
155
|
+
add: [
|
|
156
|
+
"from",
|
|
157
|
+
"digest",
|
|
158
|
+
"allow-project-local",
|
|
159
|
+
"force",
|
|
160
|
+
"acknowledge-license",
|
|
161
|
+
"acknowledge-ruleset",
|
|
162
|
+
"format",
|
|
163
|
+
],
|
|
164
|
+
list: ["category", "enabled-only", "format"],
|
|
165
|
+
status: ["format"],
|
|
166
|
+
configure: ["from", "format"],
|
|
167
|
+
setup: ["workspace", "url", "timeout", "max-output-bytes", "yes", "format"],
|
|
168
|
+
logs: ["tail", "format"],
|
|
169
|
+
enable: ["acknowledge-license", "acknowledge-ruleset", "format"],
|
|
170
|
+
disable: ["revoke-license", "remove-container", "remove-volumes", "format"],
|
|
171
|
+
remove: ["revoke-license", "format"],
|
|
172
|
+
run: ["workspace", "target", "ruleset", "url", "timeout", "max-output-bytes", "yes", "format"],
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const SUBCOMMANDS = Object.keys(ALLOWED_FLAGS);
|
|
176
|
+
|
|
177
|
+
export const extensionsCommand: Command = {
|
|
178
|
+
spec: {
|
|
179
|
+
name: "extensions",
|
|
180
|
+
implementedBy: "commands/extensions.js",
|
|
181
|
+
summary: "Manage and run analyzer extensions",
|
|
182
|
+
usage:
|
|
183
|
+
"untangle extensions <add|list|status|configure|setup|enable|disable|remove|run|logs> [options]",
|
|
184
|
+
details: [
|
|
185
|
+
"Untangle supplies the extension runtime, manifest schema and format parsers, without bundled tool definitions. A manifest is an external artifact you explicitly load (extensions.md §17, X9). The runtime understands formats (sarif, junit-xml, generic-findings, generic-metrics), not individual tools.",
|
|
186
|
+
"Trust boundary: manifests in the project directory are never loaded automatically. Discovery searches only the user profile (~/.untangle/extensions/<id>/manifest.toml and the OS data directory). A manifest specifies how to launch a program; trusting a cloned project's manifest automatically would allow unrequested execution. `add --from` therefore rejects project-local paths unless --allow-project-local is explicit.",
|
|
187
|
+
"Likewise, `add --from <https-URL>` requires --digest: changing content behind a stable URL could silently change findings. X6 forbids mutable container tags for the same reason.",
|
|
188
|
+
"Installing a manifest starts nothing. `enable` records activation without launching processes or containers (X1). Restrictively licensed tools require explicit personal acknowledgment (X5).",
|
|
189
|
+
"`status` previews the effective pinned image digest, running digest and comparison, license and ruleset gates, endpoint and last run. It neither starts containers nor pulls images (X1); an open gate also prevents version probes (X5).",
|
|
190
|
+
"setup --yes provisions the service, configures missing credentials through the manifest's declared setup process and verifies them with an analysis run. configure creates private secret configuration or imports values with --from. Environment variables take precedence; status creates no tokens.",
|
|
191
|
+
"External tool findings are `ExternalFindingV1`: evidence, never Untangle metrics. They never contribute to complexity values or Risk Score (X3), and never change the exit code.",
|
|
192
|
+
],
|
|
193
|
+
flags: FLAGS,
|
|
194
|
+
examples: [
|
|
195
|
+
"untangle extensions add --from=./my-analyzer/manifest.toml",
|
|
196
|
+
"untangle extensions add --from=https://example.invalid/manifest.toml --digest=sha256:<64 hex>",
|
|
197
|
+
"untangle extensions list --format=json",
|
|
198
|
+
"untangle extensions status my-analyzer",
|
|
199
|
+
"untangle extensions configure my-analyzer",
|
|
200
|
+
"untangle extensions setup my-analyzer --yes",
|
|
201
|
+
"untangle extensions enable my-analyzer --acknowledge-license",
|
|
202
|
+
"untangle extensions run my-analyzer --target=src --format=json",
|
|
203
|
+
"untangle extensions remove my-analyzer --revoke-license",
|
|
204
|
+
],
|
|
205
|
+
exitCodes: [
|
|
206
|
+
[EXIT.ok, "The command completed. Findings do not change this code (X3)."],
|
|
207
|
+
[EXIT.operational, "Invalid manifest, missing extension or failed run."],
|
|
208
|
+
[EXIT.usage, "Usage error: unknown subcommand, missing or unsupported option."],
|
|
209
|
+
[
|
|
210
|
+
EXIT.environment,
|
|
211
|
+
"License/ruleset gate is open, or a required secret is missing. Nothing was started.",
|
|
212
|
+
],
|
|
213
|
+
],
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
async run(ctx: CommandContext, args: ParsedArgs): Promise<number> {
|
|
217
|
+
const subcommand = args.positionals[0];
|
|
218
|
+
if (subcommand === undefined) {
|
|
219
|
+
throw new UsageError(
|
|
220
|
+
"`untangle extensions` needs a subcommand.",
|
|
221
|
+
`Choose one of: ${SUBCOMMANDS.join(", ")} — see untangle extensions --help.`,
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
const allowed = ALLOWED_FLAGS[subcommand];
|
|
225
|
+
if (allowed === undefined) {
|
|
226
|
+
throw new UsageError(
|
|
227
|
+
`Unknown subcommand "extensions ${subcommand}".`,
|
|
228
|
+
`Choose one of: ${SUBCOMMANDS.join(", ")}.`,
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
rejectForeignFlags(subcommand, args, allowed);
|
|
232
|
+
|
|
233
|
+
const format = enumFlag(args, "format", ["text", "json"] as const, "text");
|
|
234
|
+
const environment = await createExtensionEnvironment({ cwd: ctx.cwd, env: ctx.env });
|
|
235
|
+
|
|
236
|
+
switch (subcommand) {
|
|
237
|
+
case "add":
|
|
238
|
+
return await runAdd(environment, args, ctx.io, format);
|
|
239
|
+
case "list":
|
|
240
|
+
return await runList(environment, args, ctx.io, format);
|
|
241
|
+
case "status":
|
|
242
|
+
return await runStatus(environment, args, ctx.io, format);
|
|
243
|
+
case "logs":
|
|
244
|
+
return await runLogs(environment, args, ctx.io, format);
|
|
245
|
+
case "enable":
|
|
246
|
+
return await runEnable(environment, args, ctx.io, format);
|
|
247
|
+
case "disable":
|
|
248
|
+
return await runDisable(environment, args, ctx.io, format);
|
|
249
|
+
case "remove":
|
|
250
|
+
return await runRemove(environment, args, ctx.io, format);
|
|
251
|
+
case "configure":
|
|
252
|
+
return await runConfigure(environment, args, ctx.io, format);
|
|
253
|
+
case "setup":
|
|
254
|
+
case "run":
|
|
255
|
+
return await runRun(environment, args, ctx.io, format, { signal: ctx.signal });
|
|
256
|
+
default:
|
|
257
|
+
throw new UsageError(
|
|
258
|
+
`Unknown subcommand "extensions ${subcommand}".`,
|
|
259
|
+
`Choose one of: ${SUBCOMMANDS.join(", ")}.`,
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
function rejectForeignFlags(
|
|
266
|
+
subcommand: string,
|
|
267
|
+
args: ParsedArgs,
|
|
268
|
+
allowed: readonly string[],
|
|
269
|
+
): void {
|
|
270
|
+
const foreign = Object.keys(args.flags)
|
|
271
|
+
.filter((name) => !allowed.includes(name))
|
|
272
|
+
.sort();
|
|
273
|
+
if (foreign.length === 0) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
throw new UsageError(
|
|
277
|
+
`"extensions ${subcommand}" does not accept ${foreign.map((name) => `--${name}`).join(", ")}.`,
|
|
278
|
+
`Accepted here: ${allowed.map((name) => `--${name}`).join(", ")}.`,
|
|
279
|
+
);
|
|
280
|
+
}
|