@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,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Probing the two pieces of infrastructure Untangle needs.
|
|
3
|
+
*
|
|
4
|
+
* READ-ONLY, ON PURPOSE. `HttpProbePort` can issue a GET and nothing else, so
|
|
5
|
+
* `init` is structurally incapable of changing a service it finds — which is
|
|
6
|
+
* what spec.md §3.2 demands of External Infrastructure mode ("Untangle DARF in
|
|
7
|
+
* diesem Modus keine fremden Prozesse oder Container verändern").
|
|
8
|
+
*
|
|
9
|
+
* WHICH URLS ARE PROBED AT ALL IS NOT DECIDED HERE ANY MORE (WP-222). That
|
|
10
|
+
* rule lives in `cli/vector-store-policy.ts` and is the SAME rule
|
|
11
|
+
* `untangle doctor` obeys. It used to be written out twice — once here, once
|
|
12
|
+
* (by omission) in `doctor` — and the two disagreed: `init` refused upstream's
|
|
13
|
+
* default port 6333 citing spec.md §3.2, while `doctor` fell back onto it,
|
|
14
|
+
* found the foreign instance living there and reported it as healthy. Two
|
|
15
|
+
* commands of one tool, two answers to a safety question. One rule, one
|
|
16
|
+
* file, one answer.
|
|
17
|
+
*
|
|
18
|
+
* NOT FINDING EITHER SERVICE IS NOT AN ERROR (WP-125): the configuration is
|
|
19
|
+
* written regardless, and the command names exactly one next step.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { compareCodepoints } from "@untangle-code/domain";
|
|
23
|
+
|
|
24
|
+
import { MANAGED_QDRANT_URL, qdrantProbePlan } from "../../cli/vector-store-policy.js";
|
|
25
|
+
|
|
26
|
+
import type {
|
|
27
|
+
EmbeddingModelInfoV1,
|
|
28
|
+
HttpProbePort,
|
|
29
|
+
InitLimitsV1,
|
|
30
|
+
OllamaFindingsV1,
|
|
31
|
+
QdrantFindingsV1,
|
|
32
|
+
} from "./types.js";
|
|
33
|
+
|
|
34
|
+
/** Native Ollama probe target (spec.md §3.1). */
|
|
35
|
+
export const DEFAULT_OLLAMA_URL = "http://127.0.0.1:11434";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Managed Qdrant REST port (spec.md §3.1) — re-exported, NOT redefined. The
|
|
39
|
+
* value belongs to the shared policy; a second copy here is exactly how the
|
|
40
|
+
* two commands drifted apart in the first place.
|
|
41
|
+
*/
|
|
42
|
+
export const DEFAULT_QDRANT_URL = MANAGED_QDRANT_URL;
|
|
43
|
+
|
|
44
|
+
interface OllamaModelDetails {
|
|
45
|
+
context_length?: unknown;
|
|
46
|
+
embedding_length?: unknown;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface OllamaModel {
|
|
50
|
+
name?: unknown;
|
|
51
|
+
capabilities?: unknown;
|
|
52
|
+
details?: OllamaModelDetails;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Reads `/api/tags` into the embedding models it describes.
|
|
57
|
+
*
|
|
58
|
+
* The provider reports `capabilities`, `embedding_length` and
|
|
59
|
+
* `context_length` per model, so the vector width is READ, never guessed and
|
|
60
|
+
* never obtained by sending the model something to embed. A model that
|
|
61
|
+
* predates the `capabilities` field is still recognised by the presence of an
|
|
62
|
+
* `embedding_length`, which only embedding models carry.
|
|
63
|
+
*/
|
|
64
|
+
export function readEmbeddingModels(payload: unknown): EmbeddingModelInfoV1[] {
|
|
65
|
+
if (typeof payload !== "object" || payload === null) {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
const models = (payload as { models?: unknown }).models;
|
|
69
|
+
if (!Array.isArray(models)) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
const found: EmbeddingModelInfoV1[] = [];
|
|
73
|
+
for (const raw of models as OllamaModel[]) {
|
|
74
|
+
if (typeof raw !== "object" || raw === null) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const name = typeof raw.name === "string" ? raw.name : undefined;
|
|
78
|
+
if (name === undefined || name.length === 0) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const capabilities = Array.isArray(raw.capabilities)
|
|
82
|
+
? raw.capabilities.filter((item): item is string => typeof item === "string")
|
|
83
|
+
: [];
|
|
84
|
+
const details = typeof raw.details === "object" && raw.details !== null ? raw.details : {};
|
|
85
|
+
const dimensions = positiveInteger(details.embedding_length);
|
|
86
|
+
const contextLength = positiveInteger(details.context_length);
|
|
87
|
+
const isEmbedding = capabilities.includes("embedding") || dimensions !== undefined;
|
|
88
|
+
if (!isEmbedding) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
found.push({
|
|
92
|
+
name,
|
|
93
|
+
...(dimensions === undefined ? {} : { dimensions }),
|
|
94
|
+
...(contextLength === undefined ? {} : { contextLength }),
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
found.sort((a, b) => compareCodepoints(a.name, b.name));
|
|
98
|
+
return found;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface ModelChoiceV1 {
|
|
102
|
+
model: EmbeddingModelInfoV1;
|
|
103
|
+
reason: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Chooses one embedding model out of what the provider actually has.
|
|
108
|
+
*
|
|
109
|
+
* The rule, in order: the widest context window first, because a code chunk
|
|
110
|
+
* that does not fit is a chunk that gets truncated; then the widest vector,
|
|
111
|
+
* because that is the model with more to say; then codepoint order, so the
|
|
112
|
+
* decision never depends on the order the provider happened to list its
|
|
113
|
+
* models in. `preferred` (an explicit user choice) short-circuits all of it.
|
|
114
|
+
*
|
|
115
|
+
* Deliberately NOT "whatever the product default is called": on a machine
|
|
116
|
+
* that has three embedding models and not the default one, silently falling
|
|
117
|
+
* back to a name that is not installed produces a configuration that fails on
|
|
118
|
+
* first use.
|
|
119
|
+
*/
|
|
120
|
+
export function chooseEmbeddingModel(
|
|
121
|
+
models: readonly EmbeddingModelInfoV1[],
|
|
122
|
+
preferred?: string,
|
|
123
|
+
): ModelChoiceV1 | undefined {
|
|
124
|
+
if (models.length === 0) {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
if (preferred !== undefined) {
|
|
128
|
+
const exact = models.find((model) => model.name === preferred);
|
|
129
|
+
if (exact !== undefined) {
|
|
130
|
+
return { model: exact, reason: "explicitly requested (--embedding-model)" };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const ranked = [...models].sort((a, b) => {
|
|
134
|
+
const contextDelta = (b.contextLength ?? 0) - (a.contextLength ?? 0);
|
|
135
|
+
if (contextDelta !== 0) {
|
|
136
|
+
return contextDelta;
|
|
137
|
+
}
|
|
138
|
+
const dimensionDelta = (b.dimensions ?? 0) - (a.dimensions ?? 0);
|
|
139
|
+
if (dimensionDelta !== 0) {
|
|
140
|
+
return dimensionDelta;
|
|
141
|
+
}
|
|
142
|
+
return compareCodepoints(a.name, b.name);
|
|
143
|
+
});
|
|
144
|
+
const model = ranked[0] as EmbeddingModelInfoV1;
|
|
145
|
+
return {
|
|
146
|
+
model,
|
|
147
|
+
reason:
|
|
148
|
+
models.length === 1
|
|
149
|
+
? "the provider's only reported embedding model"
|
|
150
|
+
: `largest context window among ${String(models.length)} reported embedding models`,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface ProbeInput {
|
|
155
|
+
http: HttpProbePort;
|
|
156
|
+
limits: InitLimitsV1;
|
|
157
|
+
/** `UNTANGLE_OLLAMA_URL` when set. */
|
|
158
|
+
ollamaUrl: string;
|
|
159
|
+
/** `UNTANGLE_QDRANT_URL` when set — probed BEFORE the managed default. */
|
|
160
|
+
qdrantUrls: readonly string[];
|
|
161
|
+
/** Model name from `--embedding-model`, when given. */
|
|
162
|
+
preferredModel?: string;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* WP-228: Erreichbarkeit heisst NICHT „benutzbar".
|
|
167
|
+
*
|
|
168
|
+
* Bis hierher fragte `init` nur `/api/version` und `/api/tags` — zwei
|
|
169
|
+
* Endpunkte, die der Indexlauf nie anfasst. Auf dem Rechner, an dem das
|
|
170
|
+
* gemessen wurde, antworteten beide sofort, waehrend `/api/embed` haengte:
|
|
171
|
+
* die geschriebene Konfiguration versprach einen Dienst, der keinen einzigen
|
|
172
|
+
* Chunk einbetten konnte. Deshalb wird jetzt der Endpunkt geprueft, den das
|
|
173
|
+
* Produkt WIRKLICH benutzt — mit kurzer Frist, und ein Fristablauf ist ein
|
|
174
|
+
* Befund, keine bestandene Pruefung.
|
|
175
|
+
*/
|
|
176
|
+
export async function probeOllama(input: ProbeInput): Promise<OllamaFindingsV1> {
|
|
177
|
+
const { http, limits, ollamaUrl } = input;
|
|
178
|
+
const notProbed = (detail: string): OllamaFindingsV1["embedProbe"] => ({
|
|
179
|
+
outcome: "not-probed",
|
|
180
|
+
timeoutMs: limits.embedProbeTimeoutMs,
|
|
181
|
+
detail,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const version = await http.getJson(`${trimSlash(ollamaUrl)}/api/version`, limits.probeTimeoutMs);
|
|
185
|
+
if (version === null) {
|
|
186
|
+
return {
|
|
187
|
+
outcome: "unreachable",
|
|
188
|
+
url: ollamaUrl,
|
|
189
|
+
embeddingModels: [],
|
|
190
|
+
embedProbe: notProbed("the provider was already unreachable"),
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
const versionString = readString(version, "version");
|
|
194
|
+
const tags = await http.getJson(`${trimSlash(ollamaUrl)}/api/tags`, limits.probeTimeoutMs);
|
|
195
|
+
const embeddingModels = readEmbeddingModels(tags);
|
|
196
|
+
const choice = chooseEmbeddingModel(embeddingModels, input.preferredModel);
|
|
197
|
+
|
|
198
|
+
const embedProbe =
|
|
199
|
+
choice === undefined
|
|
200
|
+
? notProbed("the provider reports no embedding model")
|
|
201
|
+
: await runEmbedProbe(http, ollamaUrl, choice.model.name, limits.embedProbeTimeoutMs);
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
outcome: "reachable",
|
|
205
|
+
url: ollamaUrl,
|
|
206
|
+
...(versionString === undefined ? {} : { version: versionString }),
|
|
207
|
+
embeddingModels,
|
|
208
|
+
...(choice === undefined ? {} : { chosenModel: choice.model, chosenReason: choice.reason }),
|
|
209
|
+
embedProbe,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/** Ein winziges Probe-Embedding, mit Frist. Wirft nie — es antwortet. */
|
|
214
|
+
async function runEmbedProbe(
|
|
215
|
+
http: HttpProbePort,
|
|
216
|
+
ollamaUrl: string,
|
|
217
|
+
model: string,
|
|
218
|
+
timeoutMs: number,
|
|
219
|
+
): Promise<OllamaFindingsV1["embedProbe"]> {
|
|
220
|
+
const result = await http.probeEmbedding(trimSlash(ollamaUrl), model, timeoutMs);
|
|
221
|
+
if (result.ok) {
|
|
222
|
+
return { outcome: "ok", timeoutMs, dimensions: result.dimensions };
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
outcome: result.timedOut ? "timeout" : "failed",
|
|
226
|
+
timeoutMs,
|
|
227
|
+
detail: result.detail,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export async function probeQdrant(input: ProbeInput): Promise<QdrantFindingsV1> {
|
|
232
|
+
const { http, limits, qdrantUrls } = input;
|
|
233
|
+
const probedUrls = [...qdrantUrls];
|
|
234
|
+
// The skipped list — with its reason — comes from the shared policy, so it
|
|
235
|
+
// can never claim something other than what the policy actually enforces.
|
|
236
|
+
const skippedUrls = qdrantProbePlan({}).skipped.filter(
|
|
237
|
+
(candidate) => !probedUrls.includes(candidate.url),
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
for (const url of probedUrls) {
|
|
241
|
+
const payload = await http.getJson(`${trimSlash(url)}/`, limits.probeTimeoutMs);
|
|
242
|
+
if (payload === null) {
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
const version = readString(payload, "version");
|
|
246
|
+
return {
|
|
247
|
+
outcome: "reachable",
|
|
248
|
+
probedUrls,
|
|
249
|
+
url,
|
|
250
|
+
...(version === undefined ? {} : { version }),
|
|
251
|
+
skippedUrls,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
return { outcome: "unreachable", probedUrls, skippedUrls };
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function trimSlash(value: string): string {
|
|
258
|
+
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function readString(payload: unknown, key: string): string | undefined {
|
|
262
|
+
if (typeof payload !== "object" || payload === null) {
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
const value = (payload as Record<string, unknown>)[key];
|
|
266
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function positiveInteger(value: unknown): number | undefined {
|
|
270
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : undefined;
|
|
271
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
DEFAULT_STORAGE_CONFIG,
|
|
5
|
+
buildEnvConfigLayer,
|
|
6
|
+
mergeConfigLayers,
|
|
7
|
+
parseConfigText,
|
|
8
|
+
resolveUserConfigDir,
|
|
9
|
+
type RawConfigLayer,
|
|
10
|
+
} from "@untangle-code/config";
|
|
11
|
+
import type { FileSystemPort } from "@untangle-code/domain";
|
|
12
|
+
|
|
13
|
+
import { OperationalError } from "../../cli/exit.js";
|
|
14
|
+
|
|
15
|
+
import type { StorageFindingsV1 } from "./types.js";
|
|
16
|
+
|
|
17
|
+
/** Explicit selection wins; an explicitly configured Qdrant remains opt-in. */
|
|
18
|
+
export function initStorageBackend(
|
|
19
|
+
explicit: StorageFindingsV1["backend"] | undefined,
|
|
20
|
+
env: Readonly<Record<string, string | undefined>>,
|
|
21
|
+
existing: RawConfigLayer = {},
|
|
22
|
+
): StorageFindingsV1["backend"] {
|
|
23
|
+
const selected = explicit ?? env["UNTANGLE_STORAGE_BACKEND"] ?? existing.storage?.backend;
|
|
24
|
+
if (selected !== undefined) {
|
|
25
|
+
if (selected === "lancedb" || selected === "qdrant") return selected;
|
|
26
|
+
throw new OperationalError(
|
|
27
|
+
`Unknown storage backend ${JSON.stringify(selected)}.`,
|
|
28
|
+
"Select --storage=lancedb or --storage=qdrant.",
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return existing.qdrant !== undefined ||
|
|
32
|
+
buildEnvConfigLayer(env as NodeJS.ProcessEnv).layer.qdrant !== undefined
|
|
33
|
+
? "qdrant"
|
|
34
|
+
: "lancedb";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Inspect a local directory without opening a database or creating files. */
|
|
38
|
+
export async function inspectInitStorage(
|
|
39
|
+
fs: FileSystemPort,
|
|
40
|
+
root: string,
|
|
41
|
+
explicit: StorageFindingsV1["backend"] | undefined,
|
|
42
|
+
env: Readonly<Record<string, string | undefined>>,
|
|
43
|
+
signal?: AbortSignal,
|
|
44
|
+
): Promise<StorageFindingsV1> {
|
|
45
|
+
signal?.throwIfAborted();
|
|
46
|
+
const { layer: existing, warnings } = await existingStorageConfig(fs, root, env, signal);
|
|
47
|
+
const backend = initStorageBackend(explicit, env, existing);
|
|
48
|
+
if (backend === "qdrant") {
|
|
49
|
+
const mode = env["UNTANGLE_QDRANT_MODE"] ?? existing.qdrant?.mode;
|
|
50
|
+
const url = env["UNTANGLE_QDRANT_URL"] ?? existing.qdrant?.url;
|
|
51
|
+
return {
|
|
52
|
+
backend,
|
|
53
|
+
...(mode === "managed" || mode === "external" ? { qdrantMode: mode } : {}),
|
|
54
|
+
...(url === undefined ? {} : { qdrantUrl: url }),
|
|
55
|
+
...(warnings.length === 0 ? {} : { configurationWarnings: warnings }),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const localPath =
|
|
59
|
+
env["UNTANGLE_LANCEDB_PATH"] ?? existing.storage?.path ?? DEFAULT_STORAGE_CONFIG.path;
|
|
60
|
+
if (!localPath)
|
|
61
|
+
throw new OperationalError("The local storage path is empty.", "Set UNTANGLE_LANCEDB_PATH.");
|
|
62
|
+
const directory = path.resolve(root, localPath);
|
|
63
|
+
signal?.throwIfAborted();
|
|
64
|
+
try {
|
|
65
|
+
const entry = await fs.stat(directory);
|
|
66
|
+
signal?.throwIfAborted();
|
|
67
|
+
return {
|
|
68
|
+
backend,
|
|
69
|
+
path: localPath,
|
|
70
|
+
directory,
|
|
71
|
+
directoryStatus:
|
|
72
|
+
entry === null ? "missing" : entry.kind === "directory" ? "present" : "not-directory",
|
|
73
|
+
...(warnings.length === 0 ? {} : { configurationWarnings: warnings }),
|
|
74
|
+
};
|
|
75
|
+
} catch (error) {
|
|
76
|
+
signal?.throwIfAborted();
|
|
77
|
+
return {
|
|
78
|
+
backend,
|
|
79
|
+
path: localPath,
|
|
80
|
+
directory,
|
|
81
|
+
directoryStatus: "unreadable",
|
|
82
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
83
|
+
...(warnings.length === 0 ? {} : { configurationWarnings: warnings }),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Read the same project layer formats/order as config loading, through init's filesystem port. */
|
|
89
|
+
async function existingStorageConfig(
|
|
90
|
+
fs: FileSystemPort,
|
|
91
|
+
root: string,
|
|
92
|
+
env: Readonly<Record<string, string | undefined>>,
|
|
93
|
+
signal?: AbortSignal,
|
|
94
|
+
): Promise<{ layer: RawConfigLayer; warnings: string[] }> {
|
|
95
|
+
signal?.throwIfAborted();
|
|
96
|
+
const json = path.join(root, ".untangle.json");
|
|
97
|
+
const toml = path.join(root, "untangle.toml");
|
|
98
|
+
const legacyExists = (await fs.stat(json)) !== null || (await fs.stat(toml)) !== null;
|
|
99
|
+
const user = path.join(
|
|
100
|
+
resolveUserConfigDir(env as NodeJS.ProcessEnv, process.platform),
|
|
101
|
+
"config.json",
|
|
102
|
+
);
|
|
103
|
+
const paths = [
|
|
104
|
+
{ path: user, format: "json" as const },
|
|
105
|
+
{ path: toml, format: "toml" as const },
|
|
106
|
+
{
|
|
107
|
+
path: legacyExists ? json : path.join(root, ".untangle/config.json"),
|
|
108
|
+
format: "json" as const,
|
|
109
|
+
},
|
|
110
|
+
{ path: path.join(root, ".untangle.local.json"), format: "json" as const },
|
|
111
|
+
];
|
|
112
|
+
const layers: RawConfigLayer[] = [];
|
|
113
|
+
const warnings: string[] = [];
|
|
114
|
+
let legacyQdrant = false;
|
|
115
|
+
for (const file of paths) {
|
|
116
|
+
signal?.throwIfAborted();
|
|
117
|
+
try {
|
|
118
|
+
if ((await fs.stat(file.path))?.kind !== "file") continue;
|
|
119
|
+
const layer = parseConfigText(await fs.readTextFile(file.path), file.format);
|
|
120
|
+
if (layer.qdrant !== undefined) legacyQdrant = true;
|
|
121
|
+
layers.push(layer);
|
|
122
|
+
} catch {
|
|
123
|
+
signal?.throwIfAborted();
|
|
124
|
+
warnings.push(
|
|
125
|
+
`Storage selection could not be inspected in ${file.path}; existing configuration is preserved unless --force is selected.`,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
layer: mergeConfigLayers<RawConfigLayer>([
|
|
131
|
+
...(legacyQdrant ? [{ storage: { backend: "qdrant" } }] : []),
|
|
132
|
+
...layers,
|
|
133
|
+
]),
|
|
134
|
+
warnings,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A small, purpose-built TOML emitter.
|
|
3
|
+
*
|
|
4
|
+
* WHY NOT A LIBRARY: the point of the file `init` writes is the COMMENTS —
|
|
5
|
+
* the user must be able to see what was decided and why. Every general TOML
|
|
6
|
+
* serializer takes a value and drops the prose, because prose is not part of
|
|
7
|
+
* the value. So the emitter here is a line builder that happens to know how
|
|
8
|
+
* to spell TOML scalars, not a serializer of an object graph.
|
|
9
|
+
*
|
|
10
|
+
* It is deliberately narrow: tables, array-of-tables, scalars and homogeneous
|
|
11
|
+
* scalar arrays. Anything outside that throws rather than guessing — a config
|
|
12
|
+
* file that silently loses a value would be worse than no config file at all.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export type TomlScalar = string | number | boolean;
|
|
16
|
+
|
|
17
|
+
const BARE_KEY = /^[A-Za-z0-9_-]+$/;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* TOML basic-string escaping. `\` and `"` plus the control characters TOML
|
|
21
|
+
* names explicitly; everything else below U+0020 goes to `\uXXXX` because a
|
|
22
|
+
* raw control byte in a config file is unreadable and, in some cases,
|
|
23
|
+
* unparseable.
|
|
24
|
+
*/
|
|
25
|
+
export function escapeTomlString(value: string): string {
|
|
26
|
+
let out = "";
|
|
27
|
+
for (const char of value) {
|
|
28
|
+
switch (char) {
|
|
29
|
+
case "\\":
|
|
30
|
+
out += "\\\\";
|
|
31
|
+
break;
|
|
32
|
+
case '"':
|
|
33
|
+
out += '\\"';
|
|
34
|
+
break;
|
|
35
|
+
case "\b":
|
|
36
|
+
out += "\\b";
|
|
37
|
+
break;
|
|
38
|
+
case "\t":
|
|
39
|
+
out += "\\t";
|
|
40
|
+
break;
|
|
41
|
+
case "\n":
|
|
42
|
+
out += "\\n";
|
|
43
|
+
break;
|
|
44
|
+
case "\f":
|
|
45
|
+
out += "\\f";
|
|
46
|
+
break;
|
|
47
|
+
case "\r":
|
|
48
|
+
out += "\\r";
|
|
49
|
+
break;
|
|
50
|
+
default: {
|
|
51
|
+
const code = char.codePointAt(0) ?? 0;
|
|
52
|
+
if (code < 0x20 || code === 0x7f) {
|
|
53
|
+
out += `\\u${code.toString(16).padStart(4, "0").toUpperCase()}`;
|
|
54
|
+
} else {
|
|
55
|
+
out += char;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** A key is written bare when it can be, quoted when it must be. */
|
|
64
|
+
export function formatTomlKey(key: string): string {
|
|
65
|
+
return BARE_KEY.test(key) ? key : `"${escapeTomlString(key)}"`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Formats a number the way TOML distinguishes integers from floats: an
|
|
70
|
+
* integral value stays integral, a fractional one keeps its decimal point.
|
|
71
|
+
* Non-finite numbers are rejected — TOML has `inf`/`nan` literals, but a
|
|
72
|
+
* config value that is either is a bug upstream, not something to serialize.
|
|
73
|
+
*/
|
|
74
|
+
export function formatTomlNumber(value: number): string {
|
|
75
|
+
if (!Number.isFinite(value)) {
|
|
76
|
+
throw new Error(`cannot serialize non-finite number: ${String(value)}`);
|
|
77
|
+
}
|
|
78
|
+
if (Number.isInteger(value)) {
|
|
79
|
+
return value.toFixed(0);
|
|
80
|
+
}
|
|
81
|
+
return String(value);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function formatTomlScalar(value: TomlScalar): string {
|
|
85
|
+
if (typeof value === "string") {
|
|
86
|
+
return `"${escapeTomlString(value)}"`;
|
|
87
|
+
}
|
|
88
|
+
if (typeof value === "boolean") {
|
|
89
|
+
return value ? "true" : "false";
|
|
90
|
+
}
|
|
91
|
+
return formatTomlNumber(value);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* A line builder for commented TOML.
|
|
96
|
+
*
|
|
97
|
+
* Order is the order of the calls: this class never reorders anything, which
|
|
98
|
+
* is what lets the caller interleave prose and values so that each decision
|
|
99
|
+
* sits directly under its justification.
|
|
100
|
+
*/
|
|
101
|
+
export class TomlWriter {
|
|
102
|
+
private readonly lines: string[] = [];
|
|
103
|
+
|
|
104
|
+
/** A `#` comment. An empty string yields a bare `#`, which reads as a spacer. */
|
|
105
|
+
public comment(text: string): this {
|
|
106
|
+
this.lines.push(text.length === 0 ? "#" : `# ${text}`);
|
|
107
|
+
return this;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Several comment lines at once; convenience for wrapped prose. */
|
|
111
|
+
public comments(texts: readonly string[]): this {
|
|
112
|
+
for (const text of texts) {
|
|
113
|
+
this.comment(text);
|
|
114
|
+
}
|
|
115
|
+
return this;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public blank(): this {
|
|
119
|
+
this.lines.push("");
|
|
120
|
+
return this;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** A `[table.path]` header. */
|
|
124
|
+
public table(path: readonly string[]): this {
|
|
125
|
+
this.lines.push(`[${path.map(formatTomlKey).join(".")}]`);
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** A `[[table.path]]` array-of-tables header. */
|
|
130
|
+
public arrayTable(path: readonly string[]): this {
|
|
131
|
+
this.lines.push(`[[${path.map(formatTomlKey).join(".")}]]`);
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
public scalar(key: string, value: TomlScalar): this {
|
|
136
|
+
this.lines.push(`${formatTomlKey(key)} = ${formatTomlScalar(value)}`);
|
|
137
|
+
return this;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* A single-line array. Written multi-line once it would be long, because a
|
|
142
|
+
* 200-column exclude list is not something a human edits.
|
|
143
|
+
*/
|
|
144
|
+
public array(key: string, values: readonly TomlScalar[]): this {
|
|
145
|
+
const rendered = values.map(formatTomlScalar);
|
|
146
|
+
const inline = `${formatTomlKey(key)} = [${rendered.join(", ")}]`;
|
|
147
|
+
if (rendered.length === 0 || inline.length <= 96) {
|
|
148
|
+
this.lines.push(inline);
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
this.lines.push(`${formatTomlKey(key)} = [`);
|
|
152
|
+
for (const item of rendered) {
|
|
153
|
+
this.lines.push(` ${item},`);
|
|
154
|
+
}
|
|
155
|
+
this.lines.push("]");
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** An empty inline table — the honest way to write "nothing configured here". */
|
|
160
|
+
public emptyInlineTable(key: string): this {
|
|
161
|
+
this.lines.push(`${formatTomlKey(key)} = {}`);
|
|
162
|
+
return this;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* The finished document. Always ends in exactly one newline: a trailing
|
|
167
|
+
* newline is what every line-oriented tool expects, and "exactly one" is
|
|
168
|
+
* what keeps the idempotency comparison from reporting phantom changes.
|
|
169
|
+
*/
|
|
170
|
+
public render(): string {
|
|
171
|
+
const body = this.lines.join("\n").replace(/\n+$/u, "");
|
|
172
|
+
return `${body}\n`;
|
|
173
|
+
}
|
|
174
|
+
}
|