@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
@@ -0,0 +1,42 @@
1
+ import { z } from "zod";
2
+ import { toJsonObject } from "../../operations/result-dto.js";
3
+ import { refactorDifficultyFromGraph } from "../../warp/refactor-difficulty.js";
4
+ import type { ToolDefinition, ToolHandler } from "../context.js";
5
+
6
+ export const refactorDifficultyTool: ToolDefinition = {
7
+ name: "graft_difficulty",
8
+ description:
9
+ "Refactor difficulty score for a symbol. Combines WARP aggregate " +
10
+ "churn curvature with WARP reference-edge friction so agents can " +
11
+ "choose refactor vs workaround.",
12
+ schema: {
13
+ symbol: z.string(),
14
+ path: z.string().optional(),
15
+ limit: z.number().int().positive().optional(),
16
+ },
17
+ createHandler(): ToolHandler {
18
+ return async (args, ctx) => {
19
+ const symbol = args["symbol"];
20
+ const rawPath = args["path"];
21
+ const rawLimit = args["limit"];
22
+
23
+ if (typeof symbol !== "string" || symbol.trim().length === 0) {
24
+ throw new Error("graft_difficulty: symbol must be a non-empty string");
25
+ }
26
+
27
+ const warp = await ctx.getWarp();
28
+ const result = await refactorDifficultyFromGraph(warp, {
29
+ symbol,
30
+ ...(typeof rawPath === "string" ? { path: rawPath } : {}),
31
+ ...(typeof rawLimit === "number" ? { limit: rawLimit } : {}),
32
+ });
33
+
34
+ ctx.recordFootprint({
35
+ symbols: [symbol.trim()],
36
+ paths: result.entries.map((entry) => entry.filePath),
37
+ });
38
+
39
+ return ctx.respond("graft_difficulty", toJsonObject(result));
40
+ };
41
+ },
42
+ };
@@ -58,7 +58,7 @@ export const safeReadTool: ToolDefinition = {
58
58
  });
59
59
  }
60
60
 
61
- cacheResult.obs.touch();
61
+ cacheResult.obs.touch(ctx.cache.now());
62
62
  ctx.metrics.recordCacheHit(cf.actual.bytes);
63
63
  ctx.recordFootprint({
64
64
  symbols: cacheResult.obs.outline.map((e) => e.name),
@@ -108,7 +108,7 @@ export const safeReadTool: ToolDefinition = {
108
108
  jumpTable: cf.jumpTable,
109
109
  actual: cf.actual,
110
110
  readCount: newReadCount,
111
- lastReadAt: updatedObs?.lastReadAt ?? new Date().toISOString(),
111
+ lastReadAt: updatedObs?.lastReadAt ?? ctx.cache.now(),
112
112
  });
113
113
  }
114
114
  }
@@ -0,0 +1,55 @@
1
+ import { z } from "zod";
2
+ import type { ToolDefinition, ToolHandler } from "../context.js";
3
+ import { structuralBlameFromGraph } from "../../warp/warp-structural-blame.js";
4
+ import { toJsonObject } from "../../operations/result-dto.js";
5
+
6
+ export const structuralBlameTool: ToolDefinition = {
7
+ name: "graft_blame",
8
+ description:
9
+ "Symbol-level blame: who last changed a symbol's signature, when " +
10
+ "it was created, and its full change history. Returns creation " +
11
+ "commit, last signature change, change count, reference count, " +
12
+ "and chronological history.",
13
+ schema: {
14
+ symbol: z.string(),
15
+ path: z.string().optional(),
16
+ },
17
+ createHandler(): ToolHandler {
18
+ return async (args, ctx) => {
19
+ const symbol = args["symbol"];
20
+ const rawPath = args["path"];
21
+
22
+ if (typeof symbol !== "string" || symbol.trim().length === 0) {
23
+ throw new Error("graft_blame: symbol must be a non-empty string");
24
+ }
25
+
26
+ const symbolName = symbol.trim();
27
+ const filePath = typeof rawPath === "string" ? rawPath : undefined;
28
+ const warp = await ctx.getWarp();
29
+
30
+ const blame = await structuralBlameFromGraph(
31
+ warp,
32
+ symbolName,
33
+ filePath ?? "",
34
+ );
35
+
36
+ ctx.recordFootprint({ symbols: [symbolName] });
37
+
38
+ return ctx.respond("graft_blame", toJsonObject({
39
+ symbol: blame.symbol,
40
+ filePath: blame.filePath,
41
+ changeCount: blame.changeCount,
42
+ createdInCommit: blame.createdInCommit ?? null,
43
+ lastSignatureChange: blame.lastSignatureChange ?? null,
44
+ referenceCount: blame.referenceCount,
45
+ history: blame.history.map((v) => ({
46
+ sha: v.sha,
47
+ tick: v.tick,
48
+ changeKind: v.changeKind,
49
+ present: v.present,
50
+ signature: v.signature ?? null,
51
+ })),
52
+ }));
53
+ };
54
+ },
55
+ };
@@ -0,0 +1,28 @@
1
+ import { z } from "zod";
2
+ import { toJsonObject } from "../../operations/result-dto.js";
3
+ import { structuralChurnFromGraph } from "../../warp/warp-structural-churn.js";
4
+ import type { ToolDefinition, ToolHandler } from "../context.js";
5
+
6
+ export const structuralChurnTool: ToolDefinition = {
7
+ name: "graft_churn",
8
+ description:
9
+ "Structural churn report — which symbols change most frequently? " +
10
+ "Identifies maintenance hotspots by walking indexed commits and " +
11
+ "counting per-symbol change frequency.",
12
+ schema: {
13
+ path: z.string().optional(),
14
+ limit: z.number().int().positive().optional(),
15
+ },
16
+ createHandler(): ToolHandler {
17
+ return async (args, ctx) => {
18
+ const warp = await ctx.getWarp();
19
+ const options: { path?: string; limit?: number } = {};
20
+ const pathArg = args["path"];
21
+ const limitArg = args["limit"];
22
+ if (typeof pathArg === "string") options.path = pathArg;
23
+ if (typeof limitArg === "number") options.limit = limitArg;
24
+ const result = await structuralChurnFromGraph(warp, options);
25
+ return ctx.respond("graft_churn", toJsonObject(result));
26
+ };
27
+ },
28
+ };
@@ -0,0 +1,41 @@
1
+ import { z } from "zod";
2
+ import { structuralLogFromGraph } from "../../warp/warp-structural-log.js";
3
+ import { toJsonObject } from "../../operations/result-dto.js";
4
+ import type { ToolDefinition, ToolHandler } from "../context.js";
5
+
6
+ export const structuralLogTool: ToolDefinition = {
7
+ name: "graft_log",
8
+ description:
9
+ "Structural git log — shows symbol-level changes (added, removed, " +
10
+ "changed) per commit. Like `git log` but for code structure, not lines.",
11
+ schema: {
12
+ path: z.string().optional(),
13
+ limit: z.number().optional(),
14
+ },
15
+ createHandler(): ToolHandler {
16
+ return async (args, ctx) => {
17
+ const filePath = args["path"] as string | undefined;
18
+ const limit = args["limit"] as number | undefined;
19
+ const warp = await ctx.getWarp();
20
+
21
+ const options: { path?: string; limit?: number } = {};
22
+ if (filePath !== undefined) options.path = filePath;
23
+ if (limit !== undefined) options.limit = limit;
24
+ const entries = await structuralLogFromGraph(warp, options);
25
+
26
+ ctx.recordFootprint({
27
+ symbols: entries.flatMap((e) => [
28
+ ...e.symbols.added.map((s) => s.name),
29
+ ...e.symbols.removed.map((s) => s.name),
30
+ ...e.symbols.changed.map((s) => s.name),
31
+ ]),
32
+ });
33
+
34
+ return ctx.respond("graft_log", toJsonObject({
35
+ entries,
36
+ count: entries.length,
37
+ layer: "commit_worldline",
38
+ }));
39
+ };
40
+ },
41
+ };
@@ -0,0 +1,63 @@
1
+ import { z } from "zod";
2
+ import { structuralReview, type ReferenceCountResult } from "../../operations/structural-review.js";
3
+ import { toJsonObject } from "../../operations/result-dto.js";
4
+ import type { ToolContext, ToolDefinition, ToolHandler } from "../context.js";
5
+ import { countSymbolReferencesFromGraph } from "../../warp/warp-reference-count.js";
6
+ import { nodePathOps } from "../../adapters/node-paths.js";
7
+ import { countNamedImportReferencesAtRef } from "../../operations/import-reference-impact.js";
8
+
9
+ async function countReviewReferences(
10
+ ctx: ToolContext,
11
+ symbolName: string,
12
+ filePath: string,
13
+ headRef: string,
14
+ ): Promise<ReferenceCountResult> {
15
+ const warpCtx = await ctx.getWarp();
16
+ const graphResult = await countSymbolReferencesFromGraph(warpCtx, symbolName, filePath);
17
+ if (graphResult.referenceCount > 0) {
18
+ return graphResult;
19
+ }
20
+
21
+ try {
22
+ const fallbackResult = await countNamedImportReferencesAtRef({
23
+ cwd: ctx.projectRoot,
24
+ git: ctx.git,
25
+ pathOps: nodePathOps,
26
+ symbolName,
27
+ filePath,
28
+ ref: headRef,
29
+ });
30
+ return fallbackResult.referenceCount > 0 ? fallbackResult : graphResult;
31
+ } catch {
32
+ return graphResult;
33
+ }
34
+ }
35
+
36
+ export const structuralReviewTool: ToolDefinition = {
37
+ name: "graft_review",
38
+ description:
39
+ "Zero-noise structural PR review. Categorizes changed files as " +
40
+ "structural, formatting, test, docs, or config. Detects breaking " +
41
+ "changes (removed exports, changed signatures) with impact counts.",
42
+ schema: { base: z.string().optional(), head: z.string().optional() },
43
+ createHandler(): ToolHandler {
44
+ return async (args, ctx) => {
45
+ const head = args["head"] as string | undefined;
46
+ const result = await structuralReview({
47
+ cwd: ctx.projectRoot,
48
+ fs: ctx.fs,
49
+ git: ctx.git,
50
+ resolveWorkingTreePath: (filePath) => ctx.resolvePath(filePath),
51
+ base: args["base"] as string | undefined,
52
+ head,
53
+ countReferences: async (symbolName, filePath) => {
54
+ return countReviewReferences(ctx, symbolName, filePath, head ?? "HEAD");
55
+ },
56
+ });
57
+ ctx.recordFootprint({
58
+ paths: result.files.map((f) => f.path),
59
+ });
60
+ return ctx.respond("graft_review", toJsonObject(result));
61
+ };
62
+ },
63
+ };
@@ -1,22 +1,22 @@
1
- import type { WarpHandle } from "../ports/warp.js";
1
+ import type WarpApp from "@git-stunts/git-warp";
2
2
  import { DEFAULT_WARP_WRITER_ID } from "../warp/writer-id.js";
3
3
 
4
4
  export interface WarpPool {
5
- getOrOpen(repoId: string, worktreeRoot: string, writerId?: string): Promise<WarpHandle>;
5
+ getOrOpen(repoId: string, worktreeRoot: string, writerId?: string): Promise<WarpApp>;
6
6
  size(): number;
7
7
  }
8
8
 
9
9
  export class InMemoryWarpPool implements WarpPool {
10
- private readonly opened = new Map<string, Map<string, Promise<WarpHandle>>>();
10
+ private readonly opened = new Map<string, Map<string, Promise<WarpApp>>>();
11
11
 
12
- constructor(private readonly openWarp: (worktreeRoot: string, writerId: string) => Promise<WarpHandle>) {}
12
+ constructor(private readonly openWarp: (worktreeRoot: string, writerId: string) => Promise<WarpApp>) {}
13
13
 
14
- getOrOpen(repoId: string, worktreeRoot: string, writerId: string = DEFAULT_WARP_WRITER_ID): Promise<WarpHandle> {
14
+ getOrOpen(repoId: string, worktreeRoot: string, writerId: string = DEFAULT_WARP_WRITER_ID): Promise<WarpApp> {
15
15
  const repoHandles = this.opened.get(repoId);
16
16
  const cached = repoHandles?.get(writerId);
17
17
  if (cached !== undefined) return cached;
18
18
 
19
- const nextRepoHandles = repoHandles ?? new Map<string, Promise<WarpHandle>>();
19
+ const nextRepoHandles = repoHandles ?? new Map<string, Promise<WarpApp>>();
20
20
  const opened = this.openWarp(worktreeRoot, writerId).catch((error: unknown) => {
21
21
  const current = this.opened.get(repoId);
22
22
  current?.delete(writerId);
@@ -4,7 +4,7 @@ import type { RepoStateTracker } from "./repo-state.js";
4
4
  import type { RuntimeCausalContext } from "./runtime-causal-context.js";
5
5
  import type { PersistedLocalHistorySummary } from "./persisted-local-history.js";
6
6
  import type { GovernorTracker } from "../session/tracker.js";
7
- import type { WarpHandle } from "../ports/warp.js";
7
+ import type { WarpContext } from "../warp/context.js";
8
8
 
9
9
  export type WorkspaceMode = "repo_local" | "daemon";
10
10
  export type WorkspaceBindState = "bound" | "unbound";
@@ -89,7 +89,7 @@ export interface WorkspaceExecutionContext {
89
89
  readonly metrics: Metrics;
90
90
  readonly graftDir: string;
91
91
  readonly repoState: RepoStateTracker;
92
- readonly getWarp: () => Promise<WarpHandle>;
92
+ readonly getWarp: () => Promise<WarpContext>;
93
93
  }
94
94
 
95
95
  export interface ResolvedWorkspace {
@@ -2,7 +2,7 @@ import * as path from "node:path";
2
2
  import { createRepoPathResolver } from "../adapters/repo-paths.js";
3
3
  import type { FileSystem } from "../ports/filesystem.js";
4
4
  import type { GitClient } from "../ports/git.js";
5
- import type { WarpHandle } from "../ports/warp.js";
5
+ import type { WarpContext } from "../warp/context.js";
6
6
  import { DEFAULT_WARP_WRITER_ID } from "../warp/writer-id.js";
7
7
  import { GovernorTracker } from "../session/tracker.js";
8
8
  import { ObservationCache } from "./cache.js";
@@ -48,7 +48,7 @@ export interface BoundWorkspace {
48
48
  readonly warpWriterId: string;
49
49
  readonly transportSessionId: string;
50
50
  readonly slice: WorkspaceSlice;
51
- readonly getWarp: () => Promise<WarpHandle>;
51
+ readonly getWarp: () => Promise<WarpContext>;
52
52
  }
53
53
 
54
54
  export function createWorkspaceSlice(input: {
@@ -94,11 +94,14 @@ export async function createBoundWorkspace(input: {
94
94
  transportSessionId: input.transportSessionId,
95
95
  warpWriterId: input.warpWriterId ?? DEFAULT_WARP_WRITER_ID,
96
96
  slice: input.slice,
97
- getWarp: () => input.warpPool.getOrOpen(
98
- input.resolved.repoId,
99
- input.resolved.worktreeRoot,
100
- input.warpWriterId ?? DEFAULT_WARP_WRITER_ID,
101
- ),
97
+ getWarp: async () => ({
98
+ app: await input.warpPool.getOrOpen(
99
+ input.resolved.repoId,
100
+ input.resolved.worktreeRoot,
101
+ input.warpWriterId ?? DEFAULT_WARP_WRITER_ID,
102
+ ),
103
+ strandId: null,
104
+ }),
102
105
  };
103
106
  }
104
107
 
@@ -193,7 +196,7 @@ export async function resolveCheckoutBoundaryHookEvent(input: {
193
196
 
194
197
  export async function buildPersistedLocalHistoryGraphContext(
195
198
  worktreeRoot: string,
196
- getWarp: () => Promise<WarpHandle>,
199
+ getWarp: () => Promise<WarpContext>,
197
200
  ): Promise<PersistedLocalHistoryGraphContext | null> {
198
201
  try {
199
202
  return {
@@ -37,7 +37,7 @@ import {
37
37
  import { resolveWorkspaceRequest, stableWorkspaceId } from "./workspace-router-resolution.js";
38
38
  import type { FileSystem } from "../ports/filesystem.js";
39
39
  import type { GitClient } from "../ports/git.js";
40
- import type { WarpHandle } from "../ports/warp.js";
40
+ import type { WarpContext } from "../warp/context.js";
41
41
  import type { JsonObject } from "../contracts/json-object.js";
42
42
  import type { WarpPool } from "./warp-pool.js";
43
43
  import { DEFAULT_WARP_WRITER_ID } from "../warp/writer-id.js";
@@ -87,6 +87,7 @@ interface WorkspaceRouterOptions {
87
87
  readonly authorizationPolicy?: WorkspaceAuthorizationPolicy | undefined;
88
88
  readonly sharedAttachPolicy?: WorkspaceSharedAttachPolicy | undefined;
89
89
  readonly persistedLocalHistory: PersistedLocalHistoryStore;
90
+ readonly persistedLocalHistoryGraph?: boolean;
90
91
  }
91
92
 
92
93
  export class WorkspaceRouter {
@@ -197,7 +198,7 @@ export class WorkspaceRouter {
197
198
  return this.requireBinding().resolvePath;
198
199
  }
199
200
 
200
- getWarp(): Promise<WarpHandle> {
201
+ getWarp(): Promise<WarpContext> {
201
202
  return this.requireBinding().getWarp();
202
203
  }
203
204
 
@@ -670,12 +671,18 @@ export class WorkspaceRouter {
670
671
  private async buildPersistedLocalHistoryGraphContext(
671
672
  binding: BoundWorkspace,
672
673
  ): Promise<PersistedLocalHistoryGraphContext | null> {
674
+ if (this.options.persistedLocalHistoryGraph === false) {
675
+ return null;
676
+ }
673
677
  return buildPersistedLocalHistoryGraphContext(binding.worktreeRoot, binding.getWarp);
674
678
  }
675
679
 
676
680
  private async buildPersistedLocalHistoryGraphContextFromExecution(
677
681
  execution: WorkspaceExecutionContext,
678
682
  ): Promise<PersistedLocalHistoryGraphContext | null> {
683
+ if (this.options.persistedLocalHistoryGraph === false) {
684
+ return null;
685
+ }
679
686
  return buildPersistedLocalHistoryGraphContext(execution.worktreeRoot, execution.getWarp);
680
687
  }
681
688
  }
@@ -0,0 +1,54 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Adaptive Projection Selection — structural auto-selection
3
+ // ---------------------------------------------------------------------------
4
+
5
+ /** Structural metrics for projection selection. */
6
+ export interface ProjectionCandidate {
7
+ readonly fileLines: number;
8
+ readonly fileBytes: number;
9
+ readonly symbolCount: number;
10
+ readonly outlineCompressionRatio: number;
11
+ readonly targetSymbol?: string;
12
+ }
13
+
14
+ /** Selected projection with reasoning. */
15
+ export interface ProjectionSelection {
16
+ readonly projection: "outline" | "content" | "range";
17
+ readonly reason: string;
18
+ }
19
+
20
+ const SMALL_FILE_THRESHOLD = 50;
21
+ const HORIZON_RATIO = 0.7;
22
+
23
+ /**
24
+ * Select the optimal projection based on structural metrics.
25
+ *
26
+ * - Dense large files → outline (saves the most context)
27
+ * - Small or irreducibly complex files → content (outline doesn't help)
28
+ * - Targeted symbol investigation → range (surgical read)
29
+ */
30
+ export function selectProjection(candidate: ProjectionCandidate): ProjectionSelection {
31
+ // If a specific symbol is targeted, use range
32
+ if (candidate.targetSymbol !== undefined) {
33
+ return {
34
+ projection: "range",
35
+ reason: `Targeted read for symbol "${candidate.targetSymbol}" — range is most efficient.`,
36
+ };
37
+ }
38
+
39
+ // Small files or high compression ratio → content
40
+ if (candidate.fileLines <= SMALL_FILE_THRESHOLD || candidate.outlineCompressionRatio >= HORIZON_RATIO) {
41
+ return {
42
+ projection: "content",
43
+ reason: candidate.fileLines <= SMALL_FILE_THRESHOLD
44
+ ? `Small file (${String(candidate.fileLines)} lines) — content fits easily.`
45
+ : `Outline is ${String(Math.round(candidate.outlineCompressionRatio * 100))}% of content — outline provides negligible savings.`,
46
+ };
47
+ }
48
+
49
+ // Default: outline for larger files with good compression
50
+ return {
51
+ projection: "outline",
52
+ reason: `${String(candidate.fileLines)} lines, ${String(candidate.symbolCount)} symbols, ${String(Math.round(candidate.outlineCompressionRatio * 100))}% compression — outline is efficient.`,
53
+ };
54
+ }
@@ -0,0 +1,59 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Agent Handoff Protocol — structured session transfer
3
+ // ---------------------------------------------------------------------------
4
+
5
+ import type { ObservationCache } from "./observation-cache.js";
6
+
7
+ /** The structured handoff payload. */
8
+ export interface HandoffPayload {
9
+ readonly sessionId: string;
10
+ readonly filesRead: readonly string[];
11
+ readonly symbolsInspected: readonly string[];
12
+ readonly observations: number;
13
+ readonly budgetConsumed: string;
14
+ }
15
+
16
+ /** Options for building a handoff. */
17
+ export interface HandoffOptions {
18
+ readonly cache: ObservationCache;
19
+ readonly sessionId: string;
20
+ readonly budgetTotal?: number;
21
+ readonly budgetConsumed?: number;
22
+ }
23
+
24
+ /**
25
+ * Build a structured handoff payload from the current session state.
26
+ *
27
+ * Projects the observation cache into a portable JSON payload that
28
+ * a receiving agent can use to understand what the departing agent
29
+ * knew and where it left off.
30
+ */
31
+ export function buildHandoff(options: HandoffOptions): HandoffPayload {
32
+ const { cache, sessionId } = options;
33
+
34
+ const filesRead: string[] = [];
35
+ const symbolsInspected: string[] = [];
36
+ let observationCount = 0;
37
+
38
+ for (const [filePath, observation] of cache.allEntries()) {
39
+ filesRead.push(filePath);
40
+ for (const entry of observation.outline) {
41
+ symbolsInspected.push(entry.name);
42
+ }
43
+ observationCount++;
44
+ }
45
+
46
+ let budgetStr = "unknown";
47
+ if (options.budgetTotal !== undefined && options.budgetConsumed !== undefined && options.budgetTotal > 0) {
48
+ const pct = Math.round((options.budgetConsumed / options.budgetTotal) * 100);
49
+ budgetStr = `${String(pct)}%`;
50
+ }
51
+
52
+ return {
53
+ sessionId,
54
+ filesRead,
55
+ symbolsInspected,
56
+ observations: observationCount,
57
+ budgetConsumed: budgetStr,
58
+ };
59
+ }
@@ -0,0 +1,64 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Capture Range — opaque handles for run_capture output
3
+ // ---------------------------------------------------------------------------
4
+
5
+
6
+
7
+ interface CaptureEntry {
8
+ readonly sessionId: string;
9
+ readonly content: string;
10
+ readonly lines: readonly string[];
11
+ }
12
+
13
+ /** Result of a range retrieval. */
14
+ export type CaptureRangeResult =
15
+ | { readonly ok: true; readonly lines: readonly string[]; readonly totalLines: number }
16
+ | { readonly ok: false; readonly error: string };
17
+
18
+ /**
19
+ * Registry of opaque capture handles.
20
+ *
21
+ * Maps UUIDs to capture content. Handles are session-scoped — a
22
+ * handle from one session is rejected in another.
23
+ */
24
+ export class CaptureHandleRegistry {
25
+ private nextId = 0;
26
+ private readonly entries = new Map<string, CaptureEntry>();
27
+
28
+ /**
29
+ * Register capture content and return an opaque handle.
30
+ */
31
+ register(sessionId: string, content: string): string {
32
+ const handle = `capture-${String(++this.nextId)}`;
33
+ const lines = content.split("\n").filter(
34
+ (line, index, arr) => index < arr.length - 1 || line.length > 0,
35
+ );
36
+ this.entries.set(handle, { sessionId, content, lines });
37
+ return handle;
38
+ }
39
+
40
+ /**
41
+ * Retrieve a line range from a capture handle.
42
+ *
43
+ * @param handle - The opaque handle from register()
44
+ * @param sessionId - The requesting session (must match the registering session)
45
+ * @param start - 1-based start line (inclusive)
46
+ * @param end - 1-based end line (inclusive)
47
+ */
48
+ getRange(handle: string, sessionId: string, start: number, end: number): CaptureRangeResult {
49
+ const entry = this.entries.get(handle);
50
+ if (entry === undefined) {
51
+ return { ok: false, error: "Capture handle not found" };
52
+ }
53
+ if (entry.sessionId !== sessionId) {
54
+ return { ok: false, error: "Capture handle belongs to a different session" };
55
+ }
56
+
57
+ const totalLines = entry.lines.length;
58
+ const clampedStart = Math.max(1, start);
59
+ const clampedEnd = Math.min(totalLines, end);
60
+ const lines = entry.lines.slice(clampedStart - 1, clampedEnd);
61
+
62
+ return { ok: true, lines, totalLines };
63
+ }
64
+ }
@@ -0,0 +1,82 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Conversation Primer — auto-orient agent at session start via graft_map
3
+ // ---------------------------------------------------------------------------
4
+
5
+ import type { GitClient } from "../ports/git.js";
6
+ import type { FileSystem } from "../ports/filesystem.js";
7
+ import type { PathOps } from "../ports/paths.js";
8
+
9
+ /** Result of building a conversation primer. */
10
+ export interface ConversationPrimerResult {
11
+ readonly scope: string;
12
+ readonly files: readonly string[];
13
+ readonly truncated: boolean;
14
+ readonly totalFiles: number;
15
+ }
16
+
17
+ /** Options for building a primer. */
18
+ export interface ConversationPrimerOptions {
19
+ readonly cwd: string;
20
+ readonly git: GitClient;
21
+ readonly fs: FileSystem;
22
+ readonly pathOps: PathOps;
23
+ readonly scope?: string;
24
+ readonly maxFiles?: number;
25
+ }
26
+
27
+ /** Common source directory names, in priority order. */
28
+ const COMMON_SCOPES = ["src", "lib", "app", "packages"];
29
+
30
+ async function isDirectory(fileSystem: FileSystem, dirPath: string): Promise<boolean> {
31
+ try {
32
+ await fileSystem.readdir(dirPath);
33
+ return true;
34
+ } catch {
35
+ return false;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Build a conversation primer for the given project.
41
+ *
42
+ * Auto-detects the best scope (src/, lib/, etc.) or uses an explicit
43
+ * scope. Returns a list of tracked files, truncated if beyond maxFiles.
44
+ */
45
+ export async function buildConversationPrimer(
46
+ options: ConversationPrimerOptions,
47
+ ): Promise<ConversationPrimerResult> {
48
+ const { cwd, git, fs: fileSystem, pathOps, maxFiles = 50 } = options;
49
+
50
+ // Detect scope
51
+ let scope = options.scope ?? ".";
52
+ if (options.scope === undefined) {
53
+ for (const candidate of COMMON_SCOPES) {
54
+ const candidatePath = pathOps.join(cwd, candidate);
55
+ if (await isDirectory(fileSystem, candidatePath)) {
56
+ scope = candidate;
57
+ break;
58
+ }
59
+ }
60
+ }
61
+
62
+ // List tracked files via git ls-files (allowed by plumbing)
63
+ const lsResult = await git.run({
64
+ cwd,
65
+ args: ["ls-files", "--", scope],
66
+ });
67
+
68
+ const allFiles = lsResult.stdout
69
+ .split("\n")
70
+ .map((f) => f.trim())
71
+ .filter((f) => f.length > 0);
72
+
73
+ const truncated = allFiles.length > maxFiles;
74
+ const files = truncated ? allFiles.slice(0, maxFiles) : allFiles;
75
+
76
+ return {
77
+ scope,
78
+ files,
79
+ truncated,
80
+ totalFiles: allFiles.length,
81
+ };
82
+ }