@flyingrobots/graft 0.6.1 → 0.7.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/CHANGELOG.md +135 -0
- package/README.md +1 -1
- package/dist/adapters/json-text-decoder.d.ts +3 -0
- package/dist/adapters/json-text-decoder.d.ts.map +1 -0
- package/dist/adapters/json-text-decoder.js +12 -0
- package/dist/adapters/json-text-decoder.js.map +1 -0
- package/dist/adapters/node-paths.d.ts +3 -0
- package/dist/adapters/node-paths.d.ts.map +1 -0
- package/dist/adapters/node-paths.js +29 -0
- package/dist/adapters/node-paths.js.map +1 -0
- package/dist/adapters/repo-paths.d.ts.map +1 -1
- package/dist/adapters/repo-paths.js +40 -5
- package/dist/adapters/repo-paths.js.map +1 -1
- package/dist/api/tool-bridge.d.ts +1 -1
- package/dist/api/tool-bridge.d.ts.map +1 -1
- package/dist/api/tool-bridge.js +1 -1
- package/dist/api/tool-bridge.js.map +1 -1
- package/dist/cli/cli-error.d.ts.map +1 -1
- package/dist/cli/cli-error.js +47 -10
- package/dist/cli/cli-error.js.map +1 -1
- package/dist/cli/command-parser.d.ts +12 -3
- package/dist/cli/command-parser.d.ts.map +1 -1
- package/dist/cli/command-parser.js +161 -2
- package/dist/cli/command-parser.js.map +1 -1
- package/dist/cli/daemon-status-model.d.ts +87 -0
- package/dist/cli/daemon-status-model.d.ts.map +1 -0
- package/dist/cli/daemon-status-model.js +142 -0
- package/dist/cli/daemon-status-model.js.map +1 -0
- package/dist/cli/daemon-status-render.d.ts +3 -0
- package/dist/cli/daemon-status-render.d.ts.map +1 -0
- package/dist/cli/daemon-status-render.js +100 -0
- package/dist/cli/daemon-status-render.js.map +1 -0
- package/dist/cli/daemon-status.d.ts +7 -0
- package/dist/cli/daemon-status.d.ts.map +1 -0
- package/dist/cli/daemon-status.js +79 -0
- package/dist/cli/daemon-status.js.map +1 -0
- package/dist/cli/git-graft-enhance-model.d.ts +67 -0
- package/dist/cli/git-graft-enhance-model.d.ts.map +1 -0
- package/dist/cli/git-graft-enhance-model.js +55 -0
- package/dist/cli/git-graft-enhance-model.js.map +1 -0
- package/dist/cli/git-graft-enhance-render.d.ts +3 -0
- package/dist/cli/git-graft-enhance-render.d.ts.map +1 -0
- package/dist/cli/git-graft-enhance-render.js +29 -0
- package/dist/cli/git-graft-enhance-render.js.map +1 -0
- package/dist/cli/git-graft-enhance.d.ts +14 -0
- package/dist/cli/git-graft-enhance.d.ts.map +1 -0
- package/dist/cli/git-graft-enhance.js +29 -0
- package/dist/cli/git-graft-enhance.js.map +1 -0
- package/dist/cli/index-cmd.d.ts.map +1 -1
- package/dist/cli/index-cmd.js +18 -21
- package/dist/cli/index-cmd.js.map +1 -1
- package/dist/cli/index-model.d.ts +5 -9
- package/dist/cli/index-model.d.ts.map +1 -1
- package/dist/cli/index-model.js +20 -18
- package/dist/cli/index-model.js.map +1 -1
- package/dist/cli/init-client-config.d.ts +12 -7
- package/dist/cli/init-client-config.d.ts.map +1 -1
- package/dist/cli/init-client-config.js +105 -43
- package/dist/cli/init-client-config.js.map +1 -1
- package/dist/cli/init-model.d.ts +9 -2
- package/dist/cli/init-model.d.ts.map +1 -1
- package/dist/cli/init-model.js +52 -4
- package/dist/cli/init-model.js.map +1 -1
- package/dist/cli/init-render.d.ts.map +1 -1
- package/dist/cli/init-render.js +2 -2
- package/dist/cli/init-render.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +11 -9
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/json-document.d.ts +5 -0
- package/dist/cli/json-document.d.ts.map +1 -1
- package/dist/cli/json-document.js +9 -0
- package/dist/cli/json-document.js.map +1 -1
- package/dist/cli/main.d.ts +7 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +49 -7
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/migrate-local-history.d.ts.map +1 -1
- package/dist/cli/migrate-local-history.js +3 -2
- package/dist/cli/migrate-local-history.js.map +1 -1
- package/dist/cli/peer-command.d.ts +1 -1
- package/dist/cli/peer-command.d.ts.map +1 -1
- package/dist/cli/peer-command.js +1 -1
- package/dist/cli/peer-command.js.map +1 -1
- package/dist/contracts/capabilities.d.ts +5 -5
- package/dist/contracts/capabilities.d.ts.map +1 -1
- package/dist/contracts/capabilities.js +89 -0
- package/dist/contracts/capabilities.js.map +1 -1
- package/dist/contracts/causal-ontology.d.ts +17 -17
- package/dist/contracts/json-object.d.ts +0 -1
- package/dist/contracts/json-object.d.ts.map +1 -1
- package/dist/contracts/json-object.js +0 -10
- package/dist/contracts/json-object.js.map +1 -1
- package/dist/contracts/output-schema-cli.d.ts +277 -25
- package/dist/contracts/output-schema-cli.d.ts.map +1 -1
- package/dist/contracts/output-schema-cli.js +35 -3
- package/dist/contracts/output-schema-cli.js.map +1 -1
- package/dist/contracts/output-schema-fragments.d.ts +212 -87
- package/dist/contracts/output-schema-fragments.d.ts.map +1 -1
- package/dist/contracts/output-schema-fragments.js +49 -2
- package/dist/contracts/output-schema-fragments.js.map +1 -1
- package/dist/contracts/output-schema-mcp.d.ts +372 -47
- package/dist/contracts/output-schema-mcp.d.ts.map +1 -1
- package/dist/contracts/output-schema-mcp.js +217 -1
- package/dist/contracts/output-schema-mcp.js.map +1 -1
- package/dist/contracts/output-schema-meta.d.ts +2 -2
- package/dist/contracts/output-schema-meta.d.ts.map +1 -1
- package/dist/contracts/output-schemas.d.ts +7 -7
- package/dist/contracts/output-schemas.d.ts.map +1 -1
- package/dist/contracts/output-schemas.js +294 -6
- package/dist/contracts/output-schemas.js.map +1 -1
- package/dist/git/diff.d.ts +11 -0
- package/dist/git/diff.d.ts.map +1 -1
- package/dist/git/diff.js +50 -6
- package/dist/git/diff.js.map +1 -1
- package/dist/mcp/burden.d.ts.map +1 -1
- package/dist/mcp/burden.js +9 -0
- package/dist/mcp/burden.js.map +1 -1
- package/dist/mcp/context.d.ts +3 -2
- package/dist/mcp/context.d.ts.map +1 -1
- package/dist/mcp/context.js +2 -37
- package/dist/mcp/context.js.map +1 -1
- package/dist/mcp/daemon-server.d.ts +2 -0
- package/dist/mcp/daemon-server.d.ts.map +1 -1
- package/dist/mcp/daemon-server.js +6 -1
- package/dist/mcp/daemon-server.js.map +1 -1
- package/dist/mcp/daemon-session-host.d.ts +1 -0
- package/dist/mcp/daemon-session-host.d.ts.map +1 -1
- package/dist/mcp/daemon-session-host.js +3 -0
- package/dist/mcp/daemon-session-host.js.map +1 -1
- package/dist/mcp/daemon-stdio-bridge.d.ts +1 -0
- package/dist/mcp/daemon-stdio-bridge.d.ts.map +1 -1
- package/dist/mcp/daemon-stdio-bridge.js +1 -0
- package/dist/mcp/daemon-stdio-bridge.js.map +1 -1
- package/dist/mcp/monitor-tick-job.d.ts +1 -0
- package/dist/mcp/monitor-tick-job.d.ts.map +1 -1
- package/dist/mcp/monitor-tick-job.js +84 -29
- package/dist/mcp/monitor-tick-job.js.map +1 -1
- package/dist/mcp/monitor-types.d.ts +1 -1
- package/dist/mcp/monitor-types.d.ts.map +1 -1
- package/dist/mcp/persisted-local-history-graph.d.ts +2 -2
- package/dist/mcp/persisted-local-history-graph.d.ts.map +1 -1
- package/dist/mcp/persisted-local-history-graph.js +3 -2
- package/dist/mcp/persisted-local-history-graph.js.map +1 -1
- package/dist/mcp/persisted-local-history.d.ts +5 -5
- package/dist/mcp/persisted-local-history.js +2 -2
- package/dist/mcp/persisted-local-history.js.map +1 -1
- package/dist/mcp/persistent-monitor-runtime.d.ts +1 -0
- package/dist/mcp/persistent-monitor-runtime.d.ts.map +1 -1
- package/dist/mcp/persistent-monitor-runtime.js +35 -0
- package/dist/mcp/persistent-monitor-runtime.js.map +1 -1
- package/dist/mcp/repo-tool-worker-context.d.ts.map +1 -1
- package/dist/mcp/repo-tool-worker-context.js +5 -2
- package/dist/mcp/repo-tool-worker-context.js.map +1 -1
- package/dist/mcp/server-context.d.ts.map +1 -1
- package/dist/mcp/server-context.js +13 -0
- package/dist/mcp/server-context.js.map +1 -1
- package/dist/mcp/server-tool-access.d.ts +1 -1
- package/dist/mcp/server-tool-access.d.ts.map +1 -1
- package/dist/mcp/server-tool-access.js +3 -1
- package/dist/mcp/server-tool-access.js.map +1 -1
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +5 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-registry.d.ts.map +1 -1
- package/dist/mcp/tool-registry.js +18 -0
- package/dist/mcp/tool-registry.js.map +1 -1
- package/dist/mcp/tools/code-find.d.ts.map +1 -1
- package/dist/mcp/tools/code-find.js +20 -0
- package/dist/mcp/tools/code-find.js.map +1 -1
- package/dist/mcp/tools/code-show.d.ts.map +1 -1
- package/dist/mcp/tools/code-show.js +24 -0
- package/dist/mcp/tools/code-show.js.map +1 -1
- package/dist/mcp/tools/diagnostic-models.d.ts +2 -0
- package/dist/mcp/tools/diagnostic-models.d.ts.map +1 -1
- package/dist/mcp/tools/doctor.d.ts.map +1 -1
- package/dist/mcp/tools/doctor.js +18 -1
- package/dist/mcp/tools/doctor.js.map +1 -1
- package/dist/mcp/tools/export-surface-diff.d.ts +3 -0
- package/dist/mcp/tools/export-surface-diff.d.ts.map +1 -0
- package/dist/mcp/tools/export-surface-diff.js +24 -0
- package/dist/mcp/tools/export-surface-diff.js.map +1 -0
- package/dist/mcp/tools/file-outline.js +1 -1
- package/dist/mcp/tools/file-outline.js.map +1 -1
- package/dist/mcp/tools/graft-edit.d.ts +3 -0
- package/dist/mcp/tools/graft-edit.d.ts.map +1 -0
- package/dist/mcp/tools/graft-edit.js +192 -0
- package/dist/mcp/tools/graft-edit.js.map +1 -0
- package/dist/mcp/tools/knowledge-map.d.ts +3 -0
- package/dist/mcp/tools/knowledge-map.d.ts.map +1 -0
- package/dist/mcp/tools/knowledge-map.js +31 -0
- package/dist/mcp/tools/knowledge-map.js.map +1 -0
- package/dist/mcp/tools/monitor-nudge.d.ts +3 -0
- package/dist/mcp/tools/monitor-nudge.d.ts.map +1 -0
- package/dist/mcp/tools/monitor-nudge.js +17 -0
- package/dist/mcp/tools/monitor-nudge.js.map +1 -0
- package/dist/mcp/tools/precision-warp.d.ts +3 -3
- package/dist/mcp/tools/precision-warp.d.ts.map +1 -1
- package/dist/mcp/tools/precision-warp.js +24 -15
- package/dist/mcp/tools/precision-warp.js.map +1 -1
- package/dist/mcp/tools/refactor-difficulty.d.ts +3 -0
- package/dist/mcp/tools/refactor-difficulty.d.ts.map +1 -0
- package/dist/mcp/tools/refactor-difficulty.js +36 -0
- package/dist/mcp/tools/refactor-difficulty.js.map +1 -0
- package/dist/mcp/tools/safe-read.js +2 -2
- package/dist/mcp/tools/safe-read.js.map +1 -1
- package/dist/mcp/tools/structural-blame.d.ts +3 -0
- package/dist/mcp/tools/structural-blame.d.ts.map +1 -0
- package/dist/mcp/tools/structural-blame.js +44 -0
- package/dist/mcp/tools/structural-blame.js.map +1 -0
- package/dist/mcp/tools/structural-churn.d.ts +3 -0
- package/dist/mcp/tools/structural-churn.d.ts.map +1 -0
- package/dist/mcp/tools/structural-churn.js +28 -0
- package/dist/mcp/tools/structural-churn.js.map +1 -0
- package/dist/mcp/tools/structural-log.d.ts +3 -0
- package/dist/mcp/tools/structural-log.d.ts.map +1 -0
- package/dist/mcp/tools/structural-log.js +38 -0
- package/dist/mcp/tools/structural-log.js.map +1 -0
- package/dist/mcp/tools/structural-review.d.ts +3 -0
- package/dist/mcp/tools/structural-review.d.ts.map +1 -0
- package/dist/mcp/tools/structural-review.js +55 -0
- package/dist/mcp/tools/structural-review.js.map +1 -0
- package/dist/mcp/warp-pool.d.ts +4 -4
- package/dist/mcp/warp-pool.d.ts.map +1 -1
- package/dist/mcp/warp-pool.js.map +1 -1
- package/dist/mcp/workspace-router-model.d.ts +2 -2
- package/dist/mcp/workspace-router-model.d.ts.map +1 -1
- package/dist/mcp/workspace-router-runtime.d.ts +3 -3
- package/dist/mcp/workspace-router-runtime.d.ts.map +1 -1
- package/dist/mcp/workspace-router-runtime.js +4 -1
- package/dist/mcp/workspace-router-runtime.js.map +1 -1
- package/dist/mcp/workspace-router.d.ts +3 -2
- package/dist/mcp/workspace-router.d.ts.map +1 -1
- package/dist/mcp/workspace-router.js +6 -0
- package/dist/mcp/workspace-router.js.map +1 -1
- package/dist/operations/adaptive-projection.d.ts +22 -0
- package/dist/operations/adaptive-projection.d.ts.map +1 -0
- package/dist/operations/adaptive-projection.js +36 -0
- package/dist/operations/adaptive-projection.js.map +1 -0
- package/dist/operations/agent-handoff.d.ts +25 -0
- package/dist/operations/agent-handoff.d.ts.map +1 -0
- package/dist/operations/agent-handoff.js +36 -0
- package/dist/operations/agent-handoff.js.map +1 -0
- package/dist/operations/capture-range.d.ts +33 -0
- package/dist/operations/capture-range.d.ts.map +1 -0
- package/dist/operations/capture-range.js +45 -0
- package/dist/operations/capture-range.js.map +1 -0
- package/dist/operations/conversation-primer.d.ts +27 -0
- package/dist/operations/conversation-primer.d.ts.map +1 -0
- package/dist/operations/conversation-primer.js +52 -0
- package/dist/operations/conversation-primer.js.map +1 -0
- package/dist/operations/cross-session-resume.d.ts +28 -0
- package/dist/operations/cross-session-resume.d.ts.map +1 -0
- package/dist/operations/cross-session-resume.js +79 -0
- package/dist/operations/cross-session-resume.js.map +1 -0
- package/dist/operations/deterministic-replay.d.ts +39 -0
- package/dist/operations/deterministic-replay.d.ts.map +1 -0
- package/dist/operations/deterministic-replay.js +90 -0
- package/dist/operations/deterministic-replay.js.map +1 -0
- package/dist/operations/export-surface-diff.d.ts +36 -0
- package/dist/operations/export-surface-diff.d.ts.map +1 -0
- package/dist/operations/export-surface-diff.js +298 -0
- package/dist/operations/export-surface-diff.js.map +1 -0
- package/dist/operations/footprint-parallelism.d.ts +25 -0
- package/dist/operations/footprint-parallelism.d.ts.map +1 -0
- package/dist/operations/footprint-parallelism.js +79 -0
- package/dist/operations/footprint-parallelism.js.map +1 -0
- package/dist/operations/graft-diff.d.ts.map +1 -1
- package/dist/operations/graft-diff.js +14 -7
- package/dist/operations/graft-diff.js.map +1 -1
- package/dist/operations/horizon-of-readability.d.ts +23 -0
- package/dist/operations/horizon-of-readability.d.ts.map +1 -0
- package/dist/operations/horizon-of-readability.js +39 -0
- package/dist/operations/horizon-of-readability.js.map +1 -0
- package/dist/operations/import-reference-impact.d.ts +13 -0
- package/dist/operations/import-reference-impact.d.ts.map +1 -0
- package/dist/operations/import-reference-impact.js +101 -0
- package/dist/operations/import-reference-impact.js.map +1 -0
- package/dist/operations/knowledge-map.d.ts +30 -0
- package/dist/operations/knowledge-map.d.ts.map +1 -0
- package/dist/operations/knowledge-map.js +64 -0
- package/dist/operations/knowledge-map.js.map +1 -0
- package/dist/operations/observation-cache.d.ts +8 -2
- package/dist/operations/observation-cache.d.ts.map +1 -1
- package/dist/operations/observation-cache.js +17 -5
- package/dist/operations/observation-cache.js.map +1 -1
- package/dist/operations/projection-safety.d.ts +31 -0
- package/dist/operations/projection-safety.d.ts.map +1 -0
- package/dist/operations/projection-safety.js +77 -0
- package/dist/operations/projection-safety.js.map +1 -0
- package/dist/operations/repo-workspace.js +3 -3
- package/dist/operations/repo-workspace.js.map +1 -1
- package/dist/operations/semantic-drift.d.ts +27 -0
- package/dist/operations/semantic-drift.d.ts.map +1 -0
- package/dist/operations/semantic-drift.js +46 -0
- package/dist/operations/semantic-drift.js.map +1 -0
- package/dist/operations/session-filtration.d.ts +36 -0
- package/dist/operations/session-filtration.d.ts.map +1 -0
- package/dist/operations/session-filtration.js +48 -0
- package/dist/operations/session-filtration.js.map +1 -0
- package/dist/operations/session-replay.d.ts +17 -0
- package/dist/operations/session-replay.d.ts.map +1 -0
- package/dist/operations/session-replay.js +59 -0
- package/dist/operations/session-replay.js.map +1 -0
- package/dist/operations/sludge-detector.d.ts +45 -0
- package/dist/operations/sludge-detector.d.ts.map +1 -0
- package/dist/operations/sludge-detector.js +278 -0
- package/dist/operations/sludge-detector.js.map +1 -0
- package/dist/operations/structural-blame.d.ts +67 -0
- package/dist/operations/structural-blame.d.ts.map +1 -0
- package/dist/operations/structural-blame.js +111 -0
- package/dist/operations/structural-blame.js.map +1 -0
- package/dist/operations/structural-review.d.ts +47 -0
- package/dist/operations/structural-review.d.ts.map +1 -0
- package/dist/operations/structural-review.js +225 -0
- package/dist/operations/structural-review.js.map +1 -0
- package/dist/operations/teaching-hints.d.ts +18 -0
- package/dist/operations/teaching-hints.d.ts.map +1 -0
- package/dist/operations/teaching-hints.js +35 -0
- package/dist/operations/teaching-hints.js.map +1 -0
- package/dist/parser/diff.d.ts +2 -0
- package/dist/parser/diff.d.ts.map +1 -1
- package/dist/parser/diff.js +7 -0
- package/dist/parser/diff.js.map +1 -1
- package/dist/ports/paths.d.ts +17 -0
- package/dist/ports/paths.d.ts.map +1 -0
- package/dist/ports/{warp.js → paths.js} +2 -2
- package/dist/ports/paths.js.map +1 -0
- package/dist/warp/ast-emitter.d.ts +28 -0
- package/dist/warp/ast-emitter.d.ts.map +1 -0
- package/dist/warp/ast-emitter.js +90 -0
- package/dist/warp/ast-emitter.js.map +1 -0
- package/dist/warp/ast-import-resolver.d.ts +13 -0
- package/dist/warp/ast-import-resolver.d.ts.map +1 -0
- package/dist/warp/ast-import-resolver.js +259 -0
- package/dist/warp/ast-import-resolver.js.map +1 -0
- package/dist/warp/commit-meta.d.ts +8 -0
- package/dist/warp/commit-meta.d.ts.map +1 -0
- package/dist/warp/commit-meta.js +13 -0
- package/dist/warp/commit-meta.js.map +1 -0
- package/dist/warp/context.d.ts +10 -0
- package/dist/warp/context.d.ts.map +1 -0
- package/dist/warp/context.js +26 -0
- package/dist/warp/context.js.map +1 -0
- package/dist/warp/dead-symbols.d.ts +40 -0
- package/dist/warp/dead-symbols.d.ts.map +1 -0
- package/dist/warp/dead-symbols.js +127 -0
- package/dist/warp/dead-symbols.js.map +1 -0
- package/dist/warp/drift-sentinel.d.ts +30 -0
- package/dist/warp/drift-sentinel.d.ts.map +1 -0
- package/dist/warp/drift-sentinel.js +65 -0
- package/dist/warp/drift-sentinel.js.map +1 -0
- package/dist/warp/index-head.d.ts +32 -0
- package/dist/warp/index-head.d.ts.map +1 -0
- package/dist/warp/index-head.js +245 -0
- package/dist/warp/index-head.js.map +1 -0
- package/dist/warp/observers.d.ts +6 -6
- package/dist/warp/observers.d.ts.map +1 -1
- package/dist/warp/observers.js +5 -4
- package/dist/warp/observers.js.map +1 -1
- package/dist/warp/open.d.ts +5 -4
- package/dist/warp/open.d.ts.map +1 -1
- package/dist/warp/open.js +24 -49
- package/dist/warp/open.js.map +1 -1
- package/dist/warp/outline-diff-trailer.d.ts +26 -0
- package/dist/warp/outline-diff-trailer.d.ts.map +1 -0
- package/dist/warp/outline-diff-trailer.js +68 -0
- package/dist/warp/outline-diff-trailer.js.map +1 -0
- package/dist/warp/refactor-difficulty.d.ts +38 -0
- package/dist/warp/refactor-difficulty.d.ts.map +1 -0
- package/dist/warp/refactor-difficulty.js +169 -0
- package/dist/warp/refactor-difficulty.js.map +1 -0
- package/dist/warp/references.d.ts +22 -0
- package/dist/warp/references.d.ts.map +1 -0
- package/dist/warp/references.js +57 -0
- package/dist/warp/references.js.map +1 -0
- package/dist/warp/stale-docs.d.ts +56 -0
- package/dist/warp/stale-docs.d.ts.map +1 -0
- package/dist/warp/stale-docs.js +149 -0
- package/dist/warp/stale-docs.js.map +1 -0
- package/dist/warp/structural-drift-detection.d.ts +49 -0
- package/dist/warp/structural-drift-detection.d.ts.map +1 -0
- package/dist/warp/structural-drift-detection.js +51 -0
- package/dist/warp/structural-drift-detection.js.map +1 -0
- package/dist/warp/structural-queries.d.ts +49 -0
- package/dist/warp/structural-queries.d.ts.map +1 -0
- package/dist/warp/structural-queries.js +175 -0
- package/dist/warp/structural-queries.js.map +1 -0
- package/dist/warp/symbol-timeline.d.ts +34 -0
- package/dist/warp/symbol-timeline.d.ts.map +1 -0
- package/dist/warp/symbol-timeline.js +127 -0
- package/dist/warp/symbol-timeline.js.map +1 -0
- package/dist/warp/traverse-hydrate.d.ts +23 -0
- package/dist/warp/traverse-hydrate.d.ts.map +1 -0
- package/dist/warp/traverse-hydrate.js +39 -0
- package/dist/warp/traverse-hydrate.js.map +1 -0
- package/dist/warp/warp-reference-count.d.ts +19 -0
- package/dist/warp/warp-reference-count.d.ts.map +1 -0
- package/dist/warp/warp-reference-count.js +32 -0
- package/dist/warp/warp-reference-count.js.map +1 -0
- package/dist/warp/warp-structural-blame.d.ts +20 -0
- package/dist/warp/warp-structural-blame.d.ts.map +1 -0
- package/dist/warp/warp-structural-blame.js +43 -0
- package/dist/warp/warp-structural-blame.js.map +1 -0
- package/dist/warp/warp-structural-churn.d.ts +30 -0
- package/dist/warp/warp-structural-churn.d.ts.map +1 -0
- package/dist/warp/warp-structural-churn.js +213 -0
- package/dist/warp/warp-structural-churn.js.map +1 -0
- package/dist/warp/warp-structural-log.d.ts +35 -0
- package/dist/warp/warp-structural-log.d.ts.map +1 -0
- package/dist/warp/warp-structural-log.js +104 -0
- package/dist/warp/warp-structural-log.js.map +1 -0
- package/docs/CLI.md +68 -4
- package/docs/MCP.md +23 -0
- package/docs/SETUP.md +101 -20
- package/package.json +5 -3
- package/src/adapters/json-text-decoder.ts +11 -0
- package/src/adapters/node-paths.ts +35 -0
- package/src/adapters/repo-paths.ts +45 -4
- package/src/api/tool-bridge.ts +2 -1
- package/src/cli/cli-error.ts +49 -10
- package/src/cli/command-parser.ts +185 -3
- package/src/cli/daemon-status-model.ts +238 -0
- package/src/cli/daemon-status-render.ts +102 -0
- package/src/cli/daemon-status.ts +100 -0
- package/src/cli/git-graft-enhance-model.ts +131 -0
- package/src/cli/git-graft-enhance-render.ts +33 -0
- package/src/cli/git-graft-enhance.ts +54 -0
- package/src/cli/index-cmd.ts +18 -22
- package/src/cli/index-model.ts +21 -22
- package/src/cli/init-client-config.ts +167 -38
- package/src/cli/init-model.ts +57 -2
- package/src/cli/init-render.ts +2 -2
- package/src/cli/init.ts +11 -9
- package/src/cli/json-document.ts +11 -0
- package/src/cli/main.ts +53 -6
- package/src/cli/migrate-local-history.ts +3 -2
- package/src/cli/peer-command.ts +2 -1
- package/src/contracts/capabilities.ts +90 -0
- package/src/contracts/json-object.ts +1 -11
- package/src/contracts/output-schema-cli.ts +36 -3
- package/src/contracts/output-schema-fragments.ts +52 -2
- package/src/contracts/output-schema-mcp.ts +219 -0
- package/src/contracts/output-schemas.ts +300 -6
- package/src/git/diff.ts +61 -0
- package/src/mcp/burden.ts +9 -0
- package/src/mcp/context.ts +5 -42
- package/src/mcp/daemon-server.ts +8 -1
- package/src/mcp/daemon-session-host.ts +4 -0
- package/src/mcp/daemon-stdio-bridge.ts +2 -0
- package/src/mcp/monitor-tick-job.ts +90 -39
- package/src/mcp/monitor-types.ts +1 -1
- package/src/mcp/persisted-local-history-graph.ts +5 -4
- package/src/mcp/persisted-local-history.ts +2 -2
- package/src/mcp/persistent-monitor-runtime.ts +37 -0
- package/src/mcp/repo-tool-worker-context.ts +5 -2
- package/src/mcp/server-context.ts +15 -2
- package/src/mcp/server-tool-access.ts +4 -1
- package/src/mcp/server.ts +8 -3
- package/src/mcp/tool-registry.ts +18 -0
- package/src/mcp/tools/code-find.ts +23 -0
- package/src/mcp/tools/code-show.ts +27 -0
- package/src/mcp/tools/diagnostic-models.ts +2 -0
- package/src/mcp/tools/doctor.ts +18 -1
- package/src/mcp/tools/export-surface-diff.ts +26 -0
- package/src/mcp/tools/file-outline.ts +1 -1
- package/src/mcp/tools/graft-edit.ts +276 -0
- package/src/mcp/tools/knowledge-map.ts +34 -0
- package/src/mcp/tools/monitor-nudge.ts +19 -0
- package/src/mcp/tools/precision-warp.ts +27 -16
- package/src/mcp/tools/refactor-difficulty.ts +42 -0
- package/src/mcp/tools/safe-read.ts +2 -2
- package/src/mcp/tools/structural-blame.ts +55 -0
- package/src/mcp/tools/structural-churn.ts +28 -0
- package/src/mcp/tools/structural-log.ts +41 -0
- package/src/mcp/tools/structural-review.ts +63 -0
- package/src/mcp/warp-pool.ts +6 -6
- package/src/mcp/workspace-router-model.ts +2 -2
- package/src/mcp/workspace-router-runtime.ts +11 -8
- package/src/mcp/workspace-router.ts +9 -2
- package/src/operations/adaptive-projection.ts +54 -0
- package/src/operations/agent-handoff.ts +59 -0
- package/src/operations/capture-range.ts +64 -0
- package/src/operations/conversation-primer.ts +82 -0
- package/src/operations/cross-session-resume.ts +104 -0
- package/src/operations/deterministic-replay.ts +143 -0
- package/src/operations/export-surface-diff.ts +355 -0
- package/src/operations/footprint-parallelism.ts +98 -0
- package/src/operations/graft-diff.ts +14 -7
- package/src/operations/horizon-of-readability.ts +60 -0
- package/src/operations/import-reference-impact.ts +143 -0
- package/src/operations/knowledge-map.ts +96 -0
- package/src/operations/observation-cache.ts +20 -4
- package/src/operations/projection-safety.ts +111 -0
- package/src/operations/repo-workspace.ts +3 -3
- package/src/operations/semantic-drift.ts +70 -0
- package/src/operations/session-filtration.ts +76 -0
- package/src/operations/session-replay.ts +73 -0
- package/src/operations/sludge-detector.ts +356 -0
- package/src/operations/structural-blame.ts +197 -0
- package/src/operations/structural-review.ts +317 -0
- package/src/operations/teaching-hints.ts +52 -0
- package/src/parser/diff.ts +7 -0
- package/src/ports/paths.ts +22 -0
- package/src/warp/ast-emitter.ts +133 -0
- package/src/warp/ast-import-resolver.ts +333 -0
- package/src/warp/commit-meta.ts +19 -0
- package/src/warp/context.ts +48 -0
- package/src/warp/dead-symbols.ts +174 -0
- package/src/warp/drift-sentinel.ts +101 -0
- package/src/warp/index-head.ts +348 -0
- package/src/warp/observers.ts +8 -7
- package/src/warp/open.ts +40 -66
- package/src/warp/outline-diff-trailer.ts +100 -0
- package/src/warp/plumbing.d.ts +11 -2
- package/src/warp/refactor-difficulty.ts +257 -0
- package/src/warp/references.ts +77 -0
- package/src/warp/stale-docs.ts +210 -0
- package/src/warp/structural-drift-detection.ts +97 -0
- package/src/warp/structural-queries.ts +258 -0
- package/src/warp/symbol-timeline.ts +209 -0
- package/src/warp/traverse-hydrate.ts +61 -0
- package/src/warp/warp-reference-count.ts +47 -0
- package/src/warp/warp-structural-blame.ts +65 -0
- package/src/warp/warp-structural-churn.ts +309 -0
- package/src/warp/warp-structural-log.ts +149 -0
- package/dist/ports/warp.d.ts +0 -45
- package/dist/ports/warp.d.ts.map +0 -1
- package/dist/ports/warp.js.map +0 -1
- package/dist/warp/identity-resolver.d.ts +0 -14
- package/dist/warp/identity-resolver.d.ts.map +0 -1
- package/dist/warp/identity-resolver.js +0 -31
- package/dist/warp/identity-resolver.js.map +0 -1
- package/dist/warp/indexer-git.d.ts +0 -22
- package/dist/warp/indexer-git.d.ts.map +0 -1
- package/dist/warp/indexer-git.js +0 -148
- package/dist/warp/indexer-git.js.map +0 -1
- package/dist/warp/indexer-graph.d.ts +0 -17
- package/dist/warp/indexer-graph.d.ts.map +0 -1
- package/dist/warp/indexer-graph.js +0 -179
- package/dist/warp/indexer-graph.js.map +0 -1
- package/dist/warp/indexer-model.d.ts +0 -51
- package/dist/warp/indexer-model.d.ts.map +0 -1
- package/dist/warp/indexer-model.js +0 -21
- package/dist/warp/indexer-model.js.map +0 -1
- package/dist/warp/indexer.d.ts +0 -9
- package/dist/warp/indexer.d.ts.map +0 -1
- package/dist/warp/indexer.js +0 -112
- package/dist/warp/indexer.js.map +0 -1
- package/dist/warp/symbol-identity.d.ts +0 -11
- package/dist/warp/symbol-identity.d.ts.map +0 -1
- package/dist/warp/symbol-identity.js +0 -67
- package/dist/warp/symbol-identity.js.map +0 -1
- package/src/ports/warp.ts +0 -55
- package/src/warp/identity-resolver.ts +0 -35
- package/src/warp/indexer-git.ts +0 -182
- package/src/warp/indexer-graph.ts +0 -276
- package/src/warp/indexer-model.ts +0 -69
- package/src/warp/indexer.ts +0 -186
- package/src/warp/symbol-identity.ts +0 -100
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import type { SyntaxNode } from "web-tree-sitter";
|
|
2
|
+
import { detectLang } from "../parser/lang.js";
|
|
3
|
+
import { extractOutlineForFile } from "../parser/outline.js";
|
|
4
|
+
import { parseStructuredTreeForFile } from "../parser/runtime.js";
|
|
5
|
+
import type { OutlineEntry } from "../parser/types.js";
|
|
6
|
+
import type { FileSystem } from "../ports/filesystem.js";
|
|
7
|
+
import type { GitClient } from "../ports/git.js";
|
|
8
|
+
|
|
9
|
+
export type SludgeSignalKind =
|
|
10
|
+
| "phantom_shape"
|
|
11
|
+
| "cast_density"
|
|
12
|
+
| "homeless_constructor"
|
|
13
|
+
| "free_function_data_behavior"
|
|
14
|
+
| "god_file";
|
|
15
|
+
|
|
16
|
+
export type SludgeSeverity = "low" | "medium" | "high";
|
|
17
|
+
|
|
18
|
+
export interface SludgeSignal {
|
|
19
|
+
readonly kind: SludgeSignalKind;
|
|
20
|
+
readonly severity: SludgeSeverity;
|
|
21
|
+
readonly message: string;
|
|
22
|
+
readonly line?: number;
|
|
23
|
+
readonly symbol?: string;
|
|
24
|
+
readonly evidence: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SludgeMetrics {
|
|
28
|
+
readonly typedefCount: number;
|
|
29
|
+
readonly typeCastCount: number;
|
|
30
|
+
readonly classCount: number;
|
|
31
|
+
readonly functionCount: number;
|
|
32
|
+
readonly symbolCount: number;
|
|
33
|
+
readonly homelessConstructorCount: number;
|
|
34
|
+
readonly freeFunctionDataBehaviorCount: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface SludgeFileReport {
|
|
38
|
+
readonly path: string;
|
|
39
|
+
readonly score: number;
|
|
40
|
+
readonly metrics: SludgeMetrics;
|
|
41
|
+
readonly signals: readonly SludgeSignal[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface SludgeReport {
|
|
45
|
+
readonly scannedFiles: number;
|
|
46
|
+
readonly filesWithSignals: number;
|
|
47
|
+
readonly totalSignals: number;
|
|
48
|
+
readonly score: number;
|
|
49
|
+
readonly files: readonly SludgeFileReport[];
|
|
50
|
+
readonly summary: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface DetectSludgeOptions {
|
|
54
|
+
readonly cwd: string;
|
|
55
|
+
readonly fs: FileSystem;
|
|
56
|
+
readonly git: GitClient;
|
|
57
|
+
readonly resolvePath: (filePath: string) => string;
|
|
58
|
+
readonly path?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface FunctionFact {
|
|
62
|
+
readonly name: string;
|
|
63
|
+
readonly line: number;
|
|
64
|
+
readonly firstParameterType: string | null;
|
|
65
|
+
readonly returnsPlainObject: boolean;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const CONSTRUCTOR_PREFIXES = ["build", "create", "make", "assemble"] as const;
|
|
69
|
+
|
|
70
|
+
function walk(node: SyntaxNode, visit: (node: SyntaxNode) => void): void {
|
|
71
|
+
visit(node);
|
|
72
|
+
for (const child of node.namedChildren) {
|
|
73
|
+
walk(child, visit);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function countOutlineEntries(
|
|
78
|
+
entries: readonly OutlineEntry[],
|
|
79
|
+
predicate: (entry: OutlineEntry) => boolean,
|
|
80
|
+
): number {
|
|
81
|
+
let count = 0;
|
|
82
|
+
for (const entry of entries) {
|
|
83
|
+
if (predicate(entry)) count++;
|
|
84
|
+
if (entry.children !== undefined) {
|
|
85
|
+
count += countOutlineEntries(entry.children, predicate);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return count;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function collectTypeNames(entries: readonly OutlineEntry[]): Set<string> {
|
|
92
|
+
const names = new Set<string>();
|
|
93
|
+
for (const entry of entries) {
|
|
94
|
+
if (entry.kind === "class" || entry.kind === "interface" || entry.kind === "type") {
|
|
95
|
+
names.add(entry.name);
|
|
96
|
+
}
|
|
97
|
+
if (entry.children !== undefined) {
|
|
98
|
+
for (const childName of collectTypeNames(entry.children)) {
|
|
99
|
+
names.add(childName);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return names;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function startsWithConstructorPrefix(name: string): boolean {
|
|
107
|
+
const lower = name.toLowerCase();
|
|
108
|
+
return CONSTRUCTOR_PREFIXES.some((prefix) => lower.startsWith(prefix) && lower.length > prefix.length);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function isPlainObjectExpression(node: SyntaxNode | null): boolean {
|
|
112
|
+
if (node === null) return false;
|
|
113
|
+
if (node.type === "object") return true;
|
|
114
|
+
if (node.type !== "parenthesized_expression") return false;
|
|
115
|
+
return node.namedChildren.some((child) => child.type === "object");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function returnsPlainObject(node: SyntaxNode): boolean {
|
|
119
|
+
const body = node.childForFieldName("body");
|
|
120
|
+
if (isPlainObjectExpression(body)) return true;
|
|
121
|
+
|
|
122
|
+
let found = false;
|
|
123
|
+
const searchRoot = body ?? node;
|
|
124
|
+
walk(searchRoot, (child) => {
|
|
125
|
+
if (found || child.type !== "return_statement") return;
|
|
126
|
+
found = isPlainObjectExpression(child.namedChildren[0] ?? null);
|
|
127
|
+
});
|
|
128
|
+
return found;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function normalizedTypeName(typeAnnotation: SyntaxNode | null): string | null {
|
|
132
|
+
if (typeAnnotation === null) return null;
|
|
133
|
+
let text = typeAnnotation.text.trim();
|
|
134
|
+
if (text.startsWith(":")) {
|
|
135
|
+
text = text.slice(1).trim();
|
|
136
|
+
}
|
|
137
|
+
let end = text.length;
|
|
138
|
+
for (let index = 0; index < text.length; index++) {
|
|
139
|
+
const char = text[index];
|
|
140
|
+
if (char === "<" || char === " " || char === "|" || char === "&" || char === "[" || char === ".") {
|
|
141
|
+
end = index;
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const name = text.slice(0, end).trim();
|
|
146
|
+
return name.length > 0 ? name : null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function firstParameterType(functionNode: SyntaxNode): string | null {
|
|
150
|
+
const parameters = functionNode.childForFieldName("parameters");
|
|
151
|
+
const firstParameter = parameters?.namedChildren[0];
|
|
152
|
+
if (firstParameter === undefined) return null;
|
|
153
|
+
return normalizedTypeName(firstParameter.childForFieldName("type"));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function functionFact(name: string, node: SyntaxNode): FunctionFact {
|
|
157
|
+
return {
|
|
158
|
+
name,
|
|
159
|
+
line: node.startPosition.row + 1,
|
|
160
|
+
firstParameterType: firstParameterType(node),
|
|
161
|
+
returnsPlainObject: returnsPlainObject(node),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function declarationFunctionFacts(node: SyntaxNode): FunctionFact[] {
|
|
166
|
+
if (node.type === "function_declaration" || node.type === "generator_function_declaration") {
|
|
167
|
+
const name = node.childForFieldName("name")?.text;
|
|
168
|
+
return name !== undefined ? [functionFact(name, node)] : [];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (node.type !== "lexical_declaration") return [];
|
|
172
|
+
|
|
173
|
+
const facts: FunctionFact[] = [];
|
|
174
|
+
for (const declarator of node.namedChildren) {
|
|
175
|
+
if (declarator.type !== "variable_declarator") continue;
|
|
176
|
+
const name = declarator.childForFieldName("name")?.text;
|
|
177
|
+
const value = declarator.childForFieldName("value");
|
|
178
|
+
if (name === undefined || value === null) continue;
|
|
179
|
+
if (value.type === "arrow_function" || value.type === "function") {
|
|
180
|
+
facts.push(functionFact(name, value));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return facts;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function topLevelFunctionFacts(root: SyntaxNode): FunctionFact[] {
|
|
187
|
+
const facts: FunctionFact[] = [];
|
|
188
|
+
for (const child of root.namedChildren) {
|
|
189
|
+
if (child.type === "export_statement") {
|
|
190
|
+
for (const exportedChild of child.namedChildren) {
|
|
191
|
+
facts.push(...declarationFunctionFacts(exportedChild));
|
|
192
|
+
}
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
facts.push(...declarationFunctionFacts(child));
|
|
196
|
+
}
|
|
197
|
+
return facts;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function severityScore(severity: SludgeSeverity): number {
|
|
201
|
+
if (severity === "high") return 3;
|
|
202
|
+
if (severity === "medium") return 2;
|
|
203
|
+
return 1;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function containsTypeTag(comment: string): boolean {
|
|
207
|
+
return comment.includes("@type ") || comment.includes("@type{") || comment.includes("@type\t");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function buildSummary(report: Omit<SludgeReport, "summary">): string {
|
|
211
|
+
if (report.scannedFiles === 0) {
|
|
212
|
+
return "No supported source files scanned.";
|
|
213
|
+
}
|
|
214
|
+
if (report.totalSignals === 0) {
|
|
215
|
+
return `No sludge signals found across ${String(report.scannedFiles)} files.`;
|
|
216
|
+
}
|
|
217
|
+
return `${String(report.totalSignals)} sludge signals across ${String(report.filesWithSignals)} of ${String(report.scannedFiles)} scanned files.`;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function analyzeSludgeFile(filePath: string, source: string): SludgeFileReport | null {
|
|
221
|
+
if (detectLang(filePath) === null) return null;
|
|
222
|
+
|
|
223
|
+
const outline = extractOutlineForFile(filePath, source);
|
|
224
|
+
const parsed = parseStructuredTreeForFile(filePath, source);
|
|
225
|
+
if (outline === null || parsed === null) return null;
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
let typedefCount = 0;
|
|
229
|
+
let typeCastCount = 0;
|
|
230
|
+
for (const child of parsed.root.children) {
|
|
231
|
+
walk(child, (node) => {
|
|
232
|
+
if (node.type !== "comment") return;
|
|
233
|
+
if (node.text.includes("@typedef")) typedefCount++;
|
|
234
|
+
if (containsTypeTag(node.text)) typeCastCount++;
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const typeNames = collectTypeNames(outline.entries);
|
|
239
|
+
const classCount = countOutlineEntries(outline.entries, (entry) => entry.kind === "class");
|
|
240
|
+
const functionCount = countOutlineEntries(outline.entries, (entry) => entry.kind === "function");
|
|
241
|
+
const symbolCount = countOutlineEntries(outline.entries, () => true);
|
|
242
|
+
const functions = topLevelFunctionFacts(parsed.root);
|
|
243
|
+
const signals: SludgeSignal[] = [];
|
|
244
|
+
|
|
245
|
+
if (typedefCount > 0 && typedefCount >= classCount) {
|
|
246
|
+
const severity: SludgeSeverity = typedefCount >= 3 && classCount === 0 ? "high" : "medium";
|
|
247
|
+
signals.push({
|
|
248
|
+
kind: "phantom_shape",
|
|
249
|
+
severity,
|
|
250
|
+
message: "JSDoc typedefs outnumber class declarations.",
|
|
251
|
+
evidence: `${String(typedefCount)} typedefs, ${String(classCount)} classes`,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (typeCastCount >= 3) {
|
|
256
|
+
signals.push({
|
|
257
|
+
kind: "cast_density",
|
|
258
|
+
severity: typeCastCount >= 6 ? "high" : "medium",
|
|
259
|
+
message: "Dense JSDoc type casts suggest the type system is being hand-held.",
|
|
260
|
+
evidence: `${String(typeCastCount)} @type comments`,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
let homelessConstructorCount = 0;
|
|
265
|
+
let freeFunctionDataBehaviorCount = 0;
|
|
266
|
+
for (const fact of functions) {
|
|
267
|
+
if (startsWithConstructorPrefix(fact.name) && fact.returnsPlainObject) {
|
|
268
|
+
homelessConstructorCount++;
|
|
269
|
+
signals.push({
|
|
270
|
+
kind: "homeless_constructor",
|
|
271
|
+
severity: "medium",
|
|
272
|
+
message: "Factory-like free function returns a plain object instead of owning behavior on a type.",
|
|
273
|
+
line: fact.line,
|
|
274
|
+
symbol: fact.name,
|
|
275
|
+
evidence: "returns object literal",
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (fact.firstParameterType !== null && typeNames.has(fact.firstParameterType)) {
|
|
280
|
+
freeFunctionDataBehaviorCount++;
|
|
281
|
+
signals.push({
|
|
282
|
+
kind: "free_function_data_behavior",
|
|
283
|
+
severity: "low",
|
|
284
|
+
message: "Free function takes a project type as its first parameter.",
|
|
285
|
+
line: fact.line,
|
|
286
|
+
symbol: fact.name,
|
|
287
|
+
evidence: `first parameter type ${fact.firstParameterType}`,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (symbolCount > 30) {
|
|
293
|
+
signals.push({
|
|
294
|
+
kind: "god_file",
|
|
295
|
+
severity: symbolCount > 60 ? "high" : "medium",
|
|
296
|
+
message: "Single file exposes a large number of structural symbols.",
|
|
297
|
+
evidence: `${String(symbolCount)} outline entries`,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const score = signals.reduce((sum, signal) => sum + severityScore(signal.severity), 0);
|
|
302
|
+
return {
|
|
303
|
+
path: filePath,
|
|
304
|
+
score,
|
|
305
|
+
metrics: {
|
|
306
|
+
typedefCount,
|
|
307
|
+
typeCastCount,
|
|
308
|
+
classCount,
|
|
309
|
+
functionCount,
|
|
310
|
+
symbolCount,
|
|
311
|
+
homelessConstructorCount,
|
|
312
|
+
freeFunctionDataBehaviorCount,
|
|
313
|
+
},
|
|
314
|
+
signals,
|
|
315
|
+
};
|
|
316
|
+
} finally {
|
|
317
|
+
parsed.delete();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export async function detectSludge(options: DetectSludgeOptions): Promise<SludgeReport> {
|
|
322
|
+
const args = ["ls-files"];
|
|
323
|
+
if (options.path !== undefined) {
|
|
324
|
+
args.push("--", options.path);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const result = await options.git.run({ cwd: options.cwd, args });
|
|
328
|
+
const candidatePaths = result.status === 0
|
|
329
|
+
? result.stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0)
|
|
330
|
+
: [];
|
|
331
|
+
|
|
332
|
+
const supportedPaths = candidatePaths.filter((filePath) => detectLang(filePath) !== null);
|
|
333
|
+
const files: SludgeFileReport[] = [];
|
|
334
|
+
for (const filePath of supportedPaths) {
|
|
335
|
+
const source = await options.fs.readFile(options.resolvePath(filePath), "utf-8").catch(() => null);
|
|
336
|
+
if (source === null) continue;
|
|
337
|
+
const report = analyzeSludgeFile(filePath, source);
|
|
338
|
+
if (report !== null && report.signals.length > 0) {
|
|
339
|
+
files.push(report);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
files.sort((left, right) => right.score - left.score || left.path.localeCompare(right.path));
|
|
344
|
+
const withoutSummary = {
|
|
345
|
+
scannedFiles: supportedPaths.length,
|
|
346
|
+
filesWithSignals: files.length,
|
|
347
|
+
totalSignals: files.reduce((sum, file) => sum + file.signals.length, 0),
|
|
348
|
+
score: files.reduce((sum, file) => sum + file.score, 0),
|
|
349
|
+
files,
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
return {
|
|
353
|
+
...withoutSummary,
|
|
354
|
+
summary: buildSummary(withoutSummary),
|
|
355
|
+
};
|
|
356
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Structural Blame — symbol-level blame: who last changed a symbol's
|
|
3
|
+
// signature, when it was created, and its full change history.
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
|
|
6
|
+
import { toJsonObject } from "./result-dto.js";
|
|
7
|
+
import type { JsonObject } from "../contracts/json-object.js";
|
|
8
|
+
|
|
9
|
+
// ---- Public types ---------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
export interface CommitInfo {
|
|
12
|
+
readonly sha: string;
|
|
13
|
+
readonly author: string;
|
|
14
|
+
readonly date: string;
|
|
15
|
+
readonly message: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface LastSignatureChange extends CommitInfo {
|
|
19
|
+
readonly previousSignature?: string | undefined;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface BlameHistoryEntry {
|
|
23
|
+
readonly sha: string;
|
|
24
|
+
readonly changeKind: string;
|
|
25
|
+
readonly date: string;
|
|
26
|
+
readonly author: string;
|
|
27
|
+
readonly signature?: string | undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface StructuralBlameResult {
|
|
31
|
+
readonly symbol: string;
|
|
32
|
+
readonly filePath?: string | undefined;
|
|
33
|
+
readonly currentSignature?: string | undefined;
|
|
34
|
+
readonly kind: string;
|
|
35
|
+
readonly exported: boolean;
|
|
36
|
+
readonly created?: CommitInfo | undefined;
|
|
37
|
+
readonly lastSignatureChange?: LastSignatureChange | undefined;
|
|
38
|
+
readonly changeCount: number;
|
|
39
|
+
readonly referenceCount: number;
|
|
40
|
+
readonly referencingFiles: readonly string[];
|
|
41
|
+
readonly history: readonly BlameHistoryEntry[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ---- Input types ----------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
/** A single commit entry from the WARP symbol history. */
|
|
47
|
+
export interface SymbolCommitInput {
|
|
48
|
+
readonly sha: string;
|
|
49
|
+
readonly changeKind: string;
|
|
50
|
+
readonly signature?: string | undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Git metadata for a commit. */
|
|
54
|
+
export interface CommitMetaInput {
|
|
55
|
+
readonly author: string;
|
|
56
|
+
readonly date: string;
|
|
57
|
+
readonly message: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Symbol metadata from the most recent commit's WARP observation. */
|
|
61
|
+
export interface SymbolMetaInput {
|
|
62
|
+
readonly kind: string;
|
|
63
|
+
readonly exported: boolean;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface StructuralBlameInput {
|
|
67
|
+
readonly symbolName: string;
|
|
68
|
+
readonly filePath?: string | undefined;
|
|
69
|
+
/** The symbol's commit history from WARP. */
|
|
70
|
+
readonly commits: readonly SymbolCommitInput[];
|
|
71
|
+
/** Git metadata keyed by commit SHA. */
|
|
72
|
+
readonly commitMeta: ReadonlyMap<string, CommitMetaInput>;
|
|
73
|
+
/** Symbol kind/exported from the latest WARP observation. */
|
|
74
|
+
readonly symbolMeta?: SymbolMetaInput | undefined;
|
|
75
|
+
/** Reference count from the reference-counting query. */
|
|
76
|
+
readonly referenceCount: number;
|
|
77
|
+
/** Files referencing this symbol. */
|
|
78
|
+
readonly referencingFiles: readonly string[];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ---- Implementation -------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
export function structuralBlame(input: StructuralBlameInput): StructuralBlameResult {
|
|
84
|
+
const { symbolName, filePath, commits, commitMeta, symbolMeta, referenceCount, referencingFiles } = input;
|
|
85
|
+
|
|
86
|
+
if (commits.length === 0) {
|
|
87
|
+
return {
|
|
88
|
+
symbol: symbolName,
|
|
89
|
+
filePath,
|
|
90
|
+
kind: symbolMeta?.kind ?? "unknown",
|
|
91
|
+
exported: symbolMeta?.exported ?? false,
|
|
92
|
+
changeCount: 0,
|
|
93
|
+
referenceCount,
|
|
94
|
+
referencingFiles,
|
|
95
|
+
history: [],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Find creation commit (first "added" entry)
|
|
100
|
+
const creationCommit = commits.find((c) => c.changeKind === "added");
|
|
101
|
+
|
|
102
|
+
// Find all "changed" commits
|
|
103
|
+
const changedCommits = commits.filter((c) => c.changeKind === "changed");
|
|
104
|
+
|
|
105
|
+
// Build created info
|
|
106
|
+
let created: CommitInfo | undefined;
|
|
107
|
+
if (creationCommit !== undefined) {
|
|
108
|
+
const meta = commitMeta.get(creationCommit.sha);
|
|
109
|
+
if (meta !== undefined) {
|
|
110
|
+
created = { sha: creationCommit.sha, author: meta.author, date: meta.date, message: meta.message };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Sort all commits by date (most recent first)
|
|
115
|
+
const sortedDesc = [...commits].sort((a, b) => {
|
|
116
|
+
const dateA = commitMeta.get(a.sha)?.date ?? "";
|
|
117
|
+
const dateB = commitMeta.get(b.sha)?.date ?? "";
|
|
118
|
+
return dateB.localeCompare(dateA);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Sort all commits by date (oldest first)
|
|
122
|
+
const sortedAsc = [...commits].sort((a, b) => {
|
|
123
|
+
const dateA = commitMeta.get(a.sha)?.date ?? "";
|
|
124
|
+
const dateB = commitMeta.get(b.sha)?.date ?? "";
|
|
125
|
+
return dateA.localeCompare(dateB);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Find last signature change — most recent by date among "changed" commits
|
|
129
|
+
let lastSignatureChange: LastSignatureChange | undefined;
|
|
130
|
+
if (changedCommits.length > 0) {
|
|
131
|
+
const sorted = [...changedCommits].sort((a, b) => {
|
|
132
|
+
const dateA = commitMeta.get(a.sha)?.date ?? "";
|
|
133
|
+
const dateB = commitMeta.get(b.sha)?.date ?? "";
|
|
134
|
+
return dateB.localeCompare(dateA);
|
|
135
|
+
});
|
|
136
|
+
const lastChanged = sorted[0];
|
|
137
|
+
if (lastChanged !== undefined) {
|
|
138
|
+
const meta = commitMeta.get(lastChanged.sha);
|
|
139
|
+
if (meta !== undefined) {
|
|
140
|
+
// Find the previous signature from the commit just before this one
|
|
141
|
+
const changeIdx = sortedAsc.findIndex((c) => c.sha === lastChanged.sha);
|
|
142
|
+
let previousSignature: string | undefined;
|
|
143
|
+
for (let i = changeIdx - 1; i >= 0; i--) {
|
|
144
|
+
const prev = sortedAsc[i];
|
|
145
|
+
if (prev?.signature !== undefined) {
|
|
146
|
+
previousSignature = prev.signature;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
lastSignatureChange = {
|
|
151
|
+
sha: lastChanged.sha,
|
|
152
|
+
author: meta.author,
|
|
153
|
+
date: meta.date,
|
|
154
|
+
message: meta.message,
|
|
155
|
+
previousSignature,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Get current signature from the most recent commit
|
|
162
|
+
const mostRecent = sortedDesc[0];
|
|
163
|
+
const currentSignature = mostRecent?.signature;
|
|
164
|
+
|
|
165
|
+
// Build history entries with metadata (most recent first)
|
|
166
|
+
const historyEntries: BlameHistoryEntry[] = sortedDesc.map((c) => {
|
|
167
|
+
const meta = commitMeta.get(c.sha);
|
|
168
|
+
return {
|
|
169
|
+
sha: c.sha,
|
|
170
|
+
changeKind: c.changeKind,
|
|
171
|
+
date: meta?.date ?? "",
|
|
172
|
+
author: meta?.author ?? "",
|
|
173
|
+
signature: c.signature,
|
|
174
|
+
};
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
symbol: symbolName,
|
|
179
|
+
filePath,
|
|
180
|
+
currentSignature,
|
|
181
|
+
kind: symbolMeta?.kind ?? "unknown",
|
|
182
|
+
exported: symbolMeta?.exported ?? false,
|
|
183
|
+
created,
|
|
184
|
+
lastSignatureChange,
|
|
185
|
+
changeCount: commits.length,
|
|
186
|
+
referenceCount,
|
|
187
|
+
referencingFiles,
|
|
188
|
+
history: historyEntries,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Convert a StructuralBlameResult to a plain JsonObject for MCP responses.
|
|
194
|
+
*/
|
|
195
|
+
export function structuralBlameToJson(result: StructuralBlameResult): JsonObject {
|
|
196
|
+
return toJsonObject(result);
|
|
197
|
+
}
|