@untangle-code/cli 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/NOTICE +90 -0
- package/README.md +424 -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,336 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
import { createCategoryClusterLayout } from "./category-clusters.js";
|
|
4
|
+
import { createFeatureThread, createFeatureWoolLayout, projectFeaturePoint } from "./feature-3d.js";
|
|
5
|
+
import { createFeatureClusterLayout } from "./feature-clusters.js";
|
|
6
|
+
import type { FeatureMapGraphV1, FeatureMapNodeV1 } from "./feature-model.js";
|
|
7
|
+
import { createFeatureUntangleMotion } from "./feature-untangle-motion.js";
|
|
8
|
+
|
|
9
|
+
/** Overflow gets its own column, so nodes never wrap onto an occupied lane position. */
|
|
10
|
+
export function createFeatureLaneLayout(nodes: readonly Pick<FeatureMapNodeV1, "id" | "kind">[]): {
|
|
11
|
+
positions: Record<string, { x: number; y: number }>;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
} {
|
|
15
|
+
const positions: Record<string, { x: number; y: number }> = Object.create(null) as Record<
|
|
16
|
+
string,
|
|
17
|
+
{ x: number; y: number }
|
|
18
|
+
>;
|
|
19
|
+
let cursor = 70;
|
|
20
|
+
for (const kind of ["owner", "intent", "feature", "code", "test", "unmapped"]) {
|
|
21
|
+
const group = nodes
|
|
22
|
+
.filter((node) => node.kind === kind)
|
|
23
|
+
.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
|
24
|
+
if (group.length === 0) continue;
|
|
25
|
+
const rows = kind === "feature" ? 10 : 22;
|
|
26
|
+
const columnWidth = kind === "feature" ? 300 : 28;
|
|
27
|
+
const rowHeight = kind === "feature" ? 70 : 32;
|
|
28
|
+
group.forEach((node, index) => {
|
|
29
|
+
positions[node.id] = {
|
|
30
|
+
x: cursor + Math.floor(index / rows) * columnWidth,
|
|
31
|
+
y: 65 + (index % rows) * rowHeight,
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
cursor += Math.max(180, Math.ceil(group.length / rows) * columnWidth + 70);
|
|
35
|
+
}
|
|
36
|
+
const width = Math.max(1300, cursor + 30);
|
|
37
|
+
const shift = Math.max(0, (1300 - cursor - 30) / 2);
|
|
38
|
+
if (shift > 0) for (const point of Object.values(positions)) point.x += shift;
|
|
39
|
+
return { positions, width, height: 820 };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Readable group context is separate from the scale-dependent diagram labels. */
|
|
43
|
+
export function createFeatureGroupIndex(
|
|
44
|
+
groups: readonly {
|
|
45
|
+
id: string;
|
|
46
|
+
kind: "feature" | "category" | "shared" | "unassigned";
|
|
47
|
+
label?: string;
|
|
48
|
+
featureId?: string;
|
|
49
|
+
memberIds: readonly string[];
|
|
50
|
+
}[],
|
|
51
|
+
nodes: readonly Pick<FeatureMapNodeV1, "id" | "label">[],
|
|
52
|
+
visibleIds: readonly string[],
|
|
53
|
+
): { id: string; label: string; visible: number; total: number }[] {
|
|
54
|
+
const labels = new Map(nodes.map((node) => [node.id, node.label]));
|
|
55
|
+
const visible = new Set(visibleIds);
|
|
56
|
+
return groups.flatMap((group) => {
|
|
57
|
+
const count = group.memberIds.filter((id) => visible.has(id)).length;
|
|
58
|
+
if (count === 0) return [];
|
|
59
|
+
return [
|
|
60
|
+
{
|
|
61
|
+
id: group.id,
|
|
62
|
+
label:
|
|
63
|
+
group.label ||
|
|
64
|
+
(group.featureId && labels.get(group.featureId)) ||
|
|
65
|
+
(group.kind === "shared" ? "Shared context" : "Unassigned"),
|
|
66
|
+
visible: count,
|
|
67
|
+
total: group.memberIds.length,
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const GROUPINGS = [
|
|
74
|
+
{
|
|
75
|
+
id: "feature",
|
|
76
|
+
label: "Features",
|
|
77
|
+
action: "Untangle by feature",
|
|
78
|
+
subject: "declared feature scopes",
|
|
79
|
+
complete: "Declared feature scopes. Shared context and unassigned files stay visible. ",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: "code",
|
|
83
|
+
label: "Code areas",
|
|
84
|
+
action: "Untangle code areas",
|
|
85
|
+
subject: "code directories",
|
|
86
|
+
complete: "Code directories. Shared and unmatched context stay visible. ",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "test",
|
|
90
|
+
label: "Test areas",
|
|
91
|
+
action: "Untangle test areas",
|
|
92
|
+
subject: "test directories",
|
|
93
|
+
complete: "Test directories. Shared and unmatched context stay visible. ",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
id: "owner",
|
|
97
|
+
label: "Ownership",
|
|
98
|
+
action: "Untangle ownership",
|
|
99
|
+
subject: "declared ownership context",
|
|
100
|
+
complete: "Declared owner context via features. Shared context is separate. ",
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: "intent",
|
|
104
|
+
label: "Vision / Spec",
|
|
105
|
+
action: "Untangle vision / spec",
|
|
106
|
+
subject: "declared document context",
|
|
107
|
+
complete: "Declared document context via features. Shared context is separate. ",
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: "unmapped",
|
|
111
|
+
label: "Unassigned",
|
|
112
|
+
action: "Untangle unassigned",
|
|
113
|
+
subject: "unassigned file directories",
|
|
114
|
+
complete: "Unassigned files by directory; declared context stays separate. ",
|
|
115
|
+
},
|
|
116
|
+
] as const;
|
|
117
|
+
|
|
118
|
+
const STYLE = String.raw`
|
|
119
|
+
:root{color-scheme:light;--paper:#f8f5ed;--white:#fff;--ink:#173734;--soft:#405c57;--line:#ccd5cb;--patina:#27685d;--orange:#b44d1f;--focus:#a74316;font-family:"Avenir Next",Avenir,"Segoe UI",system-ui,sans-serif;color:var(--ink);background:var(--paper)}
|
|
120
|
+
*{box-sizing:border-box}body{margin:0}button,input,select{font:inherit;color:inherit}button,select,input{background:var(--white);border:1px solid #7a948b;border-radius:5px;min-height:38px}button{padding:6px 12px;cursor:pointer}button:hover{background:#e2eee8}button:disabled{opacity:.5;cursor:default}button[aria-pressed=true]{background:var(--ink);color:var(--white)}:focus-visible{outline:3px solid var(--focus);outline-offset:3px}input{padding:7px 10px;caret-color:var(--orange)}::selection{background:#d4e8dc;color:var(--ink)}html{scrollbar-color:var(--patina) var(--paper)}a{color:var(--patina);text-underline-offset:.2em}.skip{position:absolute;left:12px;top:-80px;padding:10px;background:#fff;z-index:5}.skip:focus{top:12px}header{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:19px 25px;border-bottom:1px solid var(--line);background:#fff}h1{margin:0;font-size:1.65rem;letter-spacing:-.02em}header p{margin:3px 0 0;color:var(--soft);font-size:.88rem}.brand{display:flex;gap:12px;align-items:center}.brand svg{width:42px;height:42px;flex:none}.snapshot{font-family:"SFMono-Regular",Consolas,monospace;font-size:.75rem;overflow-wrap:anywhere}.toolbar{display:flex;align-items:end;flex-wrap:wrap;gap:12px;padding:15px 25px;background:#fff;border-bottom:1px solid var(--line)}.field{display:grid;gap:4px;font-size:.8rem}.field input{width:min(34vw,350px)}.toolbar label{font-weight:600}.toolbar select{padding:6px 25px 6px 9px}.scope{margin:0;padding:10px 25px;color:var(--soft);font-size:.85rem;line-height:1.5;border-bottom:1px solid var(--line)}.scope[data-incomplete=true]{background:#fff0df;color:#783b15}.workspace{display:grid;grid-template-columns:minmax(0,1fr) 355px;height:calc(100dvh - 220px);min-height:460px}.map-region{position:relative;min-width:0;overflow:hidden;touch-action:none;background:var(--paper)}#viewport{height:100%;min-height:400px;outline-offset:-5px}#map{display:block;width:100%;height:100%;user-select:none}#map .edge{fill:none;stroke-width:1.3;opacity:.42}#map .edge.ownership{stroke:#2e7968;stroke-dasharray:4 4}#map .edge.intent{stroke:#7a6e92;stroke-dasharray:2 5}#map .edge.test{stroke:#477896}#map .edge.code{stroke:#bd632e}#map .edge.dependency{stroke:#903d24;stroke-width:2.5}#map .node{cursor:pointer}#map .node.selected .shape{stroke:#152f2c;stroke-width:4}#map .node .shape{stroke:#4d6a5c;stroke-width:1.4;fill:#fff}#map .node.feature .shape{fill:#edb68e;stroke:#9d4c26}#map .node.owner .shape{fill:#d3e7dc;stroke:#2c6d5e}#map .node.test .shape{fill:#d9e9ef;stroke:#3e7187}#map .node.intent .shape{fill:#e6e0ee;stroke:#74618b}#map .node.unmapped .shape{fill:#eeeae2;stroke:#77776b;stroke-dasharray:3 3}#map text{fill:#183733;font:12px "Avenir Next",Avenir,system-ui,sans-serif;paint-order:stroke;stroke:var(--paper);stroke-width:3px;stroke-linejoin:round;pointer-events:none}#map .feature text{font-weight:700;font-size:13px}.zoom{position:absolute;bottom:17px;left:20px;display:flex;gap:6px;background:var(--paper);padding:6px;border-radius:7px}.legend{position:absolute;top:12px;left:20px;display:flex;gap:14px;flex-wrap:wrap;padding:5px 0;font-size:.75rem;max-width:90%;color:var(--soft)}.legend span::before{content:"";display:inline-block;width:9px;height:9px;border:1px solid #4d6a5c;border-radius:50%;margin-right:5px;vertical-align:baseline;background:#edb68e}.legend .code::before{background:#fff}.legend .test::before{background:#d9e9ef}.legend .owner::before{background:#d3e7dc;border-radius:0}.legend .intent::before{background:#e6e0ee;border-radius:0;transform:rotate(45deg)}.legend .unmapped::before{background:#eeeae2;border-style:dashed}.aside{border-left:1px solid var(--line);background:#fff;overflow:auto;padding:21px;overscroll-behavior:contain}.aside h2{margin:0 0 10px;font-size:1.08rem;overflow-wrap:anywhere}.aside h3{margin:22px 0 8px;font-size:.9rem}.aside p,.aside li{font-size:.85rem;line-height:1.55;overflow-wrap:anywhere}.aside p{color:var(--soft);margin:8px 0}.aside ul{padding-left:20px}.aside .status{color:#773b19}.aside pre{white-space:pre-wrap;overflow-wrap:anywhere;font-size:.74rem;line-height:1.5;background:var(--paper);padding:10px}.aside code,.path{font-family:"SFMono-Regular",Consolas,monospace;font-size:.78rem}.path{width:100%;min-width:0}.node-list{display:flex;flex-direction:column;gap:4px;margin:9px 0 0}.node-list button{text-align:left;font-size:.8rem;line-height:1.35;overflow-wrap:anywhere;min-height:34px}.node-list button[aria-current=true]{background:#dfece3;border-color:var(--patina)}.section-line{display:flex;align-items:center;justify-content:space-between;gap:10px}.section-line h2{margin:0}.muted{color:var(--soft)}.empty{position:absolute;top:35%;left:8%;right:8%;max-width:48ch;text-align:center;margin:auto}.empty h2{font-size:1.5rem;letter-spacing:-.02em}.empty p{line-height:1.65;color:var(--soft)}.empty[hidden]{display:none}.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}details{margin-top:22px;font-size:.83rem}details summary{cursor:pointer}footer{padding:11px 25px;background:#fff;border-top:1px solid var(--line);font-size:.75rem;color:var(--soft)}.selection-tools{display:flex;gap:6px;margin:10px 0;flex-wrap:wrap}
|
|
121
|
+
@media(max-width:850px){header{padding:15px 16px;align-items:flex-start}header .snapshot{max-width:120px}h1{font-size:1.5rem}.toolbar{padding:12px 16px;gap:9px}.field input{width:100%}.field{flex:1 1 140px}.field-search{flex:1 1 100%}.toolbar>button{flex:1 1 120px}.scope{padding:9px 16px}.workspace{grid-template-columns:1fr;height:auto;min-height:0}.map-region{height:55dvh;min-height:360px}.aside{border-left:0;border-top:1px solid var(--line);height:auto;max-height:65dvh;padding:18px 16px}footer{padding:12px 16px}.legend{left:15px;gap:8px;font-size:.7rem}.zoom{left:12px;bottom:10px}#viewport{min-height:360px}}
|
|
122
|
+
.untangle-action{position:absolute;right:20px;bottom:17px;max-width:170px;min-height:44px;padding:8px 13px;border-color:var(--patina);background:var(--ink);color:var(--white);font-weight:650}.untangle-action:hover{background:#27685d}.untangle-note{position:absolute;left:20px;right:20px;bottom:75px;max-width:75ch;margin:0;pointer-events:none;font-size:.8rem;line-height:1.45;color:var(--soft);background:var(--paper)}#map .cluster-zone{fill:#deebe4;fill-opacity:.28;stroke:#8aa99c;stroke-width:1;stroke-dasharray:3 3}#map .cluster-context .cluster-zone{fill:#e6e0ee;stroke:#9d91ae}#map .cluster-unassigned .cluster-zone{fill:#eeeae2;stroke:#99978a}#map .cluster-title{font-size:12px;font-weight:700;text-anchor:middle}#map .cluster-count{font-size:10px;text-anchor:middle}#map[data-clustered=true] .node.feature text{display:none}.cluster-regions{pointer-events:none}
|
|
123
|
+
@media(max-width:850px){.untangle-action{right:12px;bottom:10px;max-width:165px;font-size:.85rem}.untangle-note{left:15px;right:15px;bottom:71px;font-size:.75rem}.zoom{padding:4px;gap:4px}.zoom button{padding:6px 10px;min-width:34px}}
|
|
124
|
+
#map[data-grouping=test] .cluster-category .cluster-zone{fill:#d9e9ef;stroke:#779cab}#map[data-grouping=owner] .cluster-category .cluster-zone{fill:#d3e7dc;stroke:#669685}#map[data-grouping=intent] .cluster-category .cluster-zone{fill:#e6e0ee;stroke:#9d91ae}#map[data-grouping=unmapped] .cluster-category .cluster-zone{fill:#eeeae2;stroke:#99978a}
|
|
125
|
+
#group-index summary{min-height:44px;padding:10px 0;font-size:.9rem;font-weight:650}.map-region{display:grid;grid-template-rows:auto minmax(0,1fr) 135px}.map-region .legend{position:static;max-width:none;margin:12px 20px 8px}#viewport{height:100%;min-height:0;position:relative}.empty{top:50%;transform:translateY(-50%)}@media(max-width:850px){.map-region .legend{margin:12px 15px 8px}}
|
|
126
|
+
@media(prefers-reduced-motion:no-preference){button{transition:background-color .15s ease-out}}
|
|
127
|
+
`;
|
|
128
|
+
|
|
129
|
+
const SCRIPT = String.raw`
|
|
130
|
+
(function(){
|
|
131
|
+
"use strict";
|
|
132
|
+
var raw=atob(document.getElementById("map-data").textContent.trim());
|
|
133
|
+
var data=JSON.parse(new TextDecoder().decode(Uint8Array.from(raw,function(c){return c.charCodeAt(0)})));
|
|
134
|
+
var svg=document.getElementById("map"),world=document.createElementNS("http://www.w3.org/2000/svg","g"),viewport=document.getElementById("viewport");svg.appendChild(world);
|
|
135
|
+
var state={selected:null,query:"",kind:"all",isolate:false,layout:"wool",grouping:"feature",zoom:1,dx:0,dy:0,yaw:.35,pitch:-.22,spinning:false},positions=new Map(),visibleNodes=[],drag=null,bounds={width:1300,height:820};
|
|
136
|
+
var laneLayout=${createFeatureLaneLayout.toString()};
|
|
137
|
+
var createFeatureWoolLayout=${createFeatureWoolLayout.toString()};
|
|
138
|
+
var createFeatureClusterLayout=${createFeatureClusterLayout.toString()};
|
|
139
|
+
var createCategoryClusterLayout=${createCategoryClusterLayout.toString()};
|
|
140
|
+
var createFeatureGroupIndex=${createFeatureGroupIndex.toString()};
|
|
141
|
+
var groupingChoices=${JSON.stringify(GROUPINGS)},groupingSelect=document.getElementById("grouping");
|
|
142
|
+
var createFeatureUntangleMotion=${createFeatureUntangleMotion.toString()};
|
|
143
|
+
var projectFeaturePoint=${projectFeaturePoint.toString()};
|
|
144
|
+
var createFeatureThread=${createFeatureThread.toString()};
|
|
145
|
+
var labels={feature:"Feature",code:"Code",test:"Test",owner:"Ownership",intent:"Vision / Spec",unmapped:"Unassigned"};
|
|
146
|
+
var relations={code:"Code scope",test:"Test scope",ownership:"Declared ownership",intent:"Intent",dependency:"Declared feature dependency"};
|
|
147
|
+
var byId=new Map(data.nodes.map(function(n){return[n.id,n]}));
|
|
148
|
+
var nodeElements=new Map(),edgeElements=new Map(),projected=new Map();
|
|
149
|
+
function groupingChoice(){return groupingChoices.find(function(choice){return choice.id===state.grouping})}
|
|
150
|
+
function createGrouping(){return state.grouping==="feature"?createFeatureClusterLayout(data.nodes,data.edges):createCategoryClusterLayout(data.nodes,data.edges,state.grouping)}
|
|
151
|
+
var clusterLayout=createGrouping(),clusterAmount=0,groupElements=new Map(),mapVisible=true,untangleMotion=null;
|
|
152
|
+
var untangleButton=document.getElementById("untangle"),untangleNote=document.getElementById("untangle-note");
|
|
153
|
+
var motion=typeof matchMedia==="function"?matchMedia("(prefers-reduced-motion: reduce)"):null;
|
|
154
|
+
var frame=null,lastFrame=0,rotationStarted=0,rotationButton=document.getElementById("rotation");
|
|
155
|
+
function el(name,attrs){var e=document.createElementNS("http://www.w3.org/2000/svg",name);Object.keys(attrs||{}).forEach(function(k){e.setAttribute(k,String(attrs[k]))});return e}
|
|
156
|
+
function para(text,cls){var p=document.createElement("p");p.textContent=text;if(cls)p.className=cls;return p}
|
|
157
|
+
function neighbors(id){var ids=new Set([id]);data.edges.forEach(function(e){if(e.from===id)ids.add(e.to);if(e.to===id)ids.add(e.from)});return ids}
|
|
158
|
+
function seed(id){var value=2166136261;for(var i=0;i<id.length;i++)value=Math.imul(value^id.charCodeAt(i),16777619);return(value>>>0)/4294967296}
|
|
159
|
+
function layout(){
|
|
160
|
+
positions.clear();
|
|
161
|
+
if(state.layout==="lanes"){
|
|
162
|
+
var lanes=laneLayout(data.nodes);Object.keys(lanes.positions).forEach(function(id){positions.set(id,{x:lanes.positions[id].x,y:lanes.positions[id].y,z:0})});bounds={width:lanes.width,height:lanes.height};
|
|
163
|
+
}else{
|
|
164
|
+
clusterAmount=state.layout==="clusters"?1:0;
|
|
165
|
+
var clustered=state.layout==="clusters"?clusterLayout.positions:null;
|
|
166
|
+
var wool=clustered||createFeatureWoolLayout(data.nodes,data.edges);Object.keys(wool).forEach(function(id){positions.set(id,wool[id])});bounds={width:1300,height:820};
|
|
167
|
+
}
|
|
168
|
+
if(state.layout==="lanes")clusterAmount=0;
|
|
169
|
+
svg.setAttribute("viewBox","0 0 "+bounds.width+" "+bounds.height);rotationButton.disabled=state.layout==="lanes"||Boolean(motion&&motion.matches);
|
|
170
|
+
}
|
|
171
|
+
function transform(){var x=bounds.width/2,y=bounds.height/2;world.setAttribute("transform","translate("+state.dx+" "+state.dy+") translate("+x+" "+y+") scale("+state.zoom+") translate("+(-x)+" "+(-y)+")")}
|
|
172
|
+
function nodeRadius(n){return n.kind==="feature"?Math.min(29,14+Math.sqrt(Math.max(0,n.cognitive||0))*1.1):n.kind==="code"||n.kind==="unmapped"?5.5:8}
|
|
173
|
+
function focusedControl(){
|
|
174
|
+
var active=document.activeElement;if(!active||!active.closest)return null;
|
|
175
|
+
for(var kind of ["graph","list","relation"]){var owner=active.closest("[data-"+kind+"-node]");if(owner)return{kind:kind,id:owner.getAttribute("data-"+kind+"-node")}}
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
function restoreFocus(previous){
|
|
179
|
+
if(!previous)return;
|
|
180
|
+
var target=previous.kind==="graph"?svg.querySelector('[data-graph-node="'+previous.id+'"]'):document.getElementById("node-list").querySelector('[data-list-node="'+previous.id+'"]');
|
|
181
|
+
if(!target&&previous.kind!=="graph")target=svg.querySelector('[data-graph-node="'+previous.id+'"]');
|
|
182
|
+
(target||viewport).focus({preventScroll:true});
|
|
183
|
+
}
|
|
184
|
+
function paintGroups(){
|
|
185
|
+
var opacity=Math.max(0,Math.min(1,(clusterAmount-.45)/.55));
|
|
186
|
+
groupElements.forEach(function(item){
|
|
187
|
+
var points=item.group.memberIds.map(function(id){return projected.get(id)}).filter(Boolean);
|
|
188
|
+
item.element.style.opacity=String(opacity);item.element.style.display=state.layout==="lanes"||!points.length||!opacity?"none":"";
|
|
189
|
+
if(!points.length||!opacity)return;
|
|
190
|
+
var xs=points.map(function(p){return p.x}),ys=points.map(function(p){return p.y}),left=Math.min.apply(null,xs),right=Math.max.apply(null,xs),top=Math.min.apply(null,ys),bottom=Math.max.apply(null,ys),x=(left+right)/2;
|
|
191
|
+
item.zone.setAttribute("cx",x);item.zone.setAttribute("cy",(top+bottom)/2);item.zone.setAttribute("rx",Math.max(26,(right-left)/2+11));item.zone.setAttribute("ry",Math.max(22,(bottom-top)/2+11));
|
|
192
|
+
var feature=item.group.featureId&&byId.get(item.group.featureId),label=item.group.label||(feature?feature.label:item.group.kind==="shared"?"Shared context":"Unassigned");
|
|
193
|
+
item.title.textContent=label.length>23&&(item.group.kind==="feature"||item.group.kind==="category")?label.slice(0,20)+"…":label;item.title.setAttribute("x",x);item.title.setAttribute("y",top-18);item.count.textContent=points.length+" nodes";item.count.setAttribute("x",x);item.count.setAttribute("y",top-5);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
function paint(){
|
|
197
|
+
var related=state.selected?neighbors(state.selected):null;
|
|
198
|
+
projected.clear();
|
|
199
|
+
visibleNodes.forEach(function(n){var p=positions.get(n.id);projected.set(n.id,state.layout!=="lanes"?projectFeaturePoint(p,state):{x:p.x,y:p.y,depth:0,scale:1})});
|
|
200
|
+
paintGroups();svg.setAttribute("data-clustered",String(clusterAmount>.6));svg.setAttribute("data-grouping",state.grouping);
|
|
201
|
+
edgeElements.forEach(function(line,id){var edge=line.edge,a=projected.get(edge.from),b=projected.get(edge.to),from=positions.get(edge.from),to=positions.get(edge.to);var curve;
|
|
202
|
+
if(state.layout!=="lanes")curve=createFeatureThread(from,to,state,seed(id)*2-1,clusterAmount);
|
|
203
|
+
else{var bend=(seed(id)-.5)*150;curve="M"+a.x+","+a.y+" C"+(bounds.width/2+bend)+","+(a.y+bend)+" "+(bounds.width/2-bend)+","+(b.y-bend)+" "+b.x+","+b.y}
|
|
204
|
+
line.element.setAttribute("d",curve);var depth=Math.max(.25,Math.min(.8,.52+(a.depth+b.depth)/1800));line.element.style.opacity=String(related&&edge.from!==state.selected&&edge.to!==state.selected?0.08:depth);
|
|
205
|
+
});
|
|
206
|
+
visibleNodes.forEach(function(n){var p=projected.get(n.id),g=nodeElements.get(n.id);g.setAttribute("transform","translate("+p.x+" "+p.y+")"+(state.layout!=="lanes"?" scale("+(p.scale*(1-clusterAmount*.35))+")":""));var depth=Math.max(.4,Math.min(1,.78+p.depth/1200));g.style.opacity=String(related&&!related.has(n.id)?0.22:depth)});
|
|
207
|
+
transform();
|
|
208
|
+
}
|
|
209
|
+
function draw(previous){
|
|
210
|
+
if(previous===undefined)previous=focusedControl();
|
|
211
|
+
while(world.firstChild)world.removeChild(world.firstChild);nodeElements.clear();edgeElements.clear();groupElements.clear();
|
|
212
|
+
var groupLayer=el("g",{"class":"cluster-regions","aria-hidden":"true"});world.appendChild(groupLayer);
|
|
213
|
+
clusterLayout.groups.forEach(function(group){var g=el("g",{"class":group.kind==="shared"?"cluster-context":group.kind==="unassigned"?"cluster-unassigned":group.kind==="category"?"cluster-category":"cluster-feature"}),zone=el("ellipse",{"class":"cluster-zone"}),title=el("text",{"class":"cluster-title"}),count=el("text",{"class":"cluster-count"});g.appendChild(zone);g.appendChild(title);g.appendChild(count);groupLayer.appendChild(g);groupElements.set(group.id,{element:g,zone:zone,title:title,count:count,group:group})});
|
|
214
|
+
var related=state.selected?neighbors(state.selected):null;
|
|
215
|
+
visibleNodes=data.nodes.filter(function(n){return(state.kind==="all"||n.kind===state.kind||(Array.isArray(n.details.roles)&&n.details.roles.includes(state.kind)))&&(!state.query||(n.label+" "+(n.path||"")+" "+JSON.stringify(n.details)).toLowerCase().includes(state.query))&&(!state.isolate||!related||related.has(n.id))});
|
|
216
|
+
var ids=new Set(visibleNodes.map(function(n){return n.id}));
|
|
217
|
+
data.edges.forEach(function(edge){if(!ids.has(edge.from)||!ids.has(edge.to))return;var line=el("path",{"class":"edge "+edge.kind,"data-edge":edge.id});var title=el("title",{});title.textContent=relations[edge.kind];line.appendChild(title);world.appendChild(line);edgeElements.set(edge.id,{element:line,edge:edge})});
|
|
218
|
+
var ordered=visibleNodes.slice();if(state.layout!=="lanes")ordered.sort(function(a,b){return projectFeaturePoint(positions.get(a.id),state).depth-projectFeaturePoint(positions.get(b.id),state).depth});
|
|
219
|
+
ordered.forEach(function(n){var r=nodeRadius(n);var g=el("g",{"class":"node "+n.kind+(state.selected===n.id?" selected":""),tabindex:"0",role:"button","data-graph-node":n.id,"aria-label":labels[n.kind]+": "+n.label+"; "+n.status});
|
|
220
|
+
var shape;if(n.kind==="owner")shape=el("rect",{x:-r,y:-r,width:r*2,height:r*2,"class":"shape"});else if(n.kind==="intent")shape=el("path",{d:"M0,-"+(r+3)+" L"+(r+3)+",0 L0,"+(r+3)+" L-"+(r+3)+",0 Z","class":"shape"});else shape=el("circle",{r:r,"class":"shape"});g.appendChild(shape);
|
|
221
|
+
var title=el("title",{});title.textContent=n.label+" ("+n.status+")"+(typeof n.cognitive==="number"?" — cognitive execution_unit "+n.cognitive:"");g.appendChild(title);
|
|
222
|
+
if(n.kind==="feature"||state.selected===n.id){var text=el("text",{x:r+7,y:4});text.textContent=n.label.length>40?n.label.slice(0,37)+"…":n.label;g.appendChild(text)}
|
|
223
|
+
g.addEventListener("focus",function(){settleUntangling();stopRotation()});g.addEventListener("click",function(e){e.stopPropagation();select(n.id,{kind:"graph",id:n.id})});g.addEventListener("keydown",function(e){if(e.key==="Enter"||e.key===" "){e.preventDefault();select(n.id)}});world.appendChild(g);nodeElements.set(n.id,g);
|
|
224
|
+
});paint();updateList();updateGroupIndex();
|
|
225
|
+
document.getElementById("visible-count").textContent=visibleNodes.length+" / "+data.summary.totalNodes+" nodes";
|
|
226
|
+
var empty=document.getElementById("empty");empty.hidden=visibleNodes.length!==0;
|
|
227
|
+
document.getElementById("empty-title").textContent=data.nodes.length?"No match in this snapshot":"No declared feature map yet";
|
|
228
|
+
document.getElementById("empty-text").textContent=data.nodes.length?"Reset the filters or search for another path.":"This does not mean the code is simple or correct. Declare feature boundaries, tests and ownership, then generate the map again.";
|
|
229
|
+
restoreFocus(previous);
|
|
230
|
+
}
|
|
231
|
+
function updateList(){var list=document.getElementById("node-list");while(list.firstChild)list.removeChild(list.firstChild);visibleNodes.slice(0,200).forEach(function(n){var b=document.createElement("button");b.type="button";b.textContent=labels[n.kind]+" · "+n.label;b.setAttribute("data-list-node",n.id);b.setAttribute("aria-current",String(n.id===state.selected));b.addEventListener("click",function(){select(n.id,{kind:"list",id:n.id})});list.appendChild(b)});document.getElementById("list-note").textContent=visibleNodes.length>200?"The list shows 200 matches. Narrow the search to reach another node.":"The same nodes as the diagram. Select with Tab and Enter."}
|
|
232
|
+
function updateGroupIndex(){
|
|
233
|
+
var groups=createFeatureGroupIndex(clusterLayout.groups,data.nodes,visibleNodes.map(function(node){return node.id})),list=document.getElementById("group-list");
|
|
234
|
+
while(list.firstChild)list.removeChild(list.firstChild);
|
|
235
|
+
groups.forEach(function(group){var item=document.createElement("li");item.setAttribute("data-group-id",group.id);item.textContent=group.label+" · "+(group.visible===group.total?group.total+" nodes":group.visible+" / "+group.total+" nodes visible");list.appendChild(item)});
|
|
236
|
+
document.getElementById("group-count").textContent="("+groups.length+")";
|
|
237
|
+
document.getElementById("group-note").textContent=groupingChoice().label+". Counts describe snapshot nodes; filters affect the visible count. Full feature metrics remain in the details.";
|
|
238
|
+
}
|
|
239
|
+
function heading(parent,text){var h=document.createElement("h3");h.textContent=text;parent.appendChild(h)}
|
|
240
|
+
function json(parent,value){var pre=document.createElement("pre");pre.textContent=JSON.stringify(value,null,2);parent.appendChild(pre)}
|
|
241
|
+
function select(id,previous){
|
|
242
|
+
settleUntangling();stopRotation();if(previous===undefined)previous=focusedControl();
|
|
243
|
+
state.selected=id;var n=byId.get(id),detail=document.getElementById("detail");while(detail.firstChild)detail.removeChild(detail.firstChild);
|
|
244
|
+
var h=document.createElement("h2");h.textContent=n.label;detail.appendChild(h);detail.appendChild(para(labels[n.kind]+" · "+n.status,"status"));
|
|
245
|
+
if(n.path){var input=document.createElement("input");input.className="path";input.value=n.path;input.readOnly=true;input.setAttribute("aria-label","Repository-relative path");input.addEventListener("focus",function(){input.select()});detail.appendChild(input);detail.appendChild(para("Select and copy this path to use it in your editor or agent."))}
|
|
246
|
+
if(n.kind==="feature"){
|
|
247
|
+
if(n.details.metrics){heading(detail,"Complete feature complexity");detail.appendChild(para("Cognitive: execution_unit "+n.details.metrics.cognitive.execution_unit+", self "+n.details.metrics.cognitive.self+", top_level "+n.details.metrics.cognitive.top_level+". "+n.details.metrics.files+" complete code files; "+n.details.metrics.sloc+" SLOC."));detail.appendChild(para("Shared files count in full within each declared feature. Do not add feature readings to produce a repository total."))}else detail.appendChild(para("Complexity is incomplete. Missing measurements are neither zero nor a passed result."));
|
|
248
|
+
heading(detail,"Test evidence");json(detail,n.details.testEvidence);heading(detail,"Agent hints");json(detail,n.details.agentHints);
|
|
249
|
+
}
|
|
250
|
+
heading(detail,"Direct relationships");var ul=document.createElement("ul");data.edges.filter(function(e){return e.from===id||e.to===id}).slice(0,100).forEach(function(e){var other=byId.get(e.from===id?e.to:e.from);if(!other)return;var li=document.createElement("li"),b=document.createElement("button");b.type="button";b.setAttribute("data-relation-node",other.id);b.textContent=relations[e.kind]+": "+other.label;b.addEventListener("click",function(){select(other.id,{kind:"relation",id:other.id})});li.appendChild(b);ul.appendChild(li)});detail.appendChild(ul);
|
|
251
|
+
heading(detail,"Source evidence");json(detail,n.details);document.getElementById("selected-status").textContent=labels[n.kind]+" selected: "+n.label;draw(previous);
|
|
252
|
+
}
|
|
253
|
+
function stopRotation(){state.spinning=false;if(frame!==null&&typeof cancelAnimationFrame==="function")cancelAnimationFrame(frame);frame=null;lastFrame=0;rotationButton.textContent="Start rotation";rotationButton.setAttribute("aria-pressed","false")}
|
|
254
|
+
function animate(timestamp){
|
|
255
|
+
if(!state.spinning)return;
|
|
256
|
+
if(document.hidden||(motion&&motion.matches)||state.layout==="lanes"||!mapVisible||timestamp-rotationStarted>=90000){stopRotation();return}
|
|
257
|
+
var interval=Math.max(33,Math.min(160,edgeElements.size/12));if(!lastFrame||timestamp-lastFrame>=interval){var elapsed=lastFrame?Math.min(100,timestamp-lastFrame):0;state.yaw+=elapsed*.00013;lastFrame=timestamp;paint()}
|
|
258
|
+
frame=requestAnimationFrame(animate);
|
|
259
|
+
}
|
|
260
|
+
function startRotation(){
|
|
261
|
+
settleUntangling();if(state.layout==="lanes"||!mapVisible||(motion&&motion.matches)||typeof requestAnimationFrame!=="function")return;
|
|
262
|
+
state.spinning=true;rotationStarted=typeof performance!=="undefined"?performance.now():0;lastFrame=0;rotationButton.textContent="Pause rotation";rotationButton.setAttribute("aria-pressed","true");frame=requestAnimationFrame(animate);
|
|
263
|
+
}
|
|
264
|
+
function reset(){settleUntangling();stopRotation();state.selected=null;state.query="";state.kind="all";state.isolate=false;state.zoom=1;state.dx=0;state.dy=0;state.yaw=.35;state.pitch=-.22;document.getElementById("search").value="";document.getElementById("kind").value="all";document.getElementById("isolate").setAttribute("aria-pressed","false");document.getElementById("detail").textContent="Select a feature or file. Its complete measurements and relationships appear here.";draw()}
|
|
265
|
+
function zoom(f){settleUntangling();state.zoom=Math.max(.25,Math.min(4,state.zoom*f));transform()}
|
|
266
|
+
function moveCamera(dx,dy){settleUntangling();state.yaw+=dx;state.pitch=Math.max(-1.45,Math.min(1.45,state.pitch+dy));paint()}
|
|
267
|
+
function settleUntangling(){if(untangleMotion){var phase=untangleMotion.getState().phase;if(phase==="running"||phase==="paused")untangleMotion.finish()}}
|
|
268
|
+
function updateUntangleAction(current){
|
|
269
|
+
var running=current.phase==="running",paused=current.phase==="paused",choice=groupingChoice();
|
|
270
|
+
untangleButton.textContent=running?"Pause untangling":paused?"Resume untangling":clusterAmount>.5?"Show tangle":choice.action;
|
|
271
|
+
untangleButton.setAttribute("data-phase",current.phase);untangleButton.disabled=!data.nodes.length;
|
|
272
|
+
rotationButton.disabled=state.layout==="lanes"||Boolean(motion&&motion.matches)||running||paused;
|
|
273
|
+
untangleNote.textContent=(paused?"Untangling paused. Resume when ready. ":running?"Grouping "+choice.subject+". ":clusterAmount>.5?choice.complete:"Group the wool map by "+choice.subject+". ")+"Code and metrics are unchanged.";
|
|
274
|
+
}
|
|
275
|
+
untangleMotion=createFeatureUntangleMotion({
|
|
276
|
+
requestFrame:typeof requestAnimationFrame==="function"?function(callback){return requestAnimationFrame(callback)}:undefined,
|
|
277
|
+
cancelFrame:typeof cancelAnimationFrame==="function"?function(id){cancelAnimationFrame(id)}:undefined,
|
|
278
|
+
reducedMotion:function(){return Boolean(motion&&motion.matches)},visible:function(){return !document.hidden&&mapVisible},
|
|
279
|
+
frameIntervalMs:Math.max(33,Math.min(160,data.edges.length/12)),
|
|
280
|
+
onFrame:function(next,amount){positions=new Map(Object.keys(next).map(function(id){return[id,next[id]]}));clusterAmount=amount;paint()},onState:updateUntangleAction
|
|
281
|
+
});
|
|
282
|
+
untangleButton.addEventListener("click",function(){
|
|
283
|
+
stopRotation();var current=untangleMotion.getState();
|
|
284
|
+
if(current.phase==="running"){untangleMotion.pause();return}if(current.phase==="paused"){untangleMotion.resume();return}
|
|
285
|
+
if(!data.nodes.length)return;
|
|
286
|
+
if(state.layout==="lanes"){state.layout="wool";layout();draw()}
|
|
287
|
+
var target=clusterAmount>.5?"wool":"clusters",from=Object.fromEntries(positions),to=target==="clusters"?clusterLayout.positions:createFeatureWoolLayout(data.nodes,data.edges);
|
|
288
|
+
state.layout=target;document.getElementById("layout").textContent="Arrange by layer";
|
|
289
|
+
untangleMotion.start({from:from,to:to,fromAmount:clusterAmount,toAmount:target==="clusters"?1:0,target:target});
|
|
290
|
+
});
|
|
291
|
+
groupingSelect.value=state.grouping;
|
|
292
|
+
groupingSelect.addEventListener("change",function(){
|
|
293
|
+
if(!groupingChoices.some(function(choice){return choice.id===groupingSelect.value})){groupingSelect.value=state.grouping;return}
|
|
294
|
+
settleUntangling();stopRotation();untangleMotion.cancel();state.grouping=groupingSelect.value;clusterLayout=createGrouping();state.layout="wool";document.getElementById("layout").textContent="Arrange by layer";layout();draw();updateUntangleAction(untangleMotion.getState());
|
|
295
|
+
});
|
|
296
|
+
layout();draw();updateUntangleAction(untangleMotion.getState());
|
|
297
|
+
var summary=data.summary;document.getElementById("snapshot").textContent="Source "+data.sourceTreeDigest.slice(0,12);document.getElementById("scope").textContent=summary.features+" declared features · "+summary.mappedCodeFiles+" mapped code files · "+summary.unmappedCodeFiles+" unassigned · Status: "+summary.status+(summary.truncated?" · BOUNDED SNAPSHOT: "+summary.shownNodes+" / "+summary.totalNodes+" nodes, "+summary.shownEdges+" / "+summary.totalEdges+" edges":"");document.getElementById("scope").dataset.incomplete=String(summary.truncated||summary.status!=="evidence_consistent");
|
|
298
|
+
if(summary.features===0){var intro=document.getElementById("detail");intro.appendChild(para("No declared feature map yet. These files are unassigned; missing complexity readings are not zero."));heading(intro,"Declare a feature boundary");intro.appendChild(para("Use product to propose a scope, save only report.draft as .untangle/features.json, then explicitly review code, tests and ownership. Run graph features again."));var command=document.createElement("pre");command.textContent="untangle product --draft --feature=<id> --path=<file> --format=json";intro.appendChild(command)}
|
|
299
|
+
var issues=document.getElementById("issues");data.issues.concat(data.limitations).forEach(function(issue){var li=document.createElement("li");li.textContent=issue;issues.appendChild(li)});if(data.dependencyCycles.length)issues.appendChild(para("Declared feature cycles: "+JSON.stringify(data.dependencyCycles)));
|
|
300
|
+
document.getElementById("search").addEventListener("input",function(e){settleUntangling();stopRotation();state.query=e.target.value.toLowerCase();draw()});document.getElementById("kind").addEventListener("change",function(e){settleUntangling();stopRotation();state.kind=e.target.value;draw()});
|
|
301
|
+
document.getElementById("isolate").addEventListener("click",function(){settleUntangling();stopRotation();state.isolate=!state.isolate;this.setAttribute("aria-pressed",String(state.isolate));draw()});document.getElementById("layout").addEventListener("click",function(){stopRotation();untangleMotion.cancel();state.layout=state.layout==="lanes"?"wool":"lanes";this.textContent=state.layout==="wool"?"Arrange by layer":"Show 3D wool map";state.zoom=1;state.dx=0;state.dy=0;layout();draw();updateUntangleAction(untangleMotion.getState())});document.getElementById("reset").addEventListener("click",reset);document.getElementById("rotation").addEventListener("click",function(){if(state.spinning)stopRotation();else startRotation()});document.getElementById("zoom-in").addEventListener("click",function(){stopRotation();zoom(1.2)});document.getElementById("zoom-out").addEventListener("click",function(){stopRotation();zoom(1/1.2)});document.getElementById("zoom-reset").addEventListener("click",function(){settleUntangling();stopRotation();state.zoom=1;state.dx=0;state.dy=0;state.yaw=.35;state.pitch=-.22;paint()});
|
|
302
|
+
viewport.addEventListener("wheel",function(e){e.preventDefault();stopRotation();zoom(e.deltaY<0?1.1:1/1.1)},{passive:false});
|
|
303
|
+
viewport.addEventListener("pointerdown",function(e){if(e.target.closest(".node")||e.target.closest("button"))return;settleUntangling();stopRotation();drag={id:e.pointerId,x:e.clientX,y:e.clientY,dx:state.dx,dy:state.dy,yaw:state.yaw,pitch:state.pitch,pan:e.shiftKey||state.layout==="lanes"};viewport.setPointerCapture(e.pointerId)});viewport.addEventListener("pointermove",function(e){if(!drag||e.pointerId!==drag.id)return;var rect=svg.getBoundingClientRect(),scale=Math.max(.01,Math.min(rect.width/bounds.width,rect.height/bounds.height));if(drag.pan){state.dx=drag.dx+(e.clientX-drag.x)/scale;state.dy=drag.dy+(e.clientY-drag.y)/scale;transform()}else{state.yaw=drag.yaw+(e.clientX-drag.x)*.008;state.pitch=Math.max(-1.45,Math.min(1.45,drag.pitch+(e.clientY-drag.y)*.008));paint()}});viewport.addEventListener("pointerup",function(e){if(drag&&e.pointerId===drag.id)drag=null});viewport.addEventListener("pointercancel",function(){drag=null});viewport.addEventListener("lostpointercapture",function(){drag=null});
|
|
304
|
+
viewport.addEventListener("keydown",function(e){if(e.target!==viewport)return;var moved=true;settleUntangling();stopRotation();if(e.key==="+"||e.key==="=")zoom(1.2);else if(e.key==="-")zoom(1/1.2);else if(e.key==="ArrowLeft"){if(e.shiftKey||state.layout==="lanes")state.dx-=35;else moveCamera(-.12,0)}else if(e.key==="ArrowRight"){if(e.shiftKey||state.layout==="lanes")state.dx+=35;else moveCamera(.12,0)}else if(e.key==="ArrowUp"){if(e.shiftKey||state.layout==="lanes")state.dy-=35;else moveCamera(0,-.12)}else if(e.key==="ArrowDown"){if(e.shiftKey||state.layout==="lanes")state.dy+=35;else moveCamera(0,.12)}else if(e.key==="Escape")reset();else moved=false;if(moved){e.preventDefault();transform()}});
|
|
305
|
+
if(typeof document.addEventListener==="function")document.addEventListener("visibilitychange",function(){if(document.hidden){stopRotation();untangleMotion.pause()}});
|
|
306
|
+
if(motion&&typeof motion.addEventListener==="function")motion.addEventListener("change",function(){stopRotation();if(motion.matches)settleUntangling();updateUntangleAction(untangleMotion.getState())});
|
|
307
|
+
if(typeof IntersectionObserver==="function"){var visibilityObserver=new IntersectionObserver(function(entries){entries.forEach(function(entry){if(entry.target!==viewport)return;mapVisible=entry.isIntersecting;if(!mapVisible){stopRotation();untangleMotion.pause()}})},{threshold:0});visibilityObserver.observe(viewport)}
|
|
308
|
+
if(typeof addEventListener==="function")addEventListener("pagehide",function(){stopRotation();untangleMotion.pause()});
|
|
309
|
+
document.getElementById("ready").textContent="Local 3D map ready. No network connection.";
|
|
310
|
+
})();
|
|
311
|
+
`;
|
|
312
|
+
|
|
313
|
+
function hash(value: string): string {
|
|
314
|
+
return createHash("sha256").update(value).digest("base64");
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** Static assets are CSP-hashed. Untrusted graph text is inert base64 and textContent only. */
|
|
318
|
+
export function createFeatureMapHtml(graph: FeatureMapGraphV1): string {
|
|
319
|
+
const encoded = Buffer.from(JSON.stringify(graph), "utf8").toString("base64");
|
|
320
|
+
const csp = [
|
|
321
|
+
"default-src 'none'",
|
|
322
|
+
`script-src 'sha256-${hash(SCRIPT)}'`,
|
|
323
|
+
`style-src 'sha256-${hash(STYLE)}'`,
|
|
324
|
+
"connect-src 'none'",
|
|
325
|
+
"img-src 'none'",
|
|
326
|
+
"font-src 'none'",
|
|
327
|
+
"object-src 'none'",
|
|
328
|
+
"base-uri 'none'",
|
|
329
|
+
"form-action 'none'",
|
|
330
|
+
].join("; ");
|
|
331
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="referrer" content="no-referrer"><meta http-equiv="Content-Security-Policy" content="${csp}"><title>Untangle · Feature map</title><style>${STYLE}</style></head><body>
|
|
332
|
+
<a class="skip" href="#viewport">Skip to feature map</a>
|
|
333
|
+
<header><div class="brand"><svg aria-hidden="true" viewBox="0 0 48 48" fill="none" stroke="#b44d1f" stroke-width="2.4"><circle cx="23" cy="23" r="17"/><path d="M8 14c11-7 31 7 30 16M8 23c9-7 24-3 31 7M14 8c-4 10 6 28 15 31M23 6c-5 13 3 25 12 30M9 32c5-10 22-17 29-15M36 36c7 2 8 6 6 9"/></svg><div><h1>Untangle · Feature map</h1><p>Trace declared features, code, tests and ownership.</p></div></div><p id="snapshot" class="snapshot">Local source snapshot</p></header>
|
|
334
|
+
<section class="toolbar" aria-label="Feature map controls"><div class="field field-search"><label for="search">Find a feature, path or owner</label><input id="search" type="search" placeholder="e.g. search or src/account.ts" autocomplete="off"></div><div class="field"><label for="kind">Layer</label><select id="kind"><option value="all">All layers</option><option value="feature">Features</option><option value="code">Code</option><option value="test">Tests</option><option value="owner">Ownership</option><option value="intent">Vision / Spec</option><option value="unmapped">Unassigned</option></select></div><div class="field"><label for="grouping">Untangle by</label><select id="grouping" aria-describedby="grouping-help">${GROUPINGS.map((choice) => `<option value="${choice.id}">${choice.label}</option>`).join("")}</select></div><button id="isolate" type="button" aria-pressed="false">Direct neighbors only</button><button id="layout" type="button">Arrange by layer</button><button id="rotation" type="button" aria-pressed="false" aria-describedby="motion-note">Start rotation</button><button id="reset" type="button">Reset filters</button></section>
|
|
335
|
+
<p id="grouping-help" class="sr">Choose a grouping independently of the layer filter. Code and test areas use file directories. Ownership and document context follow declared feature links; they do not infer file ownership or specification conformance. Changing the grouping returns to the tangle without starting motion.</p><p id="scope" class="scope" role="status">Loading source-bound snapshot</p><main class="workspace"><section id="untangle-view" class="map-region" aria-label="3D feature and code wool map"><div class="legend" aria-label="Legend"><span>Feature</span><span class="code">Code</span><span class="test">Test</span><span class="owner">Owner</span><span class="intent">Intent</span><span class="unmapped">Unassigned</span></div><div id="viewport" tabindex="0" role="region" aria-label="Interactive 3D feature map" aria-describedby="help"><svg id="map" xmlns="http://www.w3.org/2000/svg" role="group" aria-label="Feature, code and ownership relationships"></svg><div id="empty" class="empty" hidden><h2 id="empty-title"></h2><p id="empty-text"></p></div></div><div class="zoom" aria-label="Map zoom"><button id="zoom-out" type="button" aria-label="Zoom out">−</button><button id="zoom-reset" type="button">1:1</button><button id="zoom-in" type="button" aria-label="Zoom in">+</button></div><button id="untangle" class="untangle-action" type="button" aria-describedby="untangle-note">Untangle by feature</button><p id="untangle-note" class="untangle-note" role="status" aria-live="polite">Group the wool map by declared feature scopes. Code and metrics are unchanged.</p><p id="motion-note" class="sr">Rotation starts only on request, pauses after 90 seconds or when you interact, and stays off with reduced motion.</p><p id="help" class="sr">Drag or use arrow keys to rotate the 3D map. Hold Shift to pan. Use plus and minus to zoom. Select nodes with Tab and Enter; the same nodes are available in the list.</p></section><aside class="aside" aria-label="Details and accessible node list"><section id="detail" aria-live="polite"><h2>Follow a relationship. Inspect the full scope.</h2><p>Select a feature or file to inspect its complete measurements, test evidence and relationships.</p><p>Feature node size shows measured complexity. Spatial proximity is a layout choice, not evidence of semantic similarity or ownership.</p></section><details><summary>Measurement limits and open evidence</summary><ul id="issues"></ul></details><details id="group-index"><summary>Groups <span id="group-count"></span></summary><p id="group-note"></p><ul id="group-list"></ul></details><section><h3>Node list <span id="visible-count" class="muted"></span></h3><p id="list-note"></p><div id="node-list" class="node-list"></div></section></aside></main><footer><span id="ready">Local HTML · no external services</span> · Feature dependencies are declarations, not runtime calls. <span id="selected-status" class="sr" aria-live="polite"></span></footer><script type="application/json" id="map-data">${encoded}</script><script>${SCRIPT}</script></body></html>\n`;
|
|
336
|
+
}
|