@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.
Files changed (563) hide show
  1. package/ADVANCED_GUIDE.md +52 -0
  2. package/CHANGELOG.md +142 -0
  3. package/GUIDE.md +53 -0
  4. package/README.md +1 -1
  5. package/dist/adapters/json-text-decoder.d.ts +3 -0
  6. package/dist/adapters/json-text-decoder.d.ts.map +1 -0
  7. package/dist/adapters/json-text-decoder.js +12 -0
  8. package/dist/adapters/json-text-decoder.js.map +1 -0
  9. package/dist/adapters/node-paths.d.ts +3 -0
  10. package/dist/adapters/node-paths.d.ts.map +1 -0
  11. package/dist/adapters/node-paths.js +29 -0
  12. package/dist/adapters/node-paths.js.map +1 -0
  13. package/dist/adapters/repo-paths.d.ts.map +1 -1
  14. package/dist/adapters/repo-paths.js +40 -5
  15. package/dist/adapters/repo-paths.js.map +1 -1
  16. package/dist/api/tool-bridge.d.ts +1 -1
  17. package/dist/api/tool-bridge.d.ts.map +1 -1
  18. package/dist/api/tool-bridge.js +1 -1
  19. package/dist/api/tool-bridge.js.map +1 -1
  20. package/dist/cli/cli-error.d.ts.map +1 -1
  21. package/dist/cli/cli-error.js +47 -10
  22. package/dist/cli/cli-error.js.map +1 -1
  23. package/dist/cli/command-parser.d.ts +12 -3
  24. package/dist/cli/command-parser.d.ts.map +1 -1
  25. package/dist/cli/command-parser.js +161 -2
  26. package/dist/cli/command-parser.js.map +1 -1
  27. package/dist/cli/daemon-status-model.d.ts +87 -0
  28. package/dist/cli/daemon-status-model.d.ts.map +1 -0
  29. package/dist/cli/daemon-status-model.js +142 -0
  30. package/dist/cli/daemon-status-model.js.map +1 -0
  31. package/dist/cli/daemon-status-render.d.ts +3 -0
  32. package/dist/cli/daemon-status-render.d.ts.map +1 -0
  33. package/dist/cli/daemon-status-render.js +100 -0
  34. package/dist/cli/daemon-status-render.js.map +1 -0
  35. package/dist/cli/daemon-status.d.ts +7 -0
  36. package/dist/cli/daemon-status.d.ts.map +1 -0
  37. package/dist/cli/daemon-status.js +79 -0
  38. package/dist/cli/daemon-status.js.map +1 -0
  39. package/dist/cli/git-graft-enhance-model.d.ts +67 -0
  40. package/dist/cli/git-graft-enhance-model.d.ts.map +1 -0
  41. package/dist/cli/git-graft-enhance-model.js +55 -0
  42. package/dist/cli/git-graft-enhance-model.js.map +1 -0
  43. package/dist/cli/git-graft-enhance-render.d.ts +3 -0
  44. package/dist/cli/git-graft-enhance-render.d.ts.map +1 -0
  45. package/dist/cli/git-graft-enhance-render.js +29 -0
  46. package/dist/cli/git-graft-enhance-render.js.map +1 -0
  47. package/dist/cli/git-graft-enhance.d.ts +14 -0
  48. package/dist/cli/git-graft-enhance.d.ts.map +1 -0
  49. package/dist/cli/git-graft-enhance.js +29 -0
  50. package/dist/cli/git-graft-enhance.js.map +1 -0
  51. package/dist/cli/index-cmd.d.ts.map +1 -1
  52. package/dist/cli/index-cmd.js +18 -21
  53. package/dist/cli/index-cmd.js.map +1 -1
  54. package/dist/cli/index-model.d.ts +5 -9
  55. package/dist/cli/index-model.d.ts.map +1 -1
  56. package/dist/cli/index-model.js +20 -18
  57. package/dist/cli/index-model.js.map +1 -1
  58. package/dist/cli/init-client-config.d.ts +12 -7
  59. package/dist/cli/init-client-config.d.ts.map +1 -1
  60. package/dist/cli/init-client-config.js +105 -43
  61. package/dist/cli/init-client-config.js.map +1 -1
  62. package/dist/cli/init-model.d.ts +9 -2
  63. package/dist/cli/init-model.d.ts.map +1 -1
  64. package/dist/cli/init-model.js +52 -4
  65. package/dist/cli/init-model.js.map +1 -1
  66. package/dist/cli/init-render.d.ts.map +1 -1
  67. package/dist/cli/init-render.js +2 -2
  68. package/dist/cli/init-render.js.map +1 -1
  69. package/dist/cli/init.d.ts.map +1 -1
  70. package/dist/cli/init.js +11 -9
  71. package/dist/cli/init.js.map +1 -1
  72. package/dist/cli/json-document.d.ts +5 -0
  73. package/dist/cli/json-document.d.ts.map +1 -1
  74. package/dist/cli/json-document.js +9 -0
  75. package/dist/cli/json-document.js.map +1 -1
  76. package/dist/cli/main.d.ts +7 -0
  77. package/dist/cli/main.d.ts.map +1 -1
  78. package/dist/cli/main.js +49 -7
  79. package/dist/cli/main.js.map +1 -1
  80. package/dist/cli/migrate-local-history.d.ts.map +1 -1
  81. package/dist/cli/migrate-local-history.js +3 -2
  82. package/dist/cli/migrate-local-history.js.map +1 -1
  83. package/dist/cli/peer-command.d.ts +1 -1
  84. package/dist/cli/peer-command.d.ts.map +1 -1
  85. package/dist/cli/peer-command.js +1 -1
  86. package/dist/cli/peer-command.js.map +1 -1
  87. package/dist/contracts/capabilities.d.ts +5 -5
  88. package/dist/contracts/capabilities.d.ts.map +1 -1
  89. package/dist/contracts/capabilities.js +89 -0
  90. package/dist/contracts/capabilities.js.map +1 -1
  91. package/dist/contracts/causal-ontology.d.ts +17 -17
  92. package/dist/contracts/json-object.d.ts +0 -1
  93. package/dist/contracts/json-object.d.ts.map +1 -1
  94. package/dist/contracts/json-object.js +0 -10
  95. package/dist/contracts/json-object.js.map +1 -1
  96. package/dist/contracts/output-schema-cli.d.ts +277 -25
  97. package/dist/contracts/output-schema-cli.d.ts.map +1 -1
  98. package/dist/contracts/output-schema-cli.js +35 -3
  99. package/dist/contracts/output-schema-cli.js.map +1 -1
  100. package/dist/contracts/output-schema-fragments.d.ts +212 -87
  101. package/dist/contracts/output-schema-fragments.d.ts.map +1 -1
  102. package/dist/contracts/output-schema-fragments.js +49 -2
  103. package/dist/contracts/output-schema-fragments.js.map +1 -1
  104. package/dist/contracts/output-schema-mcp.d.ts +372 -47
  105. package/dist/contracts/output-schema-mcp.d.ts.map +1 -1
  106. package/dist/contracts/output-schema-mcp.js +217 -1
  107. package/dist/contracts/output-schema-mcp.js.map +1 -1
  108. package/dist/contracts/output-schema-meta.d.ts +2 -2
  109. package/dist/contracts/output-schema-meta.d.ts.map +1 -1
  110. package/dist/contracts/output-schemas.d.ts +7 -7
  111. package/dist/contracts/output-schemas.d.ts.map +1 -1
  112. package/dist/contracts/output-schemas.js +294 -6
  113. package/dist/contracts/output-schemas.js.map +1 -1
  114. package/dist/git/diff.d.ts +11 -0
  115. package/dist/git/diff.d.ts.map +1 -1
  116. package/dist/git/diff.js +50 -6
  117. package/dist/git/diff.js.map +1 -1
  118. package/dist/mcp/burden.d.ts.map +1 -1
  119. package/dist/mcp/burden.js +9 -0
  120. package/dist/mcp/burden.js.map +1 -1
  121. package/dist/mcp/context.d.ts +3 -2
  122. package/dist/mcp/context.d.ts.map +1 -1
  123. package/dist/mcp/context.js +2 -37
  124. package/dist/mcp/context.js.map +1 -1
  125. package/dist/mcp/daemon-server.d.ts +2 -0
  126. package/dist/mcp/daemon-server.d.ts.map +1 -1
  127. package/dist/mcp/daemon-server.js +6 -1
  128. package/dist/mcp/daemon-server.js.map +1 -1
  129. package/dist/mcp/daemon-session-host.d.ts +1 -0
  130. package/dist/mcp/daemon-session-host.d.ts.map +1 -1
  131. package/dist/mcp/daemon-session-host.js +3 -0
  132. package/dist/mcp/daemon-session-host.js.map +1 -1
  133. package/dist/mcp/daemon-stdio-bridge.d.ts +1 -0
  134. package/dist/mcp/daemon-stdio-bridge.d.ts.map +1 -1
  135. package/dist/mcp/daemon-stdio-bridge.js +1 -0
  136. package/dist/mcp/daemon-stdio-bridge.js.map +1 -1
  137. package/dist/mcp/monitor-tick-job.d.ts +1 -0
  138. package/dist/mcp/monitor-tick-job.d.ts.map +1 -1
  139. package/dist/mcp/monitor-tick-job.js +84 -29
  140. package/dist/mcp/monitor-tick-job.js.map +1 -1
  141. package/dist/mcp/monitor-types.d.ts +1 -1
  142. package/dist/mcp/monitor-types.d.ts.map +1 -1
  143. package/dist/mcp/persisted-local-history-graph.d.ts +2 -2
  144. package/dist/mcp/persisted-local-history-graph.d.ts.map +1 -1
  145. package/dist/mcp/persisted-local-history-graph.js +3 -2
  146. package/dist/mcp/persisted-local-history-graph.js.map +1 -1
  147. package/dist/mcp/persisted-local-history.d.ts +5 -5
  148. package/dist/mcp/persisted-local-history.js +2 -2
  149. package/dist/mcp/persisted-local-history.js.map +1 -1
  150. package/dist/mcp/persistent-monitor-runtime.d.ts +1 -0
  151. package/dist/mcp/persistent-monitor-runtime.d.ts.map +1 -1
  152. package/dist/mcp/persistent-monitor-runtime.js +35 -0
  153. package/dist/mcp/persistent-monitor-runtime.js.map +1 -1
  154. package/dist/mcp/repo-tool-worker-context.d.ts.map +1 -1
  155. package/dist/mcp/repo-tool-worker-context.js +5 -2
  156. package/dist/mcp/repo-tool-worker-context.js.map +1 -1
  157. package/dist/mcp/server-context.d.ts.map +1 -1
  158. package/dist/mcp/server-context.js +13 -0
  159. package/dist/mcp/server-context.js.map +1 -1
  160. package/dist/mcp/server-tool-access.d.ts +1 -1
  161. package/dist/mcp/server-tool-access.d.ts.map +1 -1
  162. package/dist/mcp/server-tool-access.js +3 -1
  163. package/dist/mcp/server-tool-access.js.map +1 -1
  164. package/dist/mcp/server.d.ts +3 -0
  165. package/dist/mcp/server.d.ts.map +1 -1
  166. package/dist/mcp/server.js +5 -3
  167. package/dist/mcp/server.js.map +1 -1
  168. package/dist/mcp/tool-registry.d.ts.map +1 -1
  169. package/dist/mcp/tool-registry.js +18 -0
  170. package/dist/mcp/tool-registry.js.map +1 -1
  171. package/dist/mcp/tools/code-find.d.ts.map +1 -1
  172. package/dist/mcp/tools/code-find.js +20 -0
  173. package/dist/mcp/tools/code-find.js.map +1 -1
  174. package/dist/mcp/tools/code-show.d.ts.map +1 -1
  175. package/dist/mcp/tools/code-show.js +24 -0
  176. package/dist/mcp/tools/code-show.js.map +1 -1
  177. package/dist/mcp/tools/diagnostic-models.d.ts +2 -0
  178. package/dist/mcp/tools/diagnostic-models.d.ts.map +1 -1
  179. package/dist/mcp/tools/doctor.d.ts.map +1 -1
  180. package/dist/mcp/tools/doctor.js +18 -1
  181. package/dist/mcp/tools/doctor.js.map +1 -1
  182. package/dist/mcp/tools/export-surface-diff.d.ts +3 -0
  183. package/dist/mcp/tools/export-surface-diff.d.ts.map +1 -0
  184. package/dist/mcp/tools/export-surface-diff.js +24 -0
  185. package/dist/mcp/tools/export-surface-diff.js.map +1 -0
  186. package/dist/mcp/tools/file-outline.js +1 -1
  187. package/dist/mcp/tools/file-outline.js.map +1 -1
  188. package/dist/mcp/tools/graft-edit.d.ts +3 -0
  189. package/dist/mcp/tools/graft-edit.d.ts.map +1 -0
  190. package/dist/mcp/tools/graft-edit.js +192 -0
  191. package/dist/mcp/tools/graft-edit.js.map +1 -0
  192. package/dist/mcp/tools/knowledge-map.d.ts +3 -0
  193. package/dist/mcp/tools/knowledge-map.d.ts.map +1 -0
  194. package/dist/mcp/tools/knowledge-map.js +31 -0
  195. package/dist/mcp/tools/knowledge-map.js.map +1 -0
  196. package/dist/mcp/tools/monitor-nudge.d.ts +3 -0
  197. package/dist/mcp/tools/monitor-nudge.d.ts.map +1 -0
  198. package/dist/mcp/tools/monitor-nudge.js +17 -0
  199. package/dist/mcp/tools/monitor-nudge.js.map +1 -0
  200. package/dist/mcp/tools/precision-warp.d.ts +3 -3
  201. package/dist/mcp/tools/precision-warp.d.ts.map +1 -1
  202. package/dist/mcp/tools/precision-warp.js +24 -15
  203. package/dist/mcp/tools/precision-warp.js.map +1 -1
  204. package/dist/mcp/tools/refactor-difficulty.d.ts +3 -0
  205. package/dist/mcp/tools/refactor-difficulty.d.ts.map +1 -0
  206. package/dist/mcp/tools/refactor-difficulty.js +36 -0
  207. package/dist/mcp/tools/refactor-difficulty.js.map +1 -0
  208. package/dist/mcp/tools/safe-read.js +2 -2
  209. package/dist/mcp/tools/safe-read.js.map +1 -1
  210. package/dist/mcp/tools/structural-blame.d.ts +3 -0
  211. package/dist/mcp/tools/structural-blame.d.ts.map +1 -0
  212. package/dist/mcp/tools/structural-blame.js +44 -0
  213. package/dist/mcp/tools/structural-blame.js.map +1 -0
  214. package/dist/mcp/tools/structural-churn.d.ts +3 -0
  215. package/dist/mcp/tools/structural-churn.d.ts.map +1 -0
  216. package/dist/mcp/tools/structural-churn.js +28 -0
  217. package/dist/mcp/tools/structural-churn.js.map +1 -0
  218. package/dist/mcp/tools/structural-log.d.ts +3 -0
  219. package/dist/mcp/tools/structural-log.d.ts.map +1 -0
  220. package/dist/mcp/tools/structural-log.js +38 -0
  221. package/dist/mcp/tools/structural-log.js.map +1 -0
  222. package/dist/mcp/tools/structural-review.d.ts +3 -0
  223. package/dist/mcp/tools/structural-review.d.ts.map +1 -0
  224. package/dist/mcp/tools/structural-review.js +55 -0
  225. package/dist/mcp/tools/structural-review.js.map +1 -0
  226. package/dist/mcp/warp-pool.d.ts +4 -4
  227. package/dist/mcp/warp-pool.d.ts.map +1 -1
  228. package/dist/mcp/warp-pool.js.map +1 -1
  229. package/dist/mcp/workspace-router-model.d.ts +2 -2
  230. package/dist/mcp/workspace-router-model.d.ts.map +1 -1
  231. package/dist/mcp/workspace-router-runtime.d.ts +3 -3
  232. package/dist/mcp/workspace-router-runtime.d.ts.map +1 -1
  233. package/dist/mcp/workspace-router-runtime.js +4 -1
  234. package/dist/mcp/workspace-router-runtime.js.map +1 -1
  235. package/dist/mcp/workspace-router.d.ts +3 -2
  236. package/dist/mcp/workspace-router.d.ts.map +1 -1
  237. package/dist/mcp/workspace-router.js +6 -0
  238. package/dist/mcp/workspace-router.js.map +1 -1
  239. package/dist/operations/adaptive-projection.d.ts +22 -0
  240. package/dist/operations/adaptive-projection.d.ts.map +1 -0
  241. package/dist/operations/adaptive-projection.js +36 -0
  242. package/dist/operations/adaptive-projection.js.map +1 -0
  243. package/dist/operations/agent-handoff.d.ts +25 -0
  244. package/dist/operations/agent-handoff.d.ts.map +1 -0
  245. package/dist/operations/agent-handoff.js +36 -0
  246. package/dist/operations/agent-handoff.js.map +1 -0
  247. package/dist/operations/capture-range.d.ts +33 -0
  248. package/dist/operations/capture-range.d.ts.map +1 -0
  249. package/dist/operations/capture-range.js +45 -0
  250. package/dist/operations/capture-range.js.map +1 -0
  251. package/dist/operations/conversation-primer.d.ts +27 -0
  252. package/dist/operations/conversation-primer.d.ts.map +1 -0
  253. package/dist/operations/conversation-primer.js +52 -0
  254. package/dist/operations/conversation-primer.js.map +1 -0
  255. package/dist/operations/cross-session-resume.d.ts +28 -0
  256. package/dist/operations/cross-session-resume.d.ts.map +1 -0
  257. package/dist/operations/cross-session-resume.js +79 -0
  258. package/dist/operations/cross-session-resume.js.map +1 -0
  259. package/dist/operations/deterministic-replay.d.ts +39 -0
  260. package/dist/operations/deterministic-replay.d.ts.map +1 -0
  261. package/dist/operations/deterministic-replay.js +90 -0
  262. package/dist/operations/deterministic-replay.js.map +1 -0
  263. package/dist/operations/export-surface-diff.d.ts +36 -0
  264. package/dist/operations/export-surface-diff.d.ts.map +1 -0
  265. package/dist/operations/export-surface-diff.js +298 -0
  266. package/dist/operations/export-surface-diff.js.map +1 -0
  267. package/dist/operations/footprint-parallelism.d.ts +25 -0
  268. package/dist/operations/footprint-parallelism.d.ts.map +1 -0
  269. package/dist/operations/footprint-parallelism.js +79 -0
  270. package/dist/operations/footprint-parallelism.js.map +1 -0
  271. package/dist/operations/graft-diff.d.ts.map +1 -1
  272. package/dist/operations/graft-diff.js +14 -7
  273. package/dist/operations/graft-diff.js.map +1 -1
  274. package/dist/operations/horizon-of-readability.d.ts +23 -0
  275. package/dist/operations/horizon-of-readability.d.ts.map +1 -0
  276. package/dist/operations/horizon-of-readability.js +39 -0
  277. package/dist/operations/horizon-of-readability.js.map +1 -0
  278. package/dist/operations/import-reference-impact.d.ts +13 -0
  279. package/dist/operations/import-reference-impact.d.ts.map +1 -0
  280. package/dist/operations/import-reference-impact.js +101 -0
  281. package/dist/operations/import-reference-impact.js.map +1 -0
  282. package/dist/operations/knowledge-map.d.ts +30 -0
  283. package/dist/operations/knowledge-map.d.ts.map +1 -0
  284. package/dist/operations/knowledge-map.js +64 -0
  285. package/dist/operations/knowledge-map.js.map +1 -0
  286. package/dist/operations/observation-cache.d.ts +8 -2
  287. package/dist/operations/observation-cache.d.ts.map +1 -1
  288. package/dist/operations/observation-cache.js +17 -5
  289. package/dist/operations/observation-cache.js.map +1 -1
  290. package/dist/operations/projection-safety.d.ts +31 -0
  291. package/dist/operations/projection-safety.d.ts.map +1 -0
  292. package/dist/operations/projection-safety.js +77 -0
  293. package/dist/operations/projection-safety.js.map +1 -0
  294. package/dist/operations/repo-workspace.js +3 -3
  295. package/dist/operations/repo-workspace.js.map +1 -1
  296. package/dist/operations/semantic-drift.d.ts +27 -0
  297. package/dist/operations/semantic-drift.d.ts.map +1 -0
  298. package/dist/operations/semantic-drift.js +46 -0
  299. package/dist/operations/semantic-drift.js.map +1 -0
  300. package/dist/operations/session-filtration.d.ts +36 -0
  301. package/dist/operations/session-filtration.d.ts.map +1 -0
  302. package/dist/operations/session-filtration.js +48 -0
  303. package/dist/operations/session-filtration.js.map +1 -0
  304. package/dist/operations/session-replay.d.ts +17 -0
  305. package/dist/operations/session-replay.d.ts.map +1 -0
  306. package/dist/operations/session-replay.js +59 -0
  307. package/dist/operations/session-replay.js.map +1 -0
  308. package/dist/operations/sludge-detector.d.ts +45 -0
  309. package/dist/operations/sludge-detector.d.ts.map +1 -0
  310. package/dist/operations/sludge-detector.js +278 -0
  311. package/dist/operations/sludge-detector.js.map +1 -0
  312. package/dist/operations/structural-blame.d.ts +67 -0
  313. package/dist/operations/structural-blame.d.ts.map +1 -0
  314. package/dist/operations/structural-blame.js +111 -0
  315. package/dist/operations/structural-blame.js.map +1 -0
  316. package/dist/operations/structural-review.d.ts +47 -0
  317. package/dist/operations/structural-review.d.ts.map +1 -0
  318. package/dist/operations/structural-review.js +225 -0
  319. package/dist/operations/structural-review.js.map +1 -0
  320. package/dist/operations/teaching-hints.d.ts +18 -0
  321. package/dist/operations/teaching-hints.d.ts.map +1 -0
  322. package/dist/operations/teaching-hints.js +35 -0
  323. package/dist/operations/teaching-hints.js.map +1 -0
  324. package/dist/parser/diff.d.ts +2 -0
  325. package/dist/parser/diff.d.ts.map +1 -1
  326. package/dist/parser/diff.js +7 -0
  327. package/dist/parser/diff.js.map +1 -1
  328. package/dist/ports/paths.d.ts +17 -0
  329. package/dist/ports/paths.d.ts.map +1 -0
  330. package/dist/ports/{warp.js → paths.js} +2 -2
  331. package/dist/ports/paths.js.map +1 -0
  332. package/dist/warp/ast-emitter.d.ts +28 -0
  333. package/dist/warp/ast-emitter.d.ts.map +1 -0
  334. package/dist/warp/ast-emitter.js +90 -0
  335. package/dist/warp/ast-emitter.js.map +1 -0
  336. package/dist/warp/ast-import-resolver.d.ts +13 -0
  337. package/dist/warp/ast-import-resolver.d.ts.map +1 -0
  338. package/dist/warp/ast-import-resolver.js +259 -0
  339. package/dist/warp/ast-import-resolver.js.map +1 -0
  340. package/dist/warp/commit-meta.d.ts +8 -0
  341. package/dist/warp/commit-meta.d.ts.map +1 -0
  342. package/dist/warp/commit-meta.js +13 -0
  343. package/dist/warp/commit-meta.js.map +1 -0
  344. package/dist/warp/context.d.ts +10 -0
  345. package/dist/warp/context.d.ts.map +1 -0
  346. package/dist/warp/context.js +26 -0
  347. package/dist/warp/context.js.map +1 -0
  348. package/dist/warp/dead-symbols.d.ts +40 -0
  349. package/dist/warp/dead-symbols.d.ts.map +1 -0
  350. package/dist/warp/dead-symbols.js +127 -0
  351. package/dist/warp/dead-symbols.js.map +1 -0
  352. package/dist/warp/drift-sentinel.d.ts +30 -0
  353. package/dist/warp/drift-sentinel.d.ts.map +1 -0
  354. package/dist/warp/drift-sentinel.js +65 -0
  355. package/dist/warp/drift-sentinel.js.map +1 -0
  356. package/dist/warp/index-head.d.ts +32 -0
  357. package/dist/warp/index-head.d.ts.map +1 -0
  358. package/dist/warp/index-head.js +245 -0
  359. package/dist/warp/index-head.js.map +1 -0
  360. package/dist/warp/observers.d.ts +6 -6
  361. package/dist/warp/observers.d.ts.map +1 -1
  362. package/dist/warp/observers.js +5 -4
  363. package/dist/warp/observers.js.map +1 -1
  364. package/dist/warp/open.d.ts +5 -4
  365. package/dist/warp/open.d.ts.map +1 -1
  366. package/dist/warp/open.js +24 -49
  367. package/dist/warp/open.js.map +1 -1
  368. package/dist/warp/outline-diff-trailer.d.ts +26 -0
  369. package/dist/warp/outline-diff-trailer.d.ts.map +1 -0
  370. package/dist/warp/outline-diff-trailer.js +68 -0
  371. package/dist/warp/outline-diff-trailer.js.map +1 -0
  372. package/dist/warp/refactor-difficulty.d.ts +38 -0
  373. package/dist/warp/refactor-difficulty.d.ts.map +1 -0
  374. package/dist/warp/refactor-difficulty.js +169 -0
  375. package/dist/warp/refactor-difficulty.js.map +1 -0
  376. package/dist/warp/references.d.ts +22 -0
  377. package/dist/warp/references.d.ts.map +1 -0
  378. package/dist/warp/references.js +57 -0
  379. package/dist/warp/references.js.map +1 -0
  380. package/dist/warp/stale-docs.d.ts +56 -0
  381. package/dist/warp/stale-docs.d.ts.map +1 -0
  382. package/dist/warp/stale-docs.js +149 -0
  383. package/dist/warp/stale-docs.js.map +1 -0
  384. package/dist/warp/structural-drift-detection.d.ts +49 -0
  385. package/dist/warp/structural-drift-detection.d.ts.map +1 -0
  386. package/dist/warp/structural-drift-detection.js +51 -0
  387. package/dist/warp/structural-drift-detection.js.map +1 -0
  388. package/dist/warp/structural-queries.d.ts +49 -0
  389. package/dist/warp/structural-queries.d.ts.map +1 -0
  390. package/dist/warp/structural-queries.js +175 -0
  391. package/dist/warp/structural-queries.js.map +1 -0
  392. package/dist/warp/symbol-timeline.d.ts +34 -0
  393. package/dist/warp/symbol-timeline.d.ts.map +1 -0
  394. package/dist/warp/symbol-timeline.js +127 -0
  395. package/dist/warp/symbol-timeline.js.map +1 -0
  396. package/dist/warp/traverse-hydrate.d.ts +23 -0
  397. package/dist/warp/traverse-hydrate.d.ts.map +1 -0
  398. package/dist/warp/traverse-hydrate.js +39 -0
  399. package/dist/warp/traverse-hydrate.js.map +1 -0
  400. package/dist/warp/warp-reference-count.d.ts +19 -0
  401. package/dist/warp/warp-reference-count.d.ts.map +1 -0
  402. package/dist/warp/warp-reference-count.js +32 -0
  403. package/dist/warp/warp-reference-count.js.map +1 -0
  404. package/dist/warp/warp-structural-blame.d.ts +20 -0
  405. package/dist/warp/warp-structural-blame.d.ts.map +1 -0
  406. package/dist/warp/warp-structural-blame.js +43 -0
  407. package/dist/warp/warp-structural-blame.js.map +1 -0
  408. package/dist/warp/warp-structural-churn.d.ts +30 -0
  409. package/dist/warp/warp-structural-churn.d.ts.map +1 -0
  410. package/dist/warp/warp-structural-churn.js +213 -0
  411. package/dist/warp/warp-structural-churn.js.map +1 -0
  412. package/dist/warp/warp-structural-log.d.ts +35 -0
  413. package/dist/warp/warp-structural-log.d.ts.map +1 -0
  414. package/dist/warp/warp-structural-log.js +104 -0
  415. package/dist/warp/warp-structural-log.js.map +1 -0
  416. package/docs/CLI.md +68 -4
  417. package/docs/MCP.md +23 -0
  418. package/docs/SETUP.md +779 -0
  419. package/package.json +10 -7
  420. package/src/adapters/json-text-decoder.ts +11 -0
  421. package/src/adapters/node-paths.ts +35 -0
  422. package/src/adapters/repo-paths.ts +45 -4
  423. package/src/api/tool-bridge.ts +2 -1
  424. package/src/cli/cli-error.ts +49 -10
  425. package/src/cli/command-parser.ts +185 -3
  426. package/src/cli/daemon-status-model.ts +238 -0
  427. package/src/cli/daemon-status-render.ts +102 -0
  428. package/src/cli/daemon-status.ts +100 -0
  429. package/src/cli/git-graft-enhance-model.ts +131 -0
  430. package/src/cli/git-graft-enhance-render.ts +33 -0
  431. package/src/cli/git-graft-enhance.ts +54 -0
  432. package/src/cli/index-cmd.ts +18 -22
  433. package/src/cli/index-model.ts +21 -22
  434. package/src/cli/init-client-config.ts +167 -38
  435. package/src/cli/init-model.ts +57 -2
  436. package/src/cli/init-render.ts +2 -2
  437. package/src/cli/init.ts +11 -9
  438. package/src/cli/json-document.ts +11 -0
  439. package/src/cli/main.ts +53 -6
  440. package/src/cli/migrate-local-history.ts +3 -2
  441. package/src/cli/peer-command.ts +2 -1
  442. package/src/contracts/capabilities.ts +90 -0
  443. package/src/contracts/json-object.ts +1 -11
  444. package/src/contracts/output-schema-cli.ts +36 -3
  445. package/src/contracts/output-schema-fragments.ts +52 -2
  446. package/src/contracts/output-schema-mcp.ts +219 -0
  447. package/src/contracts/output-schemas.ts +300 -6
  448. package/src/git/diff.ts +61 -0
  449. package/src/mcp/burden.ts +9 -0
  450. package/src/mcp/context.ts +5 -42
  451. package/src/mcp/daemon-server.ts +8 -1
  452. package/src/mcp/daemon-session-host.ts +4 -0
  453. package/src/mcp/daemon-stdio-bridge.ts +2 -0
  454. package/src/mcp/monitor-tick-job.ts +90 -39
  455. package/src/mcp/monitor-types.ts +1 -1
  456. package/src/mcp/persisted-local-history-graph.ts +5 -4
  457. package/src/mcp/persisted-local-history.ts +2 -2
  458. package/src/mcp/persistent-monitor-runtime.ts +37 -0
  459. package/src/mcp/repo-tool-worker-context.ts +5 -2
  460. package/src/mcp/server-context.ts +15 -2
  461. package/src/mcp/server-tool-access.ts +4 -1
  462. package/src/mcp/server.ts +8 -3
  463. package/src/mcp/tool-registry.ts +18 -0
  464. package/src/mcp/tools/code-find.ts +23 -0
  465. package/src/mcp/tools/code-show.ts +27 -0
  466. package/src/mcp/tools/diagnostic-models.ts +2 -0
  467. package/src/mcp/tools/doctor.ts +18 -1
  468. package/src/mcp/tools/export-surface-diff.ts +26 -0
  469. package/src/mcp/tools/file-outline.ts +1 -1
  470. package/src/mcp/tools/graft-edit.ts +276 -0
  471. package/src/mcp/tools/knowledge-map.ts +34 -0
  472. package/src/mcp/tools/monitor-nudge.ts +19 -0
  473. package/src/mcp/tools/precision-warp.ts +27 -16
  474. package/src/mcp/tools/refactor-difficulty.ts +42 -0
  475. package/src/mcp/tools/safe-read.ts +2 -2
  476. package/src/mcp/tools/structural-blame.ts +55 -0
  477. package/src/mcp/tools/structural-churn.ts +28 -0
  478. package/src/mcp/tools/structural-log.ts +41 -0
  479. package/src/mcp/tools/structural-review.ts +63 -0
  480. package/src/mcp/warp-pool.ts +6 -6
  481. package/src/mcp/workspace-router-model.ts +2 -2
  482. package/src/mcp/workspace-router-runtime.ts +11 -8
  483. package/src/mcp/workspace-router.ts +9 -2
  484. package/src/operations/adaptive-projection.ts +54 -0
  485. package/src/operations/agent-handoff.ts +59 -0
  486. package/src/operations/capture-range.ts +64 -0
  487. package/src/operations/conversation-primer.ts +82 -0
  488. package/src/operations/cross-session-resume.ts +104 -0
  489. package/src/operations/deterministic-replay.ts +143 -0
  490. package/src/operations/export-surface-diff.ts +355 -0
  491. package/src/operations/footprint-parallelism.ts +98 -0
  492. package/src/operations/graft-diff.ts +14 -7
  493. package/src/operations/horizon-of-readability.ts +60 -0
  494. package/src/operations/import-reference-impact.ts +143 -0
  495. package/src/operations/knowledge-map.ts +96 -0
  496. package/src/operations/observation-cache.ts +20 -4
  497. package/src/operations/projection-safety.ts +111 -0
  498. package/src/operations/repo-workspace.ts +3 -3
  499. package/src/operations/semantic-drift.ts +70 -0
  500. package/src/operations/session-filtration.ts +76 -0
  501. package/src/operations/session-replay.ts +73 -0
  502. package/src/operations/sludge-detector.ts +356 -0
  503. package/src/operations/structural-blame.ts +197 -0
  504. package/src/operations/structural-review.ts +317 -0
  505. package/src/operations/teaching-hints.ts +52 -0
  506. package/src/parser/diff.ts +7 -0
  507. package/src/ports/paths.ts +22 -0
  508. package/src/warp/ast-emitter.ts +133 -0
  509. package/src/warp/ast-import-resolver.ts +333 -0
  510. package/src/warp/commit-meta.ts +19 -0
  511. package/src/warp/context.ts +48 -0
  512. package/src/warp/dead-symbols.ts +174 -0
  513. package/src/warp/drift-sentinel.ts +101 -0
  514. package/src/warp/index-head.ts +348 -0
  515. package/src/warp/observers.ts +8 -7
  516. package/src/warp/open.ts +40 -66
  517. package/src/warp/outline-diff-trailer.ts +100 -0
  518. package/src/warp/plumbing.d.ts +11 -2
  519. package/src/warp/refactor-difficulty.ts +257 -0
  520. package/src/warp/references.ts +77 -0
  521. package/src/warp/stale-docs.ts +210 -0
  522. package/src/warp/structural-drift-detection.ts +97 -0
  523. package/src/warp/structural-queries.ts +258 -0
  524. package/src/warp/symbol-timeline.ts +209 -0
  525. package/src/warp/traverse-hydrate.ts +61 -0
  526. package/src/warp/warp-reference-count.ts +47 -0
  527. package/src/warp/warp-structural-blame.ts +65 -0
  528. package/src/warp/warp-structural-churn.ts +309 -0
  529. package/src/warp/warp-structural-log.ts +149 -0
  530. package/dist/ports/warp.d.ts +0 -45
  531. package/dist/ports/warp.d.ts.map +0 -1
  532. package/dist/ports/warp.js.map +0 -1
  533. package/dist/warp/identity-resolver.d.ts +0 -14
  534. package/dist/warp/identity-resolver.d.ts.map +0 -1
  535. package/dist/warp/identity-resolver.js +0 -31
  536. package/dist/warp/identity-resolver.js.map +0 -1
  537. package/dist/warp/indexer-git.d.ts +0 -22
  538. package/dist/warp/indexer-git.d.ts.map +0 -1
  539. package/dist/warp/indexer-git.js +0 -148
  540. package/dist/warp/indexer-git.js.map +0 -1
  541. package/dist/warp/indexer-graph.d.ts +0 -17
  542. package/dist/warp/indexer-graph.d.ts.map +0 -1
  543. package/dist/warp/indexer-graph.js +0 -179
  544. package/dist/warp/indexer-graph.js.map +0 -1
  545. package/dist/warp/indexer-model.d.ts +0 -51
  546. package/dist/warp/indexer-model.d.ts.map +0 -1
  547. package/dist/warp/indexer-model.js +0 -21
  548. package/dist/warp/indexer-model.js.map +0 -1
  549. package/dist/warp/indexer.d.ts +0 -9
  550. package/dist/warp/indexer.d.ts.map +0 -1
  551. package/dist/warp/indexer.js +0 -112
  552. package/dist/warp/indexer.js.map +0 -1
  553. package/dist/warp/symbol-identity.d.ts +0 -11
  554. package/dist/warp/symbol-identity.d.ts.map +0 -1
  555. package/dist/warp/symbol-identity.js +0 -67
  556. package/dist/warp/symbol-identity.js.map +0 -1
  557. package/src/ports/warp.ts +0 -55
  558. package/src/warp/identity-resolver.ts +0 -35
  559. package/src/warp/indexer-git.ts +0 -182
  560. package/src/warp/indexer-graph.ts +0 -276
  561. package/src/warp/indexer-model.ts +0 -69
  562. package/src/warp/indexer.ts +0 -186
  563. package/src/warp/symbol-identity.ts +0 -100
@@ -1,6 +1,7 @@
1
1
  import type { ToolDefinition } from "./context.js";
2
2
 
3
3
  import { safeReadTool } from "./tools/safe-read.js";
4
+ import { graftEditTool } from "./tools/graft-edit.js";
4
5
  import { fileOutlineTool } from "./tools/file-outline.js";
5
6
  import { readRangeTool } from "./tools/read-range.js";
6
7
  import { changedSinceTool } from "./tools/changed-since.js";
@@ -16,15 +17,23 @@ import { mapTool } from "./tools/map.js";
16
17
  import { codeShowTool } from "./tools/code-show.js";
17
18
  import { codeFindTool } from "./tools/code-find.js";
18
19
  import { codeRefsTool } from "./tools/code-refs.js";
20
+ import { structuralChurnTool } from "./tools/structural-churn.js";
21
+ import { exportSurfaceDiffTool } from "./tools/export-surface-diff.js";
22
+ import { structuralLogTool } from "./tools/structural-log.js";
23
+ import { structuralBlameTool } from "./tools/structural-blame.js";
24
+ import { refactorDifficultyTool } from "./tools/refactor-difficulty.js";
25
+ import { structuralReviewTool } from "./tools/structural-review.js";
19
26
  import { daemonMonitorsTool } from "./tools/daemon-monitors.js";
20
27
  import { daemonReposTool } from "./tools/daemon-repos.js";
21
28
  import { daemonSessionsTool } from "./tools/daemon-sessions.js";
22
29
  import { daemonStatusTool } from "./tools/daemon-status.js";
23
30
  import { monitorPauseTool } from "./tools/monitor-pause.js";
24
31
  import { monitorResumeTool } from "./tools/monitor-resume.js";
32
+ import { monitorNudgeTool } from "./tools/monitor-nudge.js";
25
33
  import { monitorStartTool } from "./tools/monitor-start.js";
26
34
  import { monitorStopTool } from "./tools/monitor-stop.js";
27
35
  import { activityViewTool } from "./tools/activity-view.js";
36
+ import { knowledgeMapTool } from "./tools/knowledge-map.js";
28
37
  import { causalStatusTool } from "./tools/causal-status.js";
29
38
  import { causalAttachTool } from "./tools/causal-attach.js";
30
39
  import { workspaceAuthorizeTool } from "./tools/workspace-authorize.js";
@@ -36,6 +45,7 @@ import { workspaceRebindTool } from "./tools/workspace-rebind.js";
36
45
 
37
46
  export const TOOL_REGISTRY: readonly ToolDefinition[] = [
38
47
  safeReadTool,
48
+ graftEditTool,
39
49
  fileOutlineTool,
40
50
  readRangeTool,
41
51
  changedSinceTool,
@@ -55,6 +65,13 @@ export const TOOL_REGISTRY: readonly ToolDefinition[] = [
55
65
  codeShowTool,
56
66
  codeFindTool,
57
67
  codeRefsTool,
68
+ structuralChurnTool,
69
+ exportSurfaceDiffTool,
70
+ structuralLogTool,
71
+ structuralBlameTool,
72
+ refactorDifficultyTool,
73
+ structuralReviewTool,
74
+ knowledgeMapTool,
58
75
  ];
59
76
 
60
77
  export const DAEMON_TOOL_REGISTRY: readonly ToolDefinition[] = [
@@ -65,6 +82,7 @@ export const DAEMON_TOOL_REGISTRY: readonly ToolDefinition[] = [
65
82
  monitorStartTool,
66
83
  monitorPauseTool,
67
84
  monitorResumeTool,
85
+ monitorNudgeTool,
68
86
  monitorStopTool,
69
87
  workspaceAuthorizeTool,
70
88
  workspaceAuthorizationsTool,
@@ -1,5 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import type { ToolDefinition, ToolContext, ToolHandler } from "../context.js";
3
+ import { nodePathOps } from "../../adapters/node-paths.js";
4
+ import { indexHead } from "../../warp/index-head.js";
3
5
  import { GitFileQuery, listGitFiles } from "./git-files.js";
4
6
  import {
5
7
  evaluatePrecisionPolicy,
@@ -57,6 +59,26 @@ interface CodeFindOptions {
57
59
  readonly allowWarp: boolean;
58
60
  }
59
61
 
62
+ async function lazyIndexReadPaths(
63
+ ctx: ToolContext,
64
+ paths: readonly string[],
65
+ dirty: boolean,
66
+ ): Promise<void> {
67
+ if (dirty || paths.length === 0) return;
68
+ try {
69
+ const warp = await ctx.getWarp();
70
+ await indexHead({
71
+ cwd: ctx.projectRoot,
72
+ git: ctx.git,
73
+ pathOps: nodePathOps,
74
+ ctx: warp,
75
+ paths: [...new Set(paths)],
76
+ });
77
+ } catch {
78
+ // Lazy indexing must never turn a successful read/search into a failure.
79
+ }
80
+ }
81
+
60
82
  export async function runCodeFind(
61
83
  ctx: ToolContext,
62
84
  args: Record<string, unknown>,
@@ -140,6 +162,7 @@ export async function runCodeFind(
140
162
  paths: [...new Set(visibleMatches.map((m) => m.path))],
141
163
  symbols: visibleMatches.map((m) => m.name),
142
164
  });
165
+ await lazyIndexReadPaths(ctx, visibleMatches.map((m) => m.path), repoState.dirty);
143
166
 
144
167
  return ctx.respond("code_find", {
145
168
  query: request.query,
@@ -1,6 +1,8 @@
1
1
  import { z } from "zod";
2
2
  import { readRange } from "../../operations/read-range.js";
3
3
  import type { ToolDefinition, ToolContext, ToolHandler } from "../context.js";
4
+ import { nodePathOps } from "../../adapters/node-paths.js";
5
+ import { indexHead } from "../../warp/index-head.js";
4
6
  import { listProjectFiles } from "./git-files.js";
5
7
  import {
6
8
  evaluatePrecisionPolicy,
@@ -21,6 +23,26 @@ interface CodeShowOptions {
21
23
  readonly allowWarp: boolean;
22
24
  }
23
25
 
26
+ async function lazyIndexReadPaths(
27
+ ctx: ToolContext,
28
+ paths: readonly string[],
29
+ dirty: boolean,
30
+ ): Promise<void> {
31
+ if (dirty || paths.length === 0) return;
32
+ try {
33
+ const warp = await ctx.getWarp();
34
+ await indexHead({
35
+ cwd: ctx.projectRoot,
36
+ git: ctx.git,
37
+ pathOps: nodePathOps,
38
+ ctx: warp,
39
+ paths: [...new Set(paths)],
40
+ });
41
+ } catch {
42
+ // Lazy indexing is a cache refresh. It must not break the read response.
43
+ }
44
+ }
45
+
24
46
  export async function runCodeShow(
25
47
  ctx: ToolContext,
26
48
  args: Record<string, unknown>,
@@ -186,6 +208,7 @@ export async function runCodeShow(
186
208
  paths: [...new Set(visibleLocations.map((m) => m.path))],
187
209
  symbols: visibleLocations.map((m) => m.name),
188
210
  });
211
+ await lazyIndexReadPaths(ctx, visibleLocations.map((m) => m.path), repoState.dirty);
189
212
  return ctx.respond("code_show", {
190
213
  symbol: symbolName,
191
214
  ambiguous: true,
@@ -197,6 +220,9 @@ export async function runCodeShow(
197
220
 
198
221
  const loc = visibleLocations[0];
199
222
  if (loc?.startLine === undefined || loc.endLine === undefined) {
223
+ if (loc?.path !== undefined) {
224
+ await lazyIndexReadPaths(ctx, [loc.path], repoState.dirty);
225
+ }
200
226
  return ctx.respond("code_show", {
201
227
  symbol: symbolName,
202
228
  kind: loc?.kind,
@@ -228,6 +254,7 @@ export async function runCodeShow(
228
254
  symbols: [loc.name],
229
255
  regions: [{ path: loc.path, startLine: loc.startLine, endLine: loc.endLine }],
230
256
  });
257
+ await lazyIndexReadPaths(ctx, [loc.path], repoState.dirty);
231
258
 
232
259
  return ctx.respond("code_show", {
233
260
  symbol: loc.name,
@@ -12,6 +12,7 @@ import type {
12
12
  } from "../persisted-local-history.js";
13
13
  import type { RuntimeWorkspaceOverlayFooting } from "../runtime-workspace-overlay.js";
14
14
  import type { CausalSurfaceNextAction } from "../../contracts/causal-surface-next-action.js";
15
+ import type { SludgeReport } from "../../operations/sludge-detector.js";
15
16
 
16
17
  export interface SetBudgetResponse {
17
18
  readonly budget: {
@@ -72,6 +73,7 @@ export interface DoctorResponse {
72
73
  readonly attribution: PersistedLocalHistorySummary["attribution"];
73
74
  readonly persistedLocalHistory: PersistedLocalHistorySummary;
74
75
  readonly recommendedNextAction: CausalSurfaceNextAction;
76
+ readonly sludge?: SludgeReport | undefined;
75
77
  }
76
78
 
77
79
  export interface RunCapturePolicyBoundary {
@@ -5,14 +5,30 @@ import { deriveCausalSurfaceNextAction } from "../semantic-transition-guidance.j
5
5
  import type { ToolDefinition, ToolHandler } from "../context.js";
6
6
  import { toJsonObject } from "../../operations/result-dto.js";
7
7
  import type { DoctorResponse } from "./diagnostic-models.js";
8
+ import { detectSludge } from "../../operations/sludge-detector.js";
9
+ import { z } from "zod";
8
10
 
9
11
  export const doctorTool: ToolDefinition = {
10
12
  name: "doctor",
11
13
  description:
12
14
  "Runtime health check. Shows project root, parser status, active " +
13
15
  "thresholds, session depth, message count, and burden summary.",
16
+ schema: {
17
+ sludge: z.boolean().optional(),
18
+ path: z.string().optional(),
19
+ },
14
20
  createHandler(): ToolHandler {
15
- return async (_args, ctx) => {
21
+ return async (args, ctx) => {
22
+ const pathArg = typeof args["path"] === "string" ? args["path"] : undefined;
23
+ const sludge = args["sludge"] === true
24
+ ? await detectSludge({
25
+ cwd: ctx.projectRoot,
26
+ fs: ctx.fs,
27
+ git: ctx.git,
28
+ resolvePath: (filePath) => ctx.resolvePath(filePath),
29
+ ...(pathArg !== undefined ? { path: pathArg } : {}),
30
+ })
31
+ : undefined;
16
32
  const repoState = ctx.getRepoState();
17
33
  const causalContext = ctx.getCausalContext();
18
34
  const workspaceOverlayFooting = await ctx.getWorkspaceOverlayFooting();
@@ -59,6 +75,7 @@ export const doctorTool: ToolDefinition = {
59
75
  attribution: persistedLocalHistory.attribution,
60
76
  persistedLocalHistory,
61
77
  recommendedNextAction,
78
+ ...(sludge !== undefined ? { sludge } : {}),
62
79
  };
63
80
  return ctx.respond("doctor", toJsonObject(response));
64
81
  };
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+ import { exportSurfaceDiff, exportSurfaceDiffToJson } from "../../operations/export-surface-diff.js";
3
+ import type { ToolDefinition, ToolHandler } from "../context.js";
4
+
5
+ export const exportSurfaceDiffTool: ToolDefinition = {
6
+ name: "graft_exports",
7
+ description:
8
+ "Export surface diff — what changed in the public API between two " +
9
+ "refs? Identifies added, removed, and signature-changed exported " +
10
+ "symbols and derives semver impact.",
11
+ schema: {
12
+ base: z.string().optional(),
13
+ head: z.string().optional(),
14
+ },
15
+ createHandler(): ToolHandler {
16
+ return async (args, ctx) => {
17
+ const result = await exportSurfaceDiff({
18
+ cwd: ctx.projectRoot,
19
+ git: ctx.git,
20
+ base: args["base"] as string | undefined,
21
+ head: args["head"] as string | undefined,
22
+ });
23
+ return ctx.respond("graft_exports", exportSurfaceDiffToJson(result));
24
+ };
25
+ },
26
+ };
@@ -31,7 +31,7 @@ export const fileOutlineTool: ToolDefinition = {
31
31
  if (rawContent !== null && outlineSupported) {
32
32
  const cacheResult = ctx.cache.check(filePath, rawContent);
33
33
  if (cacheResult.hit) {
34
- cacheResult.obs.touch();
34
+ cacheResult.obs.touch(ctx.cache.now());
35
35
  ctx.metrics.recordCacheHit(cacheResult.obs.actual.bytes);
36
36
  ctx.recordFootprint({
37
37
  symbols: cacheResult.obs.outline.map((e) => e.name),
@@ -0,0 +1,276 @@
1
+ import { z } from "zod";
2
+ import { evaluateMcpPolicy } from "../policy.js";
3
+ import { RefusedResult } from "../../policy/types.js";
4
+ import type { ToolDefinition, ToolHandler } from "../context.js";
5
+
6
+ type GraftEditReason =
7
+ | "NOT_FOUND"
8
+ | "OLD_STRING_NOT_FOUND"
9
+ | "OLD_STRING_AMBIGUOUS"
10
+ | RefusedResult["reason"];
11
+
12
+ type DriftPattern = "jsdoc_typedef";
13
+ type DriftDirection = "removed" | "added";
14
+
15
+ interface GraftEditDriftObservation {
16
+ readonly pattern: DriftPattern;
17
+ readonly path: string;
18
+ readonly direction: DriftDirection;
19
+ }
20
+
21
+ interface GraftEditDriftWarning {
22
+ readonly kind: "structural_pattern_reintroduced";
23
+ readonly severity: "advisory";
24
+ readonly pattern: DriftPattern;
25
+ readonly basis: "session_local_graft_edit";
26
+ readonly message: string;
27
+ readonly current: {
28
+ readonly path: string;
29
+ readonly direction: "added";
30
+ };
31
+ readonly previous: {
32
+ readonly path: string;
33
+ readonly direction: "removed";
34
+ };
35
+ }
36
+
37
+ interface GraftEditResponse {
38
+ readonly path: string;
39
+ readonly operation: "replace";
40
+ readonly projection: "edited" | "refused";
41
+ readonly status: "edited" | "refused";
42
+ readonly changed: boolean;
43
+ readonly matches: number;
44
+ readonly replacements: number;
45
+ readonly reason?: GraftEditReason;
46
+ readonly reasonDetail?: string;
47
+ readonly next?: readonly string[];
48
+ readonly actual?: {
49
+ readonly lines: number;
50
+ readonly bytes: number;
51
+ };
52
+ readonly driftWarnings?: readonly GraftEditDriftWarning[];
53
+ }
54
+
55
+ function countOccurrences(content: string, needle: string): number {
56
+ if (needle.length === 0) {
57
+ return content.length + 1;
58
+ }
59
+
60
+ let count = 0;
61
+ let offset = 0;
62
+ while (offset <= content.length) {
63
+ const index = content.indexOf(needle, offset);
64
+ if (index === -1) {
65
+ return count;
66
+ }
67
+ count += 1;
68
+ offset = index + needle.length;
69
+ }
70
+ return count;
71
+ }
72
+
73
+ async function actualForFile(
74
+ content: string,
75
+ stat: () => Promise<{ size: number }>,
76
+ ): Promise<{ lines: number; bytes: number }> {
77
+ const fileStat = await stat();
78
+ return {
79
+ lines: content.split("\n").length,
80
+ bytes: fileStat.size,
81
+ };
82
+ }
83
+
84
+ function refused(input: {
85
+ readonly path: string;
86
+ readonly reason: GraftEditReason;
87
+ readonly reasonDetail?: string;
88
+ readonly next?: readonly string[];
89
+ readonly actual?: { readonly lines: number; readonly bytes: number };
90
+ readonly matches?: number;
91
+ }): GraftEditResponse {
92
+ return {
93
+ path: input.path,
94
+ operation: "replace",
95
+ projection: "refused",
96
+ status: "refused",
97
+ changed: false,
98
+ matches: input.matches ?? 0,
99
+ replacements: 0,
100
+ reason: input.reason,
101
+ ...(input.reasonDetail !== undefined ? { reasonDetail: input.reasonDetail } : {}),
102
+ ...(input.next !== undefined ? { next: [...input.next] } : {}),
103
+ ...(input.actual !== undefined ? { actual: input.actual } : {}),
104
+ };
105
+ }
106
+
107
+ function containsJsdocTypedef(content: string): boolean {
108
+ return content
109
+ .split(/\r?\n/u)
110
+ .some((line) => line.trimStart().startsWith("* @typedef "));
111
+ }
112
+
113
+ function classifyStructuralEdit(input: {
114
+ readonly path: string;
115
+ readonly oldString: string;
116
+ readonly newString: string;
117
+ }): GraftEditDriftObservation | null {
118
+ const oldHasTypedef = containsJsdocTypedef(input.oldString);
119
+ const newHasTypedef = containsJsdocTypedef(input.newString);
120
+ if (oldHasTypedef === newHasTypedef) {
121
+ return null;
122
+ }
123
+ return {
124
+ path: input.path,
125
+ pattern: "jsdoc_typedef",
126
+ direction: oldHasTypedef ? "removed" : "added",
127
+ };
128
+ }
129
+
130
+ function buildDriftWarnings(
131
+ observation: GraftEditDriftObservation | null,
132
+ priorObservations: readonly GraftEditDriftObservation[],
133
+ ): GraftEditDriftWarning[] {
134
+ if (observation?.direction !== "added") {
135
+ return [];
136
+ }
137
+
138
+ let previous: GraftEditDriftObservation | undefined;
139
+ for (let i = priorObservations.length - 1; i >= 0; i--) {
140
+ const candidate = priorObservations[i];
141
+ if (candidate?.pattern === observation.pattern && candidate.direction === "removed") {
142
+ previous = candidate;
143
+ break;
144
+ }
145
+ }
146
+ if (previous === undefined) {
147
+ return [];
148
+ }
149
+
150
+ return [{
151
+ kind: "structural_pattern_reintroduced",
152
+ severity: "advisory",
153
+ pattern: observation.pattern,
154
+ basis: "session_local_graft_edit",
155
+ message: "You are adding a typedef in a session that has been removing typedefs.",
156
+ current: {
157
+ path: observation.path,
158
+ direction: "added",
159
+ },
160
+ previous: {
161
+ path: previous.path,
162
+ direction: "removed",
163
+ },
164
+ }];
165
+ }
166
+
167
+ export const graftEditTool: ToolDefinition = {
168
+ name: "graft_edit",
169
+ description:
170
+ "Perform one governed exact string replacement in a repo file. " +
171
+ "Requires path, old_string, and new_string. Refuses missing or " +
172
+ "ambiguous old_string matches and policy-denied paths.",
173
+ schema: {
174
+ path: z.string(),
175
+ old_string: z.string(),
176
+ new_string: z.string(),
177
+ },
178
+ createHandler(): ToolHandler {
179
+ const structuralEditObservations: GraftEditDriftObservation[] = [];
180
+
181
+ return async (args, ctx) => {
182
+ const filePath = ctx.resolvePath(args["path"] as string);
183
+ const oldString = args["old_string"] as string;
184
+ const newString = args["new_string"] as string;
185
+ ctx.recordFootprint({ paths: [filePath] });
186
+
187
+ let content: string;
188
+ try {
189
+ content = await ctx.fs.readFile(filePath, "utf-8");
190
+ } catch {
191
+ ctx.metrics.recordRefusal();
192
+ return ctx.respond("graft_edit", {
193
+ ...refused({
194
+ path: filePath,
195
+ reason: "NOT_FOUND",
196
+ reasonDetail: "File does not exist or cannot be read",
197
+ next: ["Choose an existing file; graft_edit does not create files"],
198
+ }),
199
+ });
200
+ }
201
+
202
+ const actual = await actualForFile(content, () => ctx.fs.stat(filePath));
203
+ const policy = evaluateMcpPolicy(ctx, filePath, actual);
204
+ if (policy instanceof RefusedResult) {
205
+ ctx.metrics.recordRefusal();
206
+ return ctx.respond("graft_edit", {
207
+ ...refused({
208
+ path: filePath,
209
+ reason: policy.reason,
210
+ reasonDetail: policy.reasonDetail,
211
+ next: policy.next,
212
+ actual,
213
+ }),
214
+ });
215
+ }
216
+
217
+ const matches = countOccurrences(content, oldString);
218
+ if (matches === 0) {
219
+ ctx.metrics.recordRefusal();
220
+ return ctx.respond("graft_edit", {
221
+ ...refused({
222
+ path: filePath,
223
+ reason: "OLD_STRING_NOT_FOUND",
224
+ reasonDetail: "old_string does not occur in the target file",
225
+ next: ["Inspect the current file content and provide an exact old_string"],
226
+ actual,
227
+ matches,
228
+ }),
229
+ });
230
+ }
231
+
232
+ if (matches !== 1) {
233
+ ctx.metrics.recordRefusal();
234
+ return ctx.respond("graft_edit", {
235
+ ...refused({
236
+ path: filePath,
237
+ reason: "OLD_STRING_AMBIGUOUS",
238
+ reasonDetail: "old_string must occur exactly once",
239
+ next: ["Provide a longer old_string that uniquely identifies the edit site"],
240
+ actual,
241
+ matches,
242
+ }),
243
+ });
244
+ }
245
+
246
+ const nextContent = content.replace(oldString, newString);
247
+ const changed = nextContent !== content;
248
+ if (changed) {
249
+ await ctx.fs.writeFile(filePath, nextContent, "utf-8");
250
+ }
251
+
252
+ const observation = classifyStructuralEdit({
253
+ path: filePath,
254
+ oldString,
255
+ newString,
256
+ });
257
+ const driftWarnings = buildDriftWarnings(observation, structuralEditObservations);
258
+ if (observation !== null) {
259
+ structuralEditObservations.push(observation);
260
+ }
261
+
262
+ const response: GraftEditResponse = {
263
+ path: filePath,
264
+ operation: "replace",
265
+ projection: "edited",
266
+ status: "edited",
267
+ changed,
268
+ matches,
269
+ replacements: 1,
270
+ actual,
271
+ ...(driftWarnings.length > 0 ? { driftWarnings } : {}),
272
+ };
273
+ return ctx.respond("graft_edit", { ...response });
274
+ };
275
+ },
276
+ };
@@ -0,0 +1,34 @@
1
+ import { buildKnowledgeMap } from "../../operations/knowledge-map.js";
2
+ import type { ToolDefinition, ToolHandler } from "../context.js";
3
+
4
+ export const knowledgeMapTool: ToolDefinition = {
5
+ name: "knowledge_map",
6
+ description:
7
+ "Session knowledge map — answers \"what do I already know?\" " +
8
+ "Lists all files and symbols observed this session, flags stale " +
9
+ "files (changed since last read), and shows directory coverage. " +
10
+ "Use before reading more files to avoid redundant context consumption.",
11
+ createHandler(): ToolHandler {
12
+ return async (_args, ctx) => {
13
+ const result = await buildKnowledgeMap({
14
+ cache: ctx.cache,
15
+ fs: ctx.fs,
16
+ projectRoot: ctx.projectRoot,
17
+ });
18
+
19
+ return ctx.respond("knowledge_map", {
20
+ totalFiles: result.totalFiles,
21
+ totalSymbols: result.totalSymbols,
22
+ files: result.files.map((f) => ({
23
+ path: f.path,
24
+ symbols: [...f.symbols],
25
+ readCount: f.readCount,
26
+ lastReadAt: f.lastReadAt,
27
+ stale: f.stale,
28
+ })),
29
+ staleFiles: [...result.staleFiles],
30
+ directoryCoverage: result.directoryCoverage,
31
+ });
32
+ };
33
+ },
34
+ };
@@ -0,0 +1,19 @@
1
+ import { z } from "zod";
2
+ import type { ToolDefinition, ToolHandler } from "../context.js";
3
+
4
+ export const monitorNudgeTool: ToolDefinition = {
5
+ name: "monitor_nudge",
6
+ description:
7
+ "Trigger an immediate re-index tick for a running monitor. " +
8
+ "Use from post-commit hooks to notify graft that HEAD changed.",
9
+ schema: {
10
+ cwd: z.string(),
11
+ },
12
+ createHandler(): ToolHandler {
13
+ return async (args, ctx) => {
14
+ return ctx.respond("monitor_nudge", { ...await ctx.nudgeMonitor({
15
+ cwd: args["cwd"] as string,
16
+ }) });
17
+ };
18
+ },
19
+ };
@@ -1,4 +1,6 @@
1
- import type { WarpHandle } from "../../ports/warp.js";
1
+ import type { QueryResultV1 } from "@git-stunts/git-warp";
2
+ import type { WarpContext } from "../../warp/context.js";
3
+ import { observeGraph } from "../../warp/context.js";
2
4
  import { allSymbolsLens, commitsLens, fileSymbolsLens, symbolByNameLens } from "../../warp/observers.js";
3
5
  import type { RankedPrecisionSymbolMatch } from "./precision-query.js";
4
6
  import { PrecisionSearchRequest } from "./precision-query.js";
@@ -34,15 +36,20 @@ function toMatch(
34
36
  });
35
37
  }
36
38
 
37
- export async function getIndexedCommitCeilings(warp: WarpHandle): Promise<ReadonlyMap<string, number>> {
39
+ export async function getIndexedCommitCeilings(ctx: WarpContext): Promise<ReadonlyMap<string, number>> {
38
40
  const ceilings = new Map<string, number>();
39
- const observer = await warp.observer(commitsLens());
40
- const nodeIds = await observer.getNodes();
41
+ const observer = await observeGraph(ctx, commitsLens());
41
42
 
42
- for (const nodeId of nodeIds) {
43
- const props = await observer.getNodeProps(nodeId);
44
- const sha = typeof props?.["sha"] === "string" ? props["sha"] : null;
45
- const tick = typeof props?.["tick"] === "number" ? props["tick"] : null;
43
+ // Slice-first: use query API instead of getNodes() + per-node getNodeProps()
44
+ const result = await observer.query()
45
+ .match("commit:*")
46
+ .select(["id", "props"])
47
+ .run() as QueryResultV1;
48
+
49
+ for (const node of result.nodes) {
50
+ const props = node.props ?? {};
51
+ const sha = typeof props["sha"] === "string" ? props["sha"] : null;
52
+ const tick = typeof props["tick"] === "number" ? props["tick"] : null;
46
53
  if (sha !== null && tick !== null) {
47
54
  ceilings.set(sha, tick);
48
55
  }
@@ -52,7 +59,7 @@ export async function getIndexedCommitCeilings(warp: WarpHandle): Promise<Readon
52
59
  }
53
60
 
54
61
  export async function searchWarpSymbols(
55
- warp: WarpHandle,
62
+ ctx: WarpContext,
56
63
  request: PrecisionSearchRequest,
57
64
  ): Promise<PrecisionSymbolMatch[]> {
58
65
  const lensMode = request.selectLens();
@@ -71,19 +78,23 @@ export async function searchWarpSymbols(
71
78
  lens = allSymbolsLens();
72
79
  }
73
80
 
74
- const observer = await warp.observer(
81
+ const observer = await observeGraph(ctx,
75
82
  lens,
76
83
  request.ceiling !== undefined ? { source: { kind: "live", ceiling: request.ceiling } } : undefined,
77
84
  );
78
- const nodeIds = await observer.getNodes();
85
+ // Slice-first: use query API instead of getNodes() + per-node getNodeProps()
86
+ const queryResult = await observer.query()
87
+ .match("*")
88
+ .select(["id", "props"])
89
+ .run() as QueryResultV1;
79
90
 
80
- const matches = await Promise.all(nodeIds.map(async (nodeId) => {
81
- const props = await observer.getNodeProps(nodeId);
82
- if (props === null) return null;
83
- const match = toMatch(nodeId, props);
91
+ const matches = queryResult.nodes.map((node) => {
92
+ const props = node.props ?? {};
93
+ if (node.id === undefined) return null;
94
+ const match = toMatch(node.id, props);
84
95
  if (match === null) return null;
85
96
  return request.rank(match);
86
- }));
97
+ });
87
98
 
88
99
  const visibleMatches = matches.filter((match): match is RankedPrecisionSymbolMatch => match !== null);
89
100
  return request.sort(visibleMatches);