@flyingrobots/graft 0.6.0 → 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/ADVANCED_GUIDE.md +52 -0
- package/CHANGELOG.md +142 -0
- package/GUIDE.md +53 -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 +779 -0
- package/package.json +10 -7
- 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,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WARP Structural Query Helpers — commit-symbol traversals.
|
|
3
|
+
*
|
|
4
|
+
* Shared infrastructure for graft log, graft blame, and graft churn.
|
|
5
|
+
* Uses traverse for edge-following and QueryBuilder for pattern matching
|
|
6
|
+
* and batch prop reads. No getEdges() — filtering stays substrate-side.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { Lens, QueryResultV1 } from "@git-stunts/git-warp";
|
|
10
|
+
import type { WarpContext } from "./context.js";
|
|
11
|
+
import { observeGraph } from "./context.js";
|
|
12
|
+
import { symbolTimeline } from "./symbol-timeline.js";
|
|
13
|
+
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Types
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
/** A symbol that was added, removed, or changed in a commit. */
|
|
19
|
+
export interface SymbolChange {
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly kind: string;
|
|
22
|
+
readonly signature?: string | undefined;
|
|
23
|
+
readonly exported: boolean;
|
|
24
|
+
readonly filePath: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** All symbol changes for a single commit. */
|
|
28
|
+
export interface CommitSymbols {
|
|
29
|
+
readonly sha: string;
|
|
30
|
+
readonly added: readonly SymbolChange[];
|
|
31
|
+
readonly removed: readonly SymbolChange[];
|
|
32
|
+
readonly changed: readonly SymbolChange[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The kind of change a commit made to a symbol. */
|
|
36
|
+
export type ChangeKind = "added" | "removed" | "changed";
|
|
37
|
+
|
|
38
|
+
/** A single commit entry in a symbol's history. */
|
|
39
|
+
export interface SymbolCommit {
|
|
40
|
+
readonly sha: string;
|
|
41
|
+
readonly changeKind: ChangeKind;
|
|
42
|
+
readonly signature?: string | undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Full change history for a symbol across commits. */
|
|
46
|
+
export interface SymbolHistory {
|
|
47
|
+
readonly symbol: string;
|
|
48
|
+
readonly filePath?: string | undefined;
|
|
49
|
+
readonly commits: readonly SymbolCommit[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Internal helpers
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Lens that spans both commit and symbol nodes so the observer
|
|
58
|
+
* can see the edges between them.
|
|
59
|
+
*/
|
|
60
|
+
function commitSymbolLens(): Lens {
|
|
61
|
+
return {
|
|
62
|
+
match: ["commit:*", "sym:*"],
|
|
63
|
+
expose: ["sha", "name", "kind", "signature", "exported"],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function filePathFromSymId(symId: string): string {
|
|
68
|
+
const withoutPrefix = symId.slice("sym:".length);
|
|
69
|
+
const lastColon = withoutPrefix.lastIndexOf(":");
|
|
70
|
+
if (lastColon === -1) {
|
|
71
|
+
return withoutPrefix;
|
|
72
|
+
}
|
|
73
|
+
return withoutPrefix.slice(0, lastColon);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Public API
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Given a commit SHA, return all symbols that were added, removed,
|
|
82
|
+
* or changed in that commit.
|
|
83
|
+
*
|
|
84
|
+
* Uses traverse for edge-following (substrate-side), then QueryBuilder
|
|
85
|
+
* for batch prop reads. Removals are detected by temporal diff at
|
|
86
|
+
* tick N-1 vs tick N.
|
|
87
|
+
*/
|
|
88
|
+
export async function symbolsForCommit(
|
|
89
|
+
ctx: WarpContext,
|
|
90
|
+
commitSha: string,
|
|
91
|
+
): Promise<CommitSymbols> {
|
|
92
|
+
const commitId = `commit:${commitSha}`;
|
|
93
|
+
|
|
94
|
+
// Read the commit's tick for removal detection.
|
|
95
|
+
const commitObs = await observeGraph(ctx,
|
|
96
|
+
{ match: commitId, expose: ["tick"] },
|
|
97
|
+
);
|
|
98
|
+
const commitProps = await commitObs.getNodeProps(commitId);
|
|
99
|
+
const tick = typeof commitProps?.["tick"] === "number" ? commitProps["tick"] : null;
|
|
100
|
+
|
|
101
|
+
// Observer scoped to commit + symbol nodes.
|
|
102
|
+
const obs = await observeGraph(ctx, commitSymbolLens());
|
|
103
|
+
|
|
104
|
+
// Check if the commit node exists before traversing.
|
|
105
|
+
const commitExists = await obs.hasNode(commitId);
|
|
106
|
+
if (!commitExists) {
|
|
107
|
+
return { sha: commitSha, added: [], removed: [], changed: [] };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Traverse: follow outgoing edges from this commit by label.
|
|
111
|
+
const [addedIds, changedIds] = await Promise.all([
|
|
112
|
+
obs.traverse.bfs(commitId, { dir: "out", labelFilter: "adds", maxDepth: 1 }),
|
|
113
|
+
obs.traverse.bfs(commitId, { dir: "out", labelFilter: "changes", maxDepth: 1 }),
|
|
114
|
+
]);
|
|
115
|
+
|
|
116
|
+
// Batch prop read for discovered sym nodes.
|
|
117
|
+
const allSymIds = [...addedIds, ...changedIds].filter((id) => id.startsWith("sym:"));
|
|
118
|
+
|
|
119
|
+
const symPropsMap = new Map<string, Record<string, unknown>>();
|
|
120
|
+
if (allSymIds.length > 0) {
|
|
121
|
+
const propsResult = await obs.query()
|
|
122
|
+
.match(allSymIds)
|
|
123
|
+
.select(["id", "props"])
|
|
124
|
+
.run() as QueryResultV1;
|
|
125
|
+
for (const node of propsResult.nodes) {
|
|
126
|
+
if (node.id !== undefined && node.props !== undefined) {
|
|
127
|
+
symPropsMap.set(node.id, node.props);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function toSymbolChange(symId: string): SymbolChange {
|
|
133
|
+
const props = symPropsMap.get(symId) ?? {};
|
|
134
|
+
const name = typeof props["name"] === "string" ? props["name"] : symId;
|
|
135
|
+
const kind = typeof props["kind"] === "string" ? props["kind"] : "unknown";
|
|
136
|
+
const signature = typeof props["signature"] === "string" ? props["signature"] : undefined;
|
|
137
|
+
const exported = typeof props["exported"] === "boolean" ? props["exported"] : false;
|
|
138
|
+
const filePath = filePathFromSymId(symId);
|
|
139
|
+
return { name, kind, signature, exported, filePath };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const added = addedIds.filter((id) => id.startsWith("sym:")).map(toSymbolChange);
|
|
143
|
+
const changed = changedIds.filter((id) => id.startsWith("sym:")).map(toSymbolChange);
|
|
144
|
+
|
|
145
|
+
// Detect removals by temporal receipts across the Git commit's indexed
|
|
146
|
+
// Lamport window. Lazy indexing can write one WARP patch per file, so one
|
|
147
|
+
// Git commit may span multiple Lamport ticks.
|
|
148
|
+
let removed: SymbolChange[] = [];
|
|
149
|
+
if (tick !== null) {
|
|
150
|
+
removed = await detectRemovals(ctx, await previousCommitTick(ctx, commitSha, tick), tick);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return { sha: commitSha, added, removed, changed };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async function previousCommitTick(
|
|
157
|
+
ctx: WarpContext,
|
|
158
|
+
commitSha: string,
|
|
159
|
+
tick: number,
|
|
160
|
+
): Promise<number> {
|
|
161
|
+
const obs = await observeGraph(ctx, { match: "commit:*", expose: ["sha", "tick"] });
|
|
162
|
+
const nodeIds = await obs.getNodes();
|
|
163
|
+
let previous = 0;
|
|
164
|
+
|
|
165
|
+
for (const nodeId of nodeIds) {
|
|
166
|
+
const props = await obs.getNodeProps(nodeId);
|
|
167
|
+
const sha = typeof props?.["sha"] === "string"
|
|
168
|
+
? props["sha"]
|
|
169
|
+
: nodeId.slice("commit:".length);
|
|
170
|
+
if (sha === commitSha) continue;
|
|
171
|
+
|
|
172
|
+
const candidate = typeof props?.["tick"] === "number" ? props["tick"] : null;
|
|
173
|
+
if (candidate !== null && candidate < tick && candidate > previous) {
|
|
174
|
+
previous = candidate;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return previous;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Detect symbol removals via tick receipts.
|
|
183
|
+
*
|
|
184
|
+
* Instead of scanning all sym:* nodes at two ceilings (which assumes
|
|
185
|
+
* the full graph fits in memory), we materialize with receipts and inspect
|
|
186
|
+
* receipts in one Git commit's indexed Lamport window for NodeTombstone ops
|
|
187
|
+
* on sym nodes. O(ops in indexed file patches), not O(all sym nodes).
|
|
188
|
+
*/
|
|
189
|
+
async function detectRemovals(
|
|
190
|
+
ctx: WarpContext,
|
|
191
|
+
previousTick: number,
|
|
192
|
+
tick: number,
|
|
193
|
+
): Promise<SymbolChange[]> {
|
|
194
|
+
// Use latest materialization and filter receipts locally. A ceiling
|
|
195
|
+
// materialization on the shared core would leave the app cached at an old
|
|
196
|
+
// tick, corrupting later live reads in the same operation.
|
|
197
|
+
const { receipts } = await ctx.app.core().materialize({ receipts: true });
|
|
198
|
+
|
|
199
|
+
const scopedReceipts = receipts.filter((receipt) =>
|
|
200
|
+
receipt.lamport > previousTick && receipt.lamport <= tick,
|
|
201
|
+
);
|
|
202
|
+
if (scopedReceipts.length === 0) return [];
|
|
203
|
+
|
|
204
|
+
// Tombstoned sym nodes = removals.
|
|
205
|
+
const removed = new Map<string, number>();
|
|
206
|
+
for (const receipt of scopedReceipts) {
|
|
207
|
+
for (const op of receipt.ops) {
|
|
208
|
+
if (op.op === "NodeTombstone" && op.target.startsWith("sym:") && op.result === "applied") {
|
|
209
|
+
removed.set(op.target, receipt.lamport);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (removed.size === 0) return [];
|
|
215
|
+
|
|
216
|
+
// Read props from the pre-removal observer (nodes are gone at current tick).
|
|
217
|
+
const symLens: Lens = {
|
|
218
|
+
match: "sym:*",
|
|
219
|
+
expose: ["name", "kind", "signature", "exported"],
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// Targeted per-node reads — bounded by removals in one commit.
|
|
223
|
+
const changes: SymbolChange[] = [];
|
|
224
|
+
for (const [id, removalTick] of removed) {
|
|
225
|
+
const beforeObs = await observeGraph(ctx, symLens, {
|
|
226
|
+
source: { kind: "live", ceiling: removalTick - 1 },
|
|
227
|
+
});
|
|
228
|
+
const props = await beforeObs.getNodeProps(id);
|
|
229
|
+
if (props === null) continue;
|
|
230
|
+
|
|
231
|
+
const name = typeof props["name"] === "string" ? props["name"] : id;
|
|
232
|
+
const kind = typeof props["kind"] === "string" ? props["kind"] : "unknown";
|
|
233
|
+
const signature = typeof props["signature"] === "string" ? props["signature"] : undefined;
|
|
234
|
+
const exported = typeof props["exported"] === "boolean" ? props["exported"] : false;
|
|
235
|
+
const filePath = filePathFromSymId(id);
|
|
236
|
+
|
|
237
|
+
changes.push({ name, kind, signature, exported, filePath });
|
|
238
|
+
}
|
|
239
|
+
return changes;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/** @deprecated Use symbolTimeline() from ./symbol-timeline.ts instead. */
|
|
243
|
+
export async function commitsForSymbol(
|
|
244
|
+
ctx: WarpContext,
|
|
245
|
+
symbolName: string,
|
|
246
|
+
filePath?: string,
|
|
247
|
+
): Promise<SymbolHistory> {
|
|
248
|
+
const timeline = await symbolTimeline(ctx, symbolName, filePath);
|
|
249
|
+
return {
|
|
250
|
+
symbol: symbolName,
|
|
251
|
+
filePath,
|
|
252
|
+
commits: timeline.versions.map((version) => ({
|
|
253
|
+
sha: version.sha,
|
|
254
|
+
changeKind: version.changeKind,
|
|
255
|
+
signature: version.signature,
|
|
256
|
+
})),
|
|
257
|
+
};
|
|
258
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WARP Symbol Timeline — ordered history of a symbol across commits.
|
|
3
|
+
*
|
|
4
|
+
* Reads WARP provenance for symbol ids and reconstructs versions from
|
|
5
|
+
* patches that touched the symbol. Callers that need removed-symbol
|
|
6
|
+
* history must pass filePath so the symbol id is explicit.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { PatchV2 } from "@git-stunts/git-warp";
|
|
10
|
+
import { observeGraph, type WarpContext } from "./context.js";
|
|
11
|
+
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Types
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
/** A single version of a symbol at a specific commit. */
|
|
17
|
+
export interface SymbolVersion {
|
|
18
|
+
readonly sha: string;
|
|
19
|
+
readonly tick: number;
|
|
20
|
+
readonly changeKind: "added" | "changed" | "removed";
|
|
21
|
+
readonly present: boolean;
|
|
22
|
+
readonly signature?: string | undefined;
|
|
23
|
+
readonly startLine?: number | undefined;
|
|
24
|
+
readonly endLine?: number | undefined;
|
|
25
|
+
readonly filePath: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Full ordered timeline for a symbol across commits. */
|
|
29
|
+
export interface SymbolTimelineResult {
|
|
30
|
+
readonly symbol: string;
|
|
31
|
+
readonly filePath?: string | undefined;
|
|
32
|
+
readonly versions: readonly SymbolVersion[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Internal helpers
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
function filePathFromSymId(symId: string): string {
|
|
40
|
+
const withoutPrefix = symId.slice("sym:".length);
|
|
41
|
+
const lastColon = withoutPrefix.lastIndexOf(":");
|
|
42
|
+
if (lastColon === -1) {
|
|
43
|
+
return withoutPrefix;
|
|
44
|
+
}
|
|
45
|
+
return withoutPrefix.slice(0, lastColon);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
type ChangeKind = SymbolVersion["changeKind"];
|
|
49
|
+
|
|
50
|
+
interface PatchOpView {
|
|
51
|
+
readonly type?: unknown;
|
|
52
|
+
readonly from?: unknown;
|
|
53
|
+
readonly to?: unknown;
|
|
54
|
+
readonly label?: unknown;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface ProvenanceTimelineCore {
|
|
58
|
+
patchesFor(entityId: string): Promise<string[]>;
|
|
59
|
+
loadPatchBySha(sha: string): Promise<PatchV2>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const EDGE_CHANGE_KIND = new Map<string, ChangeKind>([
|
|
63
|
+
["adds", "added"],
|
|
64
|
+
["changes", "changed"],
|
|
65
|
+
["removes", "removed"],
|
|
66
|
+
]);
|
|
67
|
+
|
|
68
|
+
function symIdFor(filePath: string, symbolName: string): string {
|
|
69
|
+
return `sym:${filePath}:${symbolName}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function patchOps(patch: PatchV2): readonly PatchOpView[] {
|
|
73
|
+
return Array.isArray(patch.ops) ? patch.ops as readonly PatchOpView[] : [];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
interface SymbolTouch {
|
|
77
|
+
readonly sha: string;
|
|
78
|
+
readonly tick: number;
|
|
79
|
+
readonly changeKind: ChangeKind;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function touchFromPatch(symId: string, patch: PatchV2): SymbolTouch | null {
|
|
83
|
+
const ops = patchOps(patch);
|
|
84
|
+
|
|
85
|
+
for (const op of ops) {
|
|
86
|
+
if (op.type !== "EdgeAdd") continue;
|
|
87
|
+
if (typeof op.from !== "string" || !op.from.startsWith("commit:")) continue;
|
|
88
|
+
if (op.to !== symId || typeof op.label !== "string") continue;
|
|
89
|
+
|
|
90
|
+
const changeKind = EDGE_CHANGE_KIND.get(op.label);
|
|
91
|
+
if (changeKind === undefined) continue;
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
sha: op.from.slice("commit:".length),
|
|
95
|
+
tick: patch.lamport,
|
|
96
|
+
changeKind,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function readSymbolPropsAtTick(
|
|
104
|
+
ctx: WarpContext,
|
|
105
|
+
symId: string,
|
|
106
|
+
tick: number,
|
|
107
|
+
): Promise<Record<string, unknown> | null> {
|
|
108
|
+
const worldline = await ctx.app.worldline().seek({
|
|
109
|
+
source: { kind: "live", ceiling: tick },
|
|
110
|
+
});
|
|
111
|
+
return worldline.getNodeProps(symId);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function versionFromPatch(
|
|
115
|
+
ctx: WarpContext,
|
|
116
|
+
symId: string,
|
|
117
|
+
patch: PatchV2,
|
|
118
|
+
): Promise<SymbolVersion | null> {
|
|
119
|
+
const touch = touchFromPatch(symId, patch);
|
|
120
|
+
if (touch === null) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const props = touch.changeKind === "removed"
|
|
125
|
+
? null
|
|
126
|
+
: await readSymbolPropsAtTick(ctx, symId, touch.tick);
|
|
127
|
+
const signature = props?.["signature"];
|
|
128
|
+
const startLine = props?.["startLine"];
|
|
129
|
+
const endLine = props?.["endLine"];
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
sha: touch.sha,
|
|
133
|
+
tick: touch.tick,
|
|
134
|
+
changeKind: touch.changeKind,
|
|
135
|
+
present: touch.changeKind !== "removed",
|
|
136
|
+
signature: typeof signature === "string" ? signature : undefined,
|
|
137
|
+
startLine: typeof startLine === "number" ? startLine : undefined,
|
|
138
|
+
endLine: typeof endLine === "number" ? endLine : undefined,
|
|
139
|
+
filePath: filePathFromSymId(symId),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function liveSymbolIds(
|
|
144
|
+
ctx: WarpContext,
|
|
145
|
+
symbolName: string,
|
|
146
|
+
filePath: string | undefined,
|
|
147
|
+
): Promise<readonly string[]> {
|
|
148
|
+
if (filePath !== undefined) {
|
|
149
|
+
return [symIdFor(filePath, symbolName)];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const obs = await observeGraph(ctx, { match: `sym:*:${symbolName}`, expose: [] });
|
|
153
|
+
return obs.getNodes();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async function readTimelineVersions(
|
|
157
|
+
ctx: WarpContext,
|
|
158
|
+
symbolName: string,
|
|
159
|
+
filePath: string | undefined,
|
|
160
|
+
): Promise<SymbolVersion[]> {
|
|
161
|
+
const core = ctx.app.core() as unknown as ProvenanceTimelineCore;
|
|
162
|
+
const symIds = await liveSymbolIds(ctx, symbolName, filePath);
|
|
163
|
+
if (symIds.length === 0) return [];
|
|
164
|
+
|
|
165
|
+
const versions: SymbolVersion[] = [];
|
|
166
|
+
const seen = new Set<string>();
|
|
167
|
+
|
|
168
|
+
for (const symId of symIds) {
|
|
169
|
+
const patchShas = await core.patchesFor(symId);
|
|
170
|
+
const patches = await Promise.all(patchShas.map(async (sha) => core.loadPatchBySha(sha)));
|
|
171
|
+
|
|
172
|
+
for (const patch of patches) {
|
|
173
|
+
const version = await versionFromPatch(ctx, symId, patch);
|
|
174
|
+
if (version === null) continue;
|
|
175
|
+
|
|
176
|
+
const key = `${String(version.tick)}:${version.sha}:${symId}:${version.changeKind}`;
|
|
177
|
+
if (seen.has(key)) continue;
|
|
178
|
+
|
|
179
|
+
versions.push(version);
|
|
180
|
+
seen.add(key);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
versions.sort((a, b) => a.tick - b.tick || a.filePath.localeCompare(b.filePath));
|
|
185
|
+
return versions;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
// Public API
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Build an ordered timeline of every version of a symbol across commits.
|
|
194
|
+
*
|
|
195
|
+
* For each commit that touched the symbol (adds, changes, removes), the
|
|
196
|
+
* returned array includes the commit SHA, tick, change kind, presence
|
|
197
|
+
* flag, signature, and line range. Entries are sorted by tick ascending.
|
|
198
|
+
*/
|
|
199
|
+
export async function symbolTimeline(
|
|
200
|
+
ctx: WarpContext,
|
|
201
|
+
symbolName: string,
|
|
202
|
+
filePath?: string,
|
|
203
|
+
): Promise<SymbolTimelineResult> {
|
|
204
|
+
return {
|
|
205
|
+
symbol: symbolName,
|
|
206
|
+
filePath,
|
|
207
|
+
versions: await readTimelineVersions(ctx, symbolName, filePath),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Traverse + Query Batch Hydration Helper
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { Observer, QueryResultV1 } from "@git-stunts/git-warp";
|
|
6
|
+
|
|
7
|
+
/** A hydrated node with its ID and properties. */
|
|
8
|
+
export interface HydratedNode {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Traversal options matching observer.traverse.bfs. */
|
|
14
|
+
export interface TraverseOptions {
|
|
15
|
+
readonly dir: "out" | "in";
|
|
16
|
+
readonly labelFilter?: string;
|
|
17
|
+
readonly maxDepth?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* BFS traversal followed by batch property hydration.
|
|
22
|
+
*
|
|
23
|
+
* Combines two common operations into one call:
|
|
24
|
+
* 1. `observer.traverse.bfs()` for topology discovery
|
|
25
|
+
* 2. `observer.query().match(ids).select(["id", "props"]).run()` for batch hydration
|
|
26
|
+
*
|
|
27
|
+
* Returns hydrated nodes with both IDs and properties.
|
|
28
|
+
*/
|
|
29
|
+
export async function traverseAndHydrate(
|
|
30
|
+
observer: Observer,
|
|
31
|
+
startId: string,
|
|
32
|
+
options: TraverseOptions,
|
|
33
|
+
): Promise<readonly HydratedNode[]> {
|
|
34
|
+
let ids: string[];
|
|
35
|
+
try {
|
|
36
|
+
const bfsOptions: {
|
|
37
|
+
dir: "out" | "in";
|
|
38
|
+
labelFilter?: string;
|
|
39
|
+
maxDepth?: number;
|
|
40
|
+
} = { dir: options.dir };
|
|
41
|
+
if (options.labelFilter !== undefined) bfsOptions.labelFilter = options.labelFilter;
|
|
42
|
+
if (options.maxDepth !== undefined) bfsOptions.maxDepth = options.maxDepth;
|
|
43
|
+
ids = await observer.traverse.bfs(startId, bfsOptions);
|
|
44
|
+
} catch {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (ids.length === 0) return [];
|
|
49
|
+
|
|
50
|
+
const result = await observer.query()
|
|
51
|
+
.match(ids)
|
|
52
|
+
.select(["id", "props"])
|
|
53
|
+
.run() as QueryResultV1;
|
|
54
|
+
|
|
55
|
+
return result.nodes
|
|
56
|
+
.filter((n): n is { id: string; props?: Record<string, unknown> } => n.id !== undefined)
|
|
57
|
+
.map((n) => ({
|
|
58
|
+
id: n.id,
|
|
59
|
+
props: n.props ?? {},
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// WARP-based symbol reference counting
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { WarpContext } from "./context.js";
|
|
6
|
+
import { referencesForSymbol } from "./references.js";
|
|
7
|
+
|
|
8
|
+
export interface ReferenceCountResult {
|
|
9
|
+
readonly symbol: string;
|
|
10
|
+
readonly referenceCount: number;
|
|
11
|
+
readonly referencingFiles: readonly string[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Count how many files reference a symbol via WARP graph edges.
|
|
16
|
+
*
|
|
17
|
+
* Uses `referencesForSymbol` which traverses incoming `references`
|
|
18
|
+
* edges from import/export specifier AST nodes to the target sym node.
|
|
19
|
+
* Uses actual imports, not text matches, and does not spawn subprocesses.
|
|
20
|
+
*
|
|
21
|
+
* @param ctx - WARP context
|
|
22
|
+
* @param symbolName - The symbol to count references for
|
|
23
|
+
* @param filePath - The file where the symbol is defined (required for sym node ID)
|
|
24
|
+
*/
|
|
25
|
+
export async function countSymbolReferencesFromGraph(
|
|
26
|
+
ctx: WarpContext,
|
|
27
|
+
symbolName: string,
|
|
28
|
+
filePath?: string,
|
|
29
|
+
): Promise<ReferenceCountResult> {
|
|
30
|
+
if (filePath === undefined) {
|
|
31
|
+
// Without filePath we can't construct the sym node ID.
|
|
32
|
+
// Return empty — caller should provide filePath for accurate results.
|
|
33
|
+
return { symbol: symbolName, referenceCount: 0, referencingFiles: [] };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const refs = await referencesForSymbol(ctx, symbolName, filePath);
|
|
37
|
+
|
|
38
|
+
// Deduplicate by file path (multiple imports from the same file
|
|
39
|
+
// count as one referencing file).
|
|
40
|
+
const uniqueFiles = [...new Set(refs.map((r) => r.filePath))];
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
symbol: symbolName,
|
|
44
|
+
referenceCount: uniqueFiles.length,
|
|
45
|
+
referencingFiles: uniqueFiles,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// WARP-based Structural Blame — replaces git-dependent blame pipeline
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { WarpContext } from "./context.js";
|
|
6
|
+
import { symbolTimeline, type SymbolVersion } from "./symbol-timeline.js";
|
|
7
|
+
import { countSymbolReferencesFromGraph } from "./warp-reference-count.js";
|
|
8
|
+
|
|
9
|
+
/** Blame result for a single symbol. */
|
|
10
|
+
export interface WarpBlameResult {
|
|
11
|
+
readonly symbol: string;
|
|
12
|
+
readonly filePath: string;
|
|
13
|
+
readonly history: readonly SymbolVersion[];
|
|
14
|
+
readonly changeCount: number;
|
|
15
|
+
readonly createdInCommit: string | undefined;
|
|
16
|
+
readonly lastSignatureChange: string | undefined;
|
|
17
|
+
readonly referenceCount: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Compute structural blame for a symbol entirely from the WARP graph.
|
|
22
|
+
*
|
|
23
|
+
* Uses symbolTimeline for history, countSymbolReferencesFromGraph for
|
|
24
|
+
* reference counting. Zero git subprocess calls.
|
|
25
|
+
*/
|
|
26
|
+
export async function structuralBlameFromGraph(
|
|
27
|
+
ctx: WarpContext,
|
|
28
|
+
symbolName: string,
|
|
29
|
+
filePath: string,
|
|
30
|
+
): Promise<WarpBlameResult> {
|
|
31
|
+
// Get full timeline from WARP
|
|
32
|
+
const timeline = await symbolTimeline(ctx, symbolName, filePath);
|
|
33
|
+
|
|
34
|
+
if (timeline.versions.length === 0) {
|
|
35
|
+
return {
|
|
36
|
+
symbol: symbolName,
|
|
37
|
+
filePath,
|
|
38
|
+
history: [],
|
|
39
|
+
changeCount: 0,
|
|
40
|
+
createdInCommit: undefined,
|
|
41
|
+
lastSignatureChange: undefined,
|
|
42
|
+
referenceCount: 0,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Find creation commit (first "added" entry)
|
|
47
|
+
const created = timeline.versions.find((v) => v.changeKind === "added");
|
|
48
|
+
|
|
49
|
+
// Find last signature change (last "changed" entry)
|
|
50
|
+
const changes = timeline.versions.filter((v) => v.changeKind === "changed");
|
|
51
|
+
const lastChange = changes.length > 0 ? changes[changes.length - 1] : undefined;
|
|
52
|
+
|
|
53
|
+
// Count references from WARP graph
|
|
54
|
+
const refs = await countSymbolReferencesFromGraph(ctx, symbolName, filePath);
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
symbol: symbolName,
|
|
58
|
+
filePath,
|
|
59
|
+
history: timeline.versions,
|
|
60
|
+
changeCount: timeline.versions.length,
|
|
61
|
+
createdInCommit: created?.sha,
|
|
62
|
+
lastSignatureChange: lastChange?.sha,
|
|
63
|
+
referenceCount: refs.referenceCount,
|
|
64
|
+
};
|
|
65
|
+
}
|