@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,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `untangle init` as the CLI shell sees it.
|
|
3
|
+
*
|
|
4
|
+
* This is the ONLY file of the command that knows about argv, exit codes and
|
|
5
|
+
* a terminal. Everything else (`run.ts` and below) is a library over ports,
|
|
6
|
+
* which is why the whole detection pipeline is testable without a process,
|
|
7
|
+
* without a network and without `node:fs`.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
|
|
12
|
+
import { boolFlag, enumFlag, stringFlag, type FlagSpecs, type ParsedArgs } from "../../cli/args.js";
|
|
13
|
+
import type { Command, CommandContext } from "../../cli/command.js";
|
|
14
|
+
import { EXIT, UsageError } from "../../cli/exit.js";
|
|
15
|
+
import { line, note, processIo } from "../../cli/io.js";
|
|
16
|
+
|
|
17
|
+
import { formatTextReport } from "./report.js";
|
|
18
|
+
import { CONFIG_FILE_NAME, runInit, type InitDepsV1, type InitOptionsV1 } from "./run.js";
|
|
19
|
+
import { createWizardTerminal } from "./wizard-terminal.js";
|
|
20
|
+
import { runInitWizard, type InitWizardDepsV1 } from "./wizard.js";
|
|
21
|
+
|
|
22
|
+
const FLAGS: FlagSpecs = {
|
|
23
|
+
interactive: {
|
|
24
|
+
kind: "boolean",
|
|
25
|
+
describe: "Guided terminal setup. --no-interactive keeps the scriptable config-only workflow.",
|
|
26
|
+
defaultLabel: "automatic only on an interactive terminal, text output and online mode",
|
|
27
|
+
},
|
|
28
|
+
root: {
|
|
29
|
+
kind: "string",
|
|
30
|
+
placeholder: "PATH",
|
|
31
|
+
describe: `Project directory where ${CONFIG_FILE_NAME} is written.`,
|
|
32
|
+
defaultLabel: "current directory",
|
|
33
|
+
},
|
|
34
|
+
force: {
|
|
35
|
+
kind: "boolean",
|
|
36
|
+
describe: `Overwrite an existing ${CONFIG_FILE_NAME}.`,
|
|
37
|
+
},
|
|
38
|
+
"dry-run": {
|
|
39
|
+
kind: "boolean",
|
|
40
|
+
describe: "Preview what would be created. Writes nothing.",
|
|
41
|
+
},
|
|
42
|
+
offline: {
|
|
43
|
+
kind: "boolean",
|
|
44
|
+
describe: "No network probes; local LanceDB setup remains available.",
|
|
45
|
+
},
|
|
46
|
+
storage: {
|
|
47
|
+
kind: "string",
|
|
48
|
+
placeholder: "lancedb|qdrant",
|
|
49
|
+
describe:
|
|
50
|
+
"Search storage backend. LanceDB keeps the index in the project without a service; Qdrant is an explicit opt-in.",
|
|
51
|
+
defaultLabel: "lancedb for new projects; existing explicit backend is preserved",
|
|
52
|
+
},
|
|
53
|
+
"embedding-model": {
|
|
54
|
+
kind: "string",
|
|
55
|
+
placeholder: "NAME",
|
|
56
|
+
describe: "Select a specific embedding model instead of automatic discovery.",
|
|
57
|
+
defaultLabel: "largest context window",
|
|
58
|
+
},
|
|
59
|
+
vision: {
|
|
60
|
+
kind: "string",
|
|
61
|
+
placeholder: "PATH",
|
|
62
|
+
describe: "Vision for local document inspection; path relative to the project directory.",
|
|
63
|
+
},
|
|
64
|
+
spec: {
|
|
65
|
+
kind: "string",
|
|
66
|
+
placeholder: "PATH",
|
|
67
|
+
describe:
|
|
68
|
+
"Specification for local document inspection; path relative to the project directory.",
|
|
69
|
+
},
|
|
70
|
+
"feature-map": {
|
|
71
|
+
kind: "string",
|
|
72
|
+
placeholder: "PATH",
|
|
73
|
+
describe:
|
|
74
|
+
"Declared feature map for local evidence inspection; relative to the project directory.",
|
|
75
|
+
defaultLabel: "untangle.features.json",
|
|
76
|
+
},
|
|
77
|
+
format: {
|
|
78
|
+
kind: "string",
|
|
79
|
+
placeholder: "text|json",
|
|
80
|
+
describe: "Output format. `json` contains all findings, including the skip ledger.",
|
|
81
|
+
defaultLabel: "text",
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/** argv → options. Rejects the ambiguous call rather than picking a winner. */
|
|
86
|
+
export function initOptionsFrom(args: ParsedArgs, cwd: string): InitOptionsV1 {
|
|
87
|
+
if (args.positionals.length > 1) {
|
|
88
|
+
throw new UsageError(
|
|
89
|
+
`init accepts at most one path; received ${String(args.positionals.length)}.`,
|
|
90
|
+
"untangle init [PATH]",
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
const positional = args.positionals[0];
|
|
94
|
+
const flagRoot = stringFlag(args, "root");
|
|
95
|
+
if (positional !== undefined && flagRoot !== undefined) {
|
|
96
|
+
throw new UsageError(
|
|
97
|
+
"Specify the path as either an argument or --root, not both.",
|
|
98
|
+
"untangle init /path/to/project",
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
const preferredModel = stringFlag(args, "embedding-model");
|
|
102
|
+
const visionPath = stringFlag(args, "vision");
|
|
103
|
+
const specPath = stringFlag(args, "spec");
|
|
104
|
+
const featureManifestPath = stringFlag(args, "feature-map");
|
|
105
|
+
const storageBackend =
|
|
106
|
+
args.flags["storage"] === undefined
|
|
107
|
+
? undefined
|
|
108
|
+
: enumFlag(args, "storage", ["lancedb", "qdrant"] as const, "lancedb");
|
|
109
|
+
return {
|
|
110
|
+
root: path.resolve(cwd, flagRoot ?? positional ?? "."),
|
|
111
|
+
force: boolFlag(args, "force"),
|
|
112
|
+
dryRun: boolFlag(args, "dry-run"),
|
|
113
|
+
offline: boolFlag(args, "offline"),
|
|
114
|
+
...(storageBackend === undefined ? {} : { storageBackend }),
|
|
115
|
+
...(preferredModel === undefined ? {} : { preferredModel }),
|
|
116
|
+
...(visionPath === undefined ? {} : { visionPath }),
|
|
117
|
+
...(specPath === undefined ? {} : { specPath }),
|
|
118
|
+
...(featureManifestPath === undefined ? {} : { featureManifestPath }),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Builds the command. `deps` exists so a test can hand in an in-memory file
|
|
124
|
+
* system and a probe that answers nothing; production calls it with none.
|
|
125
|
+
*/
|
|
126
|
+
export interface InitCommandDepsV1 extends InitDepsV1 {
|
|
127
|
+
wizard?: Partial<InitWizardDepsV1>;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function createInitCommand(deps: InitCommandDepsV1 = {}): Command {
|
|
131
|
+
return {
|
|
132
|
+
spec: {
|
|
133
|
+
name: "init",
|
|
134
|
+
implementedBy: "commands/init/index.js",
|
|
135
|
+
summary: "Discover a project and write a commented untangle.toml",
|
|
136
|
+
usage:
|
|
137
|
+
"untangle init [PATH] [--interactive|--no-interactive] [--storage=lancedb|qdrant] [--vision=PATH] [--spec=PATH] [--feature-map=PATH] [--force] [--dry-run] [--offline]",
|
|
138
|
+
details: [
|
|
139
|
+
"On a terminal, guided setup previews configuration, optional local search/analyzer installation and a local feature/code map. No file, download or service is changed before the final selection. Preparing recipes and executing the displayed setup are separate choices. Prompts stay on stderr. Escape and Ctrl-C cancel; raw terminal mode is restored before external tools run.",
|
|
140
|
+
"Pipes, agents, --format=json, --dry-run, --offline and --no-interactive retain config-only behavior. Explicit --interactive requires a terminal and cannot be combined with JSON or dry-run. Explicit offline interactive setup may prepare local files but cannot download or start tools.",
|
|
141
|
+
`Discovers project languages weighted by lines, identifying parsed and search-only languages; monorepo topology across workspace packages and container services; an available embedding provider with its reported model, vector width and context window; an available vector store; and .gitignore rules plus defaults.`,
|
|
142
|
+
`Writes a ${CONFIG_FILE_NAME} with comments explaining each value's evidence. Omitted values come from product defaults; the file includes only decisions made by init.`,
|
|
143
|
+
"New projects use embedded LanceDB at .untangle/index/lancedb. No Docker or Qdrant probe is needed. Select --storage=qdrant for an owned or explicitly configured server. Missing Ollama is not an error; local offline indexing remains available.",
|
|
144
|
+
"Vision and specification are inspected locally through filenames, readability, hashes and document references. --vision and --spec select sources relative to the project directory. The review draft confirms neither features nor ownership and does not claim semantic conformance.",
|
|
145
|
+
"A supplied --feature-map, or untangle.features.json when present, makes declared features, code/test evidence, ownership declarations and feature complexity visible. No tests are executed and semantic conformance is not independently proven. Noninteractive init writes no visual map; confirmed guided setup may save a separate HTML/JSON snapshot. No ownership or implementation is confirmed automatically.",
|
|
146
|
+
"Spec-driven setup can inspect detected local Spec Kit or OpenSpec artifacts when no explicit feature manifest was chosen. Only final confirmation saves a source-bound proposed manifest under .untangle/sdd/ and uses it for this setup's feature report/map. Existing declarations are preserved. No framework commands or tests run; imported features remain planned/proposed without invented owners. The same connector is available through `untangle product connect [auto|spec-kit|openspec]`.",
|
|
147
|
+
"Discovery reads service information with GET and probes /api/embed with a small POST. Noninteractive init does not start or modify foreign services. A foreign vector store's usual default port is deliberately not probed (spec.md §3.2); set UNTANGLE_QDRANT_URL to select it explicitly. Only a confirmed interactive tool selection can install/start prepared owned services.",
|
|
148
|
+
"A second identical run changes nothing. If an existing file differs, init displays line-by-line differences and preserves it unless --force is explicit.",
|
|
149
|
+
],
|
|
150
|
+
flags: FLAGS,
|
|
151
|
+
examples: [
|
|
152
|
+
"untangle init",
|
|
153
|
+
"untangle init --interactive",
|
|
154
|
+
"untangle init --no-interactive --offline",
|
|
155
|
+
"untangle init /path/to/another/project --dry-run",
|
|
156
|
+
"untangle init --offline --force",
|
|
157
|
+
"untangle init --format=json",
|
|
158
|
+
"untangle init /path/to/project --vision=docs/vision.md --spec=docs/requirements.md",
|
|
159
|
+
],
|
|
160
|
+
exitCodes: [
|
|
161
|
+
[EXIT.ok, `${CONFIG_FILE_NAME} written or already current.`],
|
|
162
|
+
[
|
|
163
|
+
EXIT.operational,
|
|
164
|
+
"An existing file differs and was preserved (use --force), or the generated configuration would be invalid.",
|
|
165
|
+
],
|
|
166
|
+
[EXIT.usage, "Invalid arguments."],
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
async run(ctx: CommandContext, args: ParsedArgs): Promise<number> {
|
|
171
|
+
const format = enumFlag(args, "format", ["text", "json"] as const, "text");
|
|
172
|
+
const options = initOptionsFrom(args, ctx.cwd);
|
|
173
|
+
const explicit = args.flags["interactive"];
|
|
174
|
+
if (explicit === true && (format === "json" || options.dryRun))
|
|
175
|
+
throw new UsageError(
|
|
176
|
+
"--interactive cannot be combined with --format=json or --dry-run.",
|
|
177
|
+
"Use --no-interactive for a machine-readable or write-free preview.",
|
|
178
|
+
);
|
|
179
|
+
const automatic =
|
|
180
|
+
explicit === undefined &&
|
|
181
|
+
ctx.io === processIo &&
|
|
182
|
+
process.stdin.isTTY === true &&
|
|
183
|
+
process.stderr.isTTY === true &&
|
|
184
|
+
!ctx.env["CI"] &&
|
|
185
|
+
format === "text" &&
|
|
186
|
+
!options.dryRun &&
|
|
187
|
+
!options.offline;
|
|
188
|
+
const { wizard, ...ports } = deps;
|
|
189
|
+
const initDeps = {
|
|
190
|
+
env: ctx.env,
|
|
191
|
+
signal: ctx.signal,
|
|
192
|
+
...ports,
|
|
193
|
+
};
|
|
194
|
+
let result;
|
|
195
|
+
if (explicit === true || automatic) {
|
|
196
|
+
if (
|
|
197
|
+
wizard?.terminal === undefined &&
|
|
198
|
+
(process.stdin.isTTY !== true || process.stderr.isTTY !== true)
|
|
199
|
+
)
|
|
200
|
+
throw new UsageError(
|
|
201
|
+
"--interactive requires a terminal on stdin and stderr.",
|
|
202
|
+
"Use `untangle init --no-interactive` in a pipe or coding agent.",
|
|
203
|
+
);
|
|
204
|
+
const terminal =
|
|
205
|
+
wizard?.terminal ??
|
|
206
|
+
createWizardTerminal({ write: (text) => ctx.io.err(text), signal: ctx.signal });
|
|
207
|
+
if (
|
|
208
|
+
!terminal.interactive ||
|
|
209
|
+
(wizard?.terminal === undefined && process.stderr.isTTY !== true)
|
|
210
|
+
)
|
|
211
|
+
throw new UsageError(
|
|
212
|
+
"--interactive requires a terminal on stdin and stderr.",
|
|
213
|
+
"Use `untangle init --no-interactive` in a pipe or coding agent.",
|
|
214
|
+
);
|
|
215
|
+
const completed = await runInitWizard(ctx, options, initDeps, { ...wizard, terminal });
|
|
216
|
+
if (completed.result === null) return completed.exitCode;
|
|
217
|
+
result = completed.result;
|
|
218
|
+
if (completed.exitCode !== result.exitCode) return completed.exitCode;
|
|
219
|
+
} else result = await runInit(options, initDeps);
|
|
220
|
+
|
|
221
|
+
if (format === "json") {
|
|
222
|
+
line(ctx.io, JSON.stringify(result, null, 2));
|
|
223
|
+
return result.exitCode;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// The path goes to stdout — it is the payload of this command, the one
|
|
227
|
+
// thing a script would pipe. Everything else is diagnosis (cli/io.ts).
|
|
228
|
+
line(ctx.io, result.configPath);
|
|
229
|
+
for (const reportLine of formatTextReport(result)) {
|
|
230
|
+
note(ctx.io, reportLine);
|
|
231
|
+
}
|
|
232
|
+
return result.exitCode;
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** The command with production ports. */
|
|
238
|
+
export const initCommand: Command = createInitCommand();
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turning findings into a configuration.
|
|
3
|
+
*
|
|
4
|
+
* The shape written to disk is `UntangleConfigV1` from
|
|
5
|
+
* `@untangle-code/config` — not a private CLI dialect — and it is checked with
|
|
6
|
+
* that package's own validator before a byte reaches the file system. A first
|
|
7
|
+
* command that writes a configuration the rest of the product then rejects is
|
|
8
|
+
* a first command that has failed.
|
|
9
|
+
*
|
|
10
|
+
* WHICH SECTIONS GET WRITTEN: only the ones `init` actually DECIDED something
|
|
11
|
+
* about. Everything else is left to the product defaults, because a file that
|
|
12
|
+
* restates two hundred defaults verbatim tells the reader nothing about what
|
|
13
|
+
* was chosen. `defaultsFor` records the values that stay defaulted so the
|
|
14
|
+
* renderer can name them in prose instead.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
DEFAULT_EMBEDDING_CONFIG,
|
|
19
|
+
DEFAULT_INDEX_CONFIG,
|
|
20
|
+
PRODUCT_DEFAULT_CONFIG,
|
|
21
|
+
mergeConfigLayers,
|
|
22
|
+
validateEffectiveConfig,
|
|
23
|
+
} from "@untangle-code/config";
|
|
24
|
+
import type { RawConfigLayer } from "@untangle-code/config";
|
|
25
|
+
import { sha256Hex, sortByCodepoints } from "@untangle-code/domain";
|
|
26
|
+
|
|
27
|
+
import type { ProjectFindingsV1 } from "./types.js";
|
|
28
|
+
|
|
29
|
+
/** The sub-sections `init` fills in, without the `| undefined` of the optional slot. */
|
|
30
|
+
type QdrantSection = NonNullable<RawConfigLayer["qdrant"]>;
|
|
31
|
+
type EmbeddingSection = NonNullable<RawConfigLayer["embeddings"]>;
|
|
32
|
+
|
|
33
|
+
export interface ConfigDraftV1 {
|
|
34
|
+
/** Exactly what `init` decided — the layer that ends up in the file. */
|
|
35
|
+
layer: RawConfigLayer;
|
|
36
|
+
/** Validator warnings over the layer merged onto the product defaults. */
|
|
37
|
+
warnings: string[];
|
|
38
|
+
/** Validator errors. Non-empty means the file is NOT written. */
|
|
39
|
+
errors: string[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Derives a project id from a directory name.
|
|
44
|
+
*
|
|
45
|
+
* Lowercase, non-alphanumerics collapsed to `-`, trimmed. A name that reduces
|
|
46
|
+
* to nothing (a directory called `...`) falls back to `project`, because an
|
|
47
|
+
* empty id would fail validation and an id derived from something random
|
|
48
|
+
* would not be reproducible.
|
|
49
|
+
*/
|
|
50
|
+
export function deriveProjectId(directoryName: string): string {
|
|
51
|
+
const slug = directoryName
|
|
52
|
+
.toLowerCase()
|
|
53
|
+
.replace(/[^a-z0-9]+/gu, "-")
|
|
54
|
+
.replace(/^-+|-+$/gu, "");
|
|
55
|
+
return slug.length === 0 ? "project" : slug;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function buildConfigDraft(findings: ProjectFindingsV1): ConfigDraftV1 {
|
|
59
|
+
const contextArtifacts = productContextArtifacts(findings);
|
|
60
|
+
const layer: RawConfigLayer = {
|
|
61
|
+
schemaVersion: 1,
|
|
62
|
+
projectId: findings.projectId,
|
|
63
|
+
repositories: [
|
|
64
|
+
{
|
|
65
|
+
id: findings.projectId,
|
|
66
|
+
// Relative to this configuration file — spec.md §4.3 allows exactly
|
|
67
|
+
// that, and a relative path keeps the file portable between checkouts.
|
|
68
|
+
path: ".",
|
|
69
|
+
label: findings.projectId,
|
|
70
|
+
exclude: sortByCodepoints([
|
|
71
|
+
...findings.ignore.defaultExcludes,
|
|
72
|
+
...findings.ignore.additionalExcludes,
|
|
73
|
+
]),
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
...(findings.storage?.backend === "lancedb"
|
|
77
|
+
? {
|
|
78
|
+
storage: {
|
|
79
|
+
backend: "lancedb" as const,
|
|
80
|
+
...(findings.storage.path === undefined ? {} : { path: findings.storage.path }),
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
: { storage: { backend: "qdrant" as const }, qdrant: buildQdrantSection(findings) }),
|
|
84
|
+
embeddings: buildEmbeddingSection(findings),
|
|
85
|
+
index: {
|
|
86
|
+
// The only index knob `init` moves: a project whose sources are wider
|
|
87
|
+
// than the default ceiling would otherwise lose them silently.
|
|
88
|
+
maxFileSizeMb: DEFAULT_INDEX_CONFIG.maxFileSizeMb,
|
|
89
|
+
watch: DEFAULT_INDEX_CONFIG.watch,
|
|
90
|
+
},
|
|
91
|
+
graph: {
|
|
92
|
+
// Both levels of the topology feed the graph; a single-package project
|
|
93
|
+
// gets the same setting, it simply has less to draw.
|
|
94
|
+
enabled: true,
|
|
95
|
+
},
|
|
96
|
+
telemetry: { enabled: false },
|
|
97
|
+
...(contextArtifacts.length === 0 ? {} : { contextArtifacts }),
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const merged = mergeConfigLayers<Record<string, unknown>>([PRODUCT_DEFAULT_CONFIG, layer]);
|
|
101
|
+
const validation = validateEffectiveConfig(merged);
|
|
102
|
+
return {
|
|
103
|
+
layer,
|
|
104
|
+
warnings: [
|
|
105
|
+
...validation.warnings.map((issue) => `${issue.path}: ${issue.message}`),
|
|
106
|
+
...(findings.storage?.configurationWarnings ?? []),
|
|
107
|
+
...(findings.storage?.directoryStatus === "not-directory" ||
|
|
108
|
+
findings.storage?.directoryStatus === "unreadable"
|
|
109
|
+
? [
|
|
110
|
+
`Local storage ${findings.storage.directory}: ${findings.storage.directoryStatus}${findings.storage.detail === undefined ? "" : ` (${findings.storage.detail})`}. Indexing cannot use this path.`,
|
|
111
|
+
]
|
|
112
|
+
: []),
|
|
113
|
+
],
|
|
114
|
+
errors: validation.errors.map((issue) => `${issue.path}: ${issue.message} [${issue.code}]`),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function productContextArtifacts(
|
|
119
|
+
findings: ProjectFindingsV1,
|
|
120
|
+
): NonNullable<RawConfigLayer["contextArtifacts"]> {
|
|
121
|
+
const descriptions = {
|
|
122
|
+
vision: "Provisional vision",
|
|
123
|
+
specification: "Provisional specification",
|
|
124
|
+
product: "Provisional product description",
|
|
125
|
+
};
|
|
126
|
+
return (findings.productContext?.sources ?? [])
|
|
127
|
+
.filter((source) => source.selected && source.status === "readable")
|
|
128
|
+
.map((source) => ({
|
|
129
|
+
name: `product-${source.role}-${sha256Hex(source.path).slice(0, 12)}`,
|
|
130
|
+
path: `./${source.path}`,
|
|
131
|
+
description: `${descriptions[source.role]}; local document inspection, features and ownership remain unconfirmed.`,
|
|
132
|
+
type: "markdown",
|
|
133
|
+
}));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Qdrant: `external` only when an endpoint actually answered. Otherwise
|
|
138
|
+
* `managed` with no URL — the mode that says "start your own instance", which
|
|
139
|
+
* is the correct answer both when nothing is running and when the only thing
|
|
140
|
+
* running is somebody else's (spec.md §3.2).
|
|
141
|
+
*/
|
|
142
|
+
function buildQdrantSection(findings: ProjectFindingsV1): QdrantSection {
|
|
143
|
+
if (findings.storage?.qdrantMode !== undefined) {
|
|
144
|
+
return {
|
|
145
|
+
mode: findings.storage.qdrantMode,
|
|
146
|
+
...(findings.storage.qdrantUrl === undefined ? {} : { url: findings.storage.qdrantUrl }),
|
|
147
|
+
collectionPrefix: collectionPrefixFor(findings),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
if (findings.qdrant.outcome === "reachable" && findings.qdrant.url !== undefined) {
|
|
151
|
+
return {
|
|
152
|
+
mode: "external",
|
|
153
|
+
url: findings.qdrant.url,
|
|
154
|
+
collectionPrefix: collectionPrefixFor(findings),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
return { mode: "managed", collectionPrefix: collectionPrefixFor(findings) };
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** `untangle_<projectId>_` — keeps two projects on one instance from colliding. */
|
|
161
|
+
export function collectionPrefixFor(findings: ProjectFindingsV1): string {
|
|
162
|
+
return `untangle_${findings.projectId.replace(/-/gu, "_")}_`;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Embeddings: when a provider answered, the model AND its vector width and
|
|
167
|
+
* context window are taken from what the provider reported about itself. When
|
|
168
|
+
* none answered, the product default profile stands and `mode` stays `auto`,
|
|
169
|
+
* so the next run can still discover a provider without the user editing
|
|
170
|
+
* anything.
|
|
171
|
+
*/
|
|
172
|
+
function buildEmbeddingSection(findings: ProjectFindingsV1): EmbeddingSection {
|
|
173
|
+
const chosen = findings.ollama.chosenModel;
|
|
174
|
+
if (findings.ollama.outcome !== "reachable" || chosen === undefined) {
|
|
175
|
+
return {
|
|
176
|
+
provider: "ollama",
|
|
177
|
+
mode: "auto",
|
|
178
|
+
model: DEFAULT_EMBEDDING_CONFIG.model,
|
|
179
|
+
dimensions: DEFAULT_EMBEDDING_CONFIG.dimensions,
|
|
180
|
+
contextLength: DEFAULT_EMBEDDING_CONFIG.contextLength,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
provider: "ollama",
|
|
185
|
+
mode: "external",
|
|
186
|
+
url: findings.ollama.url,
|
|
187
|
+
model: chosen.name,
|
|
188
|
+
dimensions: chosen.dimensions ?? DEFAULT_EMBEDDING_CONFIG.dimensions,
|
|
189
|
+
contextLength: chosen.contextLength ?? DEFAULT_EMBEDDING_CONFIG.contextLength,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* The single next step.
|
|
195
|
+
*
|
|
196
|
+
* EXACTLY ONE, in a fixed priority order, because a first command that ends
|
|
197
|
+
* in a list of five things is a first command the user closes. The order is
|
|
198
|
+
* "what blocks the next command first": no embedding provider blocks
|
|
199
|
+
* indexing; no model blocks it too; no vector store blocks it; otherwise
|
|
200
|
+
* nothing blocks it and the step is to index.
|
|
201
|
+
*/
|
|
202
|
+
export function nextStepFor(findings: ProjectFindingsV1): string {
|
|
203
|
+
if (findings.storage?.backend === "lancedb") {
|
|
204
|
+
if (
|
|
205
|
+
findings.storage.directoryStatus === "not-directory" ||
|
|
206
|
+
findings.storage.directoryStatus === "unreadable"
|
|
207
|
+
)
|
|
208
|
+
return `Local storage path ${JSON.stringify(findings.storage.directory)} is ${findings.storage.directoryStatus}. Next step: choose an accessible directory with UNTANGLE_LANCEDB_PATH and rerun \`untangle init\`.`;
|
|
209
|
+
if (findings.ollama.outcome !== "reachable" || findings.ollama.chosenModel === undefined)
|
|
210
|
+
return "Local LanceDB storage needs no service. Next step: `untangle index --embedder=offline` (local vectors without semantic embeddings).";
|
|
211
|
+
}
|
|
212
|
+
if (findings.ollama.outcome !== "reachable") {
|
|
213
|
+
return `No embedding provider at ${findings.ollama.url}. Next step: start \`ollama serve\` and rerun \`untangle init\`.`;
|
|
214
|
+
}
|
|
215
|
+
if (findings.ollama.chosenModel === undefined) {
|
|
216
|
+
return `${findings.ollama.url} is running but reports no embedding model. Next step: \`ollama pull ${DEFAULT_EMBEDDING_CONFIG.model}\`.`;
|
|
217
|
+
}
|
|
218
|
+
if (findings.storage?.backend !== "lancedb" && findings.qdrant.outcome !== "reachable") {
|
|
219
|
+
if (findings.storage?.qdrantMode === "external")
|
|
220
|
+
return `The selected Qdrant server ${JSON.stringify(findings.storage.qdrantUrl)} is unreachable. Next step: check that server's URL and availability, then rerun \`untangle doctor\`.`;
|
|
221
|
+
return "No vector store is reachable. Next step: start an owned instance with `docker run -d --name untangle-qdrant -p 16333:6333 -v untangle-qdrant-data:/qdrant/storage qdrant/qdrant`, then run `untangle index`.";
|
|
222
|
+
}
|
|
223
|
+
// WP-228: Der Anbieter laeuft, das Modell ist da, der Speicher steht — und
|
|
224
|
+
// trotzdem kann nicht indiziert werden, weil der Endpunkt, den der
|
|
225
|
+
// Indexlauf benutzt, nicht antwortet. Das ist ein eigener Fall und
|
|
226
|
+
// verdient einen eigenen naechsten Schritt; „alles vorhanden" waere hier
|
|
227
|
+
// schlicht falsch.
|
|
228
|
+
if (findings.ollama.embedProbe.outcome === "timeout") {
|
|
229
|
+
return `${findings.ollama.url} responds on /api/tags, but /api/embed did not respond within ${String(findings.ollama.embedProbe.timeoutMs)} ms, so embeddings are unavailable. Next step: \`untangle index --embedder=offline\` (local vectors without semantics).`;
|
|
230
|
+
}
|
|
231
|
+
if (findings.ollama.embedProbe.outcome === "failed") {
|
|
232
|
+
return `${findings.ollama.url} is running, but /api/embed failed (${findings.ollama.embedProbe.detail ?? "no details"}). Next step: \`untangle index --embedder=offline\` (local vectors without semantics).`;
|
|
233
|
+
}
|
|
234
|
+
return "Everything is available. Next step: `untangle index`.";
|
|
235
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idempotency: what a second run would change.
|
|
3
|
+
*
|
|
4
|
+
* `init` compares the RENDERED text against the file on disk rather than
|
|
5
|
+
* parsing the file back into a config object. That is a deliberate choice and
|
|
6
|
+
* it buys three things at once:
|
|
7
|
+
*
|
|
8
|
+
* - it needs no TOML parser, so there is no second grammar to keep in step
|
|
9
|
+
* with the writer;
|
|
10
|
+
* - it notices changes the user made BY HAND, including in the comments,
|
|
11
|
+
* which a value-level comparison would call "identical";
|
|
12
|
+
* - it is only meaningful because `renderUntangleToml` is pure and carries no
|
|
13
|
+
* clock — otherwise every run would differ and the check would be theatre.
|
|
14
|
+
*
|
|
15
|
+
* The comparison is a line diff, so the report says which lines would be
|
|
16
|
+
* added and which lost, not merely "the file differs".
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import type { ConfigChangeV1 } from "./types.js";
|
|
20
|
+
|
|
21
|
+
/** Above this line count the diff degrades to a set comparison (see `diffLines`). */
|
|
22
|
+
const LCS_LINE_BUDGET = 2_000;
|
|
23
|
+
|
|
24
|
+
/** Splits into lines, dropping the single trailing empty element of a final newline. */
|
|
25
|
+
export function toLines(text: string): string[] {
|
|
26
|
+
const lines = text.split("\n");
|
|
27
|
+
if (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
28
|
+
lines.pop();
|
|
29
|
+
}
|
|
30
|
+
return lines;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Line diff, longest-common-subsequence based.
|
|
35
|
+
*
|
|
36
|
+
* The dynamic-programming table is O(n·m); both sides are a configuration
|
|
37
|
+
* file, so that is a few hundred by a few hundred. Above `LCS_LINE_BUDGET`
|
|
38
|
+
* the function falls back to a multiset comparison — less precise about
|
|
39
|
+
* ORDER, but still exact about which lines appear on only one side, and it
|
|
40
|
+
* cannot be made to allocate gigabytes by a pathological input.
|
|
41
|
+
*/
|
|
42
|
+
export function diffLines(before: readonly string[], after: readonly string[]): ConfigChangeV1[] {
|
|
43
|
+
if (before.length > LCS_LINE_BUDGET || after.length > LCS_LINE_BUDGET) {
|
|
44
|
+
return multisetDiff(before, after);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const rows = before.length;
|
|
48
|
+
const columns = after.length;
|
|
49
|
+
// table[i][j] = length of the LCS of before[i…] and after[j…]
|
|
50
|
+
const table: number[][] = Array.from({ length: rows + 1 }, () =>
|
|
51
|
+
new Array<number>(columns + 1).fill(0),
|
|
52
|
+
);
|
|
53
|
+
for (let i = rows - 1; i >= 0; i -= 1) {
|
|
54
|
+
const row = table[i] as number[];
|
|
55
|
+
const nextRow = table[i + 1] as number[];
|
|
56
|
+
for (let j = columns - 1; j >= 0; j -= 1) {
|
|
57
|
+
row[j] =
|
|
58
|
+
before[i] === after[j]
|
|
59
|
+
? (nextRow[j + 1] as number) + 1
|
|
60
|
+
: Math.max(nextRow[j] as number, row[j + 1] as number);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const changes: ConfigChangeV1[] = [];
|
|
65
|
+
let i = 0;
|
|
66
|
+
let j = 0;
|
|
67
|
+
while (i < rows && j < columns) {
|
|
68
|
+
if (before[i] === after[j]) {
|
|
69
|
+
i += 1;
|
|
70
|
+
j += 1;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const row = table[i] as number[];
|
|
74
|
+
const nextRow = table[i + 1] as number[];
|
|
75
|
+
if ((nextRow[j] as number) >= (row[j + 1] as number)) {
|
|
76
|
+
changes.push({ kind: "removed", line: (before[i] as string).trimEnd() });
|
|
77
|
+
i += 1;
|
|
78
|
+
} else {
|
|
79
|
+
changes.push({ kind: "added", line: (after[j] as string).trimEnd() });
|
|
80
|
+
j += 1;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (; i < rows; i += 1) {
|
|
84
|
+
changes.push({ kind: "removed", line: (before[i] as string).trimEnd() });
|
|
85
|
+
}
|
|
86
|
+
for (; j < columns; j += 1) {
|
|
87
|
+
changes.push({ kind: "added", line: (after[j] as string).trimEnd() });
|
|
88
|
+
}
|
|
89
|
+
return changes;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function multisetDiff(before: readonly string[], after: readonly string[]): ConfigChangeV1[] {
|
|
93
|
+
const counts = new Map<string, number>();
|
|
94
|
+
for (const line of before) {
|
|
95
|
+
counts.set(line, (counts.get(line) ?? 0) + 1);
|
|
96
|
+
}
|
|
97
|
+
const changes: ConfigChangeV1[] = [];
|
|
98
|
+
for (const line of after) {
|
|
99
|
+
const remaining = counts.get(line) ?? 0;
|
|
100
|
+
if (remaining > 0) {
|
|
101
|
+
counts.set(line, remaining - 1);
|
|
102
|
+
} else {
|
|
103
|
+
changes.push({ kind: "added", line: line.trimEnd() });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
for (const [line, remaining] of counts) {
|
|
107
|
+
for (let index = 0; index < remaining; index += 1) {
|
|
108
|
+
changes.push({ kind: "removed", line: line.trimEnd() });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return changes;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** True when the file on disk already IS what `init` would write. */
|
|
115
|
+
export function isUnchanged(existing: string, rendered: string): boolean {
|
|
116
|
+
return existing === rendered;
|
|
117
|
+
}
|