@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,7 +1,8 @@
1
1
  import { CanonicalJsonCodec } from "../adapters/canonical-json.js";
2
2
  import { nodeGit } from "../adapters/node-git.js";
3
+ import { nodePathOps } from "../adapters/node-paths.js";
3
4
  import { attachCliSchemaMeta, validateCliOutput } from "../contracts/output-schemas.js";
4
- import { indexCommits } from "../warp/indexer.js";
5
+ import { indexHead } from "../warp/index-head.js";
5
6
  import { openWarp } from "../warp/open.js";
6
7
  import { writeCliError } from "./cli-error.js";
7
8
  import {
@@ -39,33 +40,31 @@ export async function runIndex(options: RunIndexOptions = {}): Promise<void> {
39
40
  const stderr = options.stderr ?? process.stderr;
40
41
 
41
42
  try {
42
- const { json, from } = parseIndexCommandArgs(args);
43
- const warp = await openWarp({ cwd });
44
- const result = await indexCommits(warp, {
43
+ const { json, paths } = parseIndexCommandArgs(args);
44
+ const app = await openWarp({ cwd });
45
+ const ctx = { app, strandId: null };
46
+ const result = await indexHead({
45
47
  cwd,
46
48
  git: nodeGit,
47
- ...(from !== null ? { from } : {}),
49
+ pathOps: nodePathOps,
50
+ ctx,
51
+ ...(paths.length > 0 ? { paths } : {}),
48
52
  });
49
53
 
50
- if (!result.ok) {
51
- throw new Error(result.error);
52
- }
53
-
54
54
  if (json) {
55
55
  emitIndexJson(buildIndexCliSuccess({
56
56
  cwd,
57
- from,
58
- commitsIndexed: result.commitsIndexed,
59
- patchesWritten: result.patchesWritten,
57
+ filesIndexed: result.filesIndexed,
58
+ nodesEmitted: result.nodesEmitted,
60
59
  }), stdout);
61
60
  return;
62
61
  }
63
62
 
64
63
  writeLine(stdout);
65
- writeLine(stdout, `Indexing structural history in ${cwd}`);
64
+ writeLine(stdout, `Indexing HEAD in ${cwd}`);
66
65
  writeLine(stdout);
67
- writeLine(stdout, ` commits indexed: ${String(result.commitsIndexed)}`);
68
- writeLine(stdout, ` patches written: ${String(result.patchesWritten)}`);
66
+ writeLine(stdout, ` files indexed: ${String(result.filesIndexed)}`);
67
+ writeLine(stdout, ` nodes emitted: ${String(result.nodesEmitted)}`);
69
68
  writeLine(stdout);
70
69
  writeLine(stdout, "Done.");
71
70
  writeLine(stdout);
@@ -76,19 +75,16 @@ export async function runIndex(options: RunIndexOptions = {}): Promise<void> {
76
75
  try {
77
76
  return parseIndexCommandArgs(args);
78
77
  } catch {
79
- return {
80
- json: args.includes("--json"),
81
- from: args.find((arg) => arg !== "--json" && !arg.startsWith("--")) ?? null,
82
- };
78
+ return { json: args.includes("--json") };
83
79
  }
84
80
  })();
85
81
  if (parsed.json) {
86
- emitIndexJson(buildIndexCliFailure({ cwd, from: parsed.from, error: message }), stdout);
82
+ emitIndexJson(buildIndexCliFailure({ cwd, error: message }), stdout);
87
83
  return;
88
84
  }
89
85
  writeCliError(stderr, message, {
90
- usage: "graft index [<from-ref>] [--json]",
91
- nextSteps: ["Use `--json` if you want a machine-readable indexing report."],
86
+ usage: "graft index [--path <path>] [--json]",
87
+ nextSteps: ["Use `--path <path>` for lazy per-file indexing and `--json` for machine-readable output."],
92
88
  });
93
89
  }
94
90
  }
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
 
3
3
  const indexCommandArgsSchema = z.object({
4
4
  json: z.boolean(),
5
- from: z.string().nullable(),
5
+ paths: z.array(z.string()),
6
6
  });
7
7
 
8
8
  export type IndexCommandArgs = z.infer<typeof indexCommandArgsSchema>;
@@ -10,15 +10,13 @@ export type IndexCommandArgs = z.infer<typeof indexCommandArgsSchema>;
10
10
  const indexSuccessSchema = z.object({
11
11
  ok: z.literal(true),
12
12
  cwd: z.string(),
13
- from: z.string().nullable(),
14
- commitsIndexed: z.number().int().nonnegative(),
15
- patchesWritten: z.number().int().nonnegative(),
13
+ filesIndexed: z.number().int().nonnegative(),
14
+ nodesEmitted: z.number().int().nonnegative(),
16
15
  });
17
16
 
18
17
  const indexFailureSchema = z.object({
19
18
  ok: z.literal(false),
20
19
  cwd: z.string(),
21
- from: z.string().nullable(),
22
20
  error: z.string(),
23
21
  });
24
22
 
@@ -28,49 +26,50 @@ export type IndexCliResult = z.infer<typeof indexCliResultSchema>;
28
26
 
29
27
  export function parseIndexCommandArgs(args: readonly string[]): IndexCommandArgs {
30
28
  let json = false;
31
- let from: string | null = null;
29
+ const paths: string[] = [];
32
30
 
33
- for (const arg of args) {
31
+ for (let index = 0; index < args.length; index++) {
32
+ const arg = args[index];
33
+ if (arg === undefined) continue;
34
34
  if (arg === "--json") {
35
35
  json = true;
36
36
  continue;
37
37
  }
38
- if (arg.startsWith("--")) {
39
- throw new Error(`Unknown index arguments: ${arg}`);
40
- }
41
- if (from !== null) {
42
- throw new Error(`Unknown index arguments: ${arg}`);
38
+ if (arg === "--path") {
39
+ const value = args[index + 1];
40
+ if (value === undefined) {
41
+ throw new Error("Missing value for --path");
42
+ }
43
+ paths.push(value);
44
+ index++;
45
+ continue;
43
46
  }
44
- from = arg;
47
+ throw new Error(`Unknown index arguments: ${arg}`);
45
48
  }
46
49
 
47
- return indexCommandArgsSchema.parse({ json, from });
50
+ return indexCommandArgsSchema.parse({ json, paths });
48
51
  }
49
52
 
50
53
  export function buildIndexCliSuccess(input: {
51
54
  readonly cwd: string;
52
- readonly from: string | null;
53
- readonly commitsIndexed: number;
54
- readonly patchesWritten: number;
55
+ readonly filesIndexed: number;
56
+ readonly nodesEmitted: number;
55
57
  }): IndexCliResult {
56
58
  return indexSuccessSchema.parse({
57
59
  ok: true,
58
60
  cwd: input.cwd,
59
- from: input.from,
60
- commitsIndexed: input.commitsIndexed,
61
- patchesWritten: input.patchesWritten,
61
+ filesIndexed: input.filesIndexed,
62
+ nodesEmitted: input.nodesEmitted,
62
63
  });
63
64
  }
64
65
 
65
66
  export function buildIndexCliFailure(input: {
66
67
  readonly cwd: string;
67
- readonly from: string | null;
68
68
  readonly error: string;
69
69
  }): IndexCliResult {
70
70
  return indexFailureSchema.parse({
71
71
  ok: false,
72
72
  cwd: input.cwd,
73
- from: input.from,
74
73
  error: input.error,
75
74
  });
76
75
  }
@@ -3,8 +3,12 @@ import * as path from "node:path";
3
3
  import {
4
4
  GRAFT_HOOKS_CONFIG,
5
5
  GRAFT_MCP_SERVER,
6
+ GraftMcpServer,
6
7
  InitAction,
8
+ isGraftMcpServerEntryForRuntime,
7
9
  type GraftHookMatcher,
10
+ type JsonObjectValue,
11
+ type JsonValue,
8
12
  } from "./init-model.js";
9
13
  import {
10
14
  JsonArrayNode,
@@ -14,28 +18,33 @@ import {
14
18
  class JsonMcpConfigDocument {
15
19
  constructor(
16
20
  private readonly document: JsonObjectDocument,
17
- private readonly server: typeof GRAFT_MCP_SERVER,
21
+ private readonly server: GraftMcpServer,
22
+ private readonly updateExisting: boolean,
18
23
  ) {}
19
24
 
20
25
  static create(
21
26
  filePath: string,
22
27
  label: string,
23
- server: typeof GRAFT_MCP_SERVER,
28
+ server: GraftMcpServer,
29
+ updateExisting: boolean,
24
30
  ): JsonMcpConfigDocument {
25
31
  return new JsonMcpConfigDocument(
26
32
  JsonObjectDocument.create(filePath, label, server.toJsonMcpConfig()),
27
33
  server,
34
+ updateExisting,
28
35
  );
29
36
  }
30
37
 
31
38
  static open(
32
39
  filePath: string,
33
40
  label: string,
34
- server: typeof GRAFT_MCP_SERVER,
41
+ server: GraftMcpServer,
42
+ updateExisting: boolean,
35
43
  ): JsonMcpConfigDocument {
36
44
  return new JsonMcpConfigDocument(
37
45
  JsonObjectDocument.open(filePath, label),
38
46
  server,
47
+ updateExisting,
39
48
  );
40
49
  }
41
50
 
@@ -46,6 +55,15 @@ class JsonMcpConfigDocument {
46
55
  ensureGraftServer(): InitAction {
47
56
  const root = this.document.root();
48
57
  const servers = root.ensureObject("mcpServers");
58
+ const existing = servers.toJsonValue()[this.server.name];
59
+ if (existing !== undefined) {
60
+ if (isGraftMcpServerEntryForRuntime(existing, this.server.runtime) || !this.updateExisting) {
61
+ return InitAction.exists(this.document.label, "already has graft mcp server");
62
+ }
63
+ servers.set(this.server.name, this.server.toJsonServerEntry());
64
+ this.document.write();
65
+ return InitAction.append(this.document.label, `updated graft mcp server runtime to ${this.server.runtime}`);
66
+ }
49
67
  if (servers.has(this.server.name)) {
50
68
  return InitAction.exists(this.document.label, "already has graft mcp server");
51
69
  }
@@ -58,28 +76,33 @@ class JsonMcpConfigDocument {
58
76
  class ContinueMcpConfigDocument {
59
77
  constructor(
60
78
  private readonly document: JsonObjectDocument,
61
- private readonly server: typeof GRAFT_MCP_SERVER,
79
+ private readonly server: GraftMcpServer,
80
+ private readonly updateExisting: boolean,
62
81
  ) {}
63
82
 
64
83
  static create(
65
84
  filePath: string,
66
85
  label: string,
67
- server: typeof GRAFT_MCP_SERVER,
86
+ server: GraftMcpServer,
87
+ updateExisting: boolean,
68
88
  ): ContinueMcpConfigDocument {
69
89
  return new ContinueMcpConfigDocument(
70
90
  JsonObjectDocument.create(filePath, label, server.toContinueConfig()),
71
91
  server,
92
+ updateExisting,
72
93
  );
73
94
  }
74
95
 
75
96
  static open(
76
97
  filePath: string,
77
98
  label: string,
78
- server: typeof GRAFT_MCP_SERVER,
99
+ server: GraftMcpServer,
100
+ updateExisting: boolean,
79
101
  ): ContinueMcpConfigDocument {
80
102
  return new ContinueMcpConfigDocument(
81
103
  JsonObjectDocument.open(filePath, label),
82
104
  server,
105
+ updateExisting,
83
106
  );
84
107
  }
85
108
 
@@ -90,11 +113,16 @@ class ContinueMcpConfigDocument {
90
113
  ensureGraftServer(): InitAction {
91
114
  const root = this.document.root();
92
115
  const servers = root.ensureArray("mcpServers");
93
- const exists = servers
94
- .objectItems()
95
- .some((entry) => entry.stringValue("name") === this.server.name);
96
- if (exists) {
97
- return InitAction.exists(this.document.label, "already has graft mcp server");
116
+ const existingEntries = servers.objectEntries();
117
+ const existing = existingEntries
118
+ .find((entry) => entry.node.stringValue("name") === this.server.name);
119
+ if (existing !== undefined) {
120
+ if (isContinueServerEntryForRuntime(existing.node.toJsonValue(), this.server.runtime) || !this.updateExisting) {
121
+ return InitAction.exists(this.document.label, "already has graft mcp server");
122
+ }
123
+ servers.set(existing.index, this.server.toContinueServerEntry());
124
+ this.document.write();
125
+ return InitAction.append(this.document.label, `updated graft mcp server runtime to ${this.server.runtime}`);
98
126
  }
99
127
  servers.push(this.server.toContinueServerEntry());
100
128
  this.document.write();
@@ -180,12 +208,15 @@ class ClaudeHooksDocument {
180
208
  export function ensureCodexStartupTimeout(
181
209
  existing: string,
182
210
  ): { content: string; changed: boolean } {
211
+ const ensured = ensureCodexMcpServerBlock(existing, GRAFT_MCP_SERVER, false);
212
+ return { content: ensured.content, changed: ensured.changed };
213
+ }
214
+
215
+ function codexBlockBounds(lines: readonly string[]): { start: number; end: number } | undefined {
183
216
  const marker = "[mcp_servers.graft]";
184
- const timeoutLine = `startup_timeout_sec = ${String(GRAFT_MCP_SERVER.codexStartupTimeoutSec)}`;
185
- const lines = existing.split("\n");
186
217
  const blockStart = lines.findIndex((line) => line.trim() === marker);
187
218
  if (blockStart === -1) {
188
- return { content: existing, changed: false };
219
+ return undefined;
189
220
  }
190
221
 
191
222
  let blockEnd = lines.length;
@@ -197,53 +228,143 @@ export function ensureCodexStartupTimeout(
197
228
  }
198
229
  }
199
230
 
231
+ return { start: blockStart, end: blockEnd };
232
+ }
233
+
234
+ function replaceOrInsertLine(
235
+ lines: string[],
236
+ bounds: { readonly start: number; readonly end: number },
237
+ predicate: (line: string) => boolean,
238
+ value: string,
239
+ ): { end: number; changed: boolean } {
240
+ const index = lines
241
+ .slice(bounds.start + 1, bounds.end)
242
+ .findIndex(predicate);
243
+ if (index === -1) {
244
+ lines.splice(bounds.end, 0, value);
245
+ return { end: bounds.end + 1, changed: true };
246
+ }
247
+
248
+ const absoluteIndex = bounds.start + 1 + index;
249
+ if (lines[absoluteIndex] === value) {
250
+ return { end: bounds.end, changed: false };
251
+ }
252
+
253
+ lines[absoluteIndex] = value;
254
+ return { end: bounds.end, changed: true };
255
+ }
256
+
257
+ export function ensureCodexMcpServerBlock(
258
+ existing: string,
259
+ server: GraftMcpServer,
260
+ updateExisting: boolean,
261
+ ): { content: string; changed: boolean; detail?: string | undefined } {
262
+ const lines = existing.split("\n");
263
+ const bounds = codexBlockBounds(lines);
264
+ if (bounds === undefined) {
265
+ return { content: existing, changed: false };
266
+ }
267
+
268
+ let changed = false;
269
+ let runtimeChanged = false;
270
+ let blockEnd = bounds.end;
271
+ if (updateExisting) {
272
+ const command = replaceOrInsertLine(
273
+ lines,
274
+ { start: bounds.start, end: blockEnd },
275
+ (line) => line.trim().startsWith("command"),
276
+ `command = "${server.command}"`,
277
+ );
278
+ runtimeChanged = command.changed;
279
+ changed = command.changed;
280
+ blockEnd = command.end;
281
+
282
+ const args = replaceOrInsertLine(
283
+ lines,
284
+ { start: bounds.start, end: blockEnd },
285
+ (line) => line.trim().startsWith("args"),
286
+ server.toCodexTomlArgsLine(),
287
+ );
288
+ runtimeChanged = runtimeChanged || args.changed;
289
+ changed = changed || args.changed;
290
+ blockEnd = args.end;
291
+ }
292
+
200
293
  const hasTimeout = lines
201
- .slice(blockStart + 1, blockEnd)
294
+ .slice(bounds.start + 1, blockEnd)
202
295
  .some((line) => line.trim().startsWith("startup_timeout_sec"));
203
- if (hasTimeout) {
204
- return { content: existing, changed: false };
296
+ if (!hasTimeout) {
297
+ lines.splice(blockEnd, 0, `startup_timeout_sec = ${String(server.codexStartupTimeoutSec)}`);
298
+ changed = true;
205
299
  }
206
300
 
207
- lines.splice(blockEnd, 0, timeoutLine);
208
301
  return {
209
302
  content: lines.join("\n"),
210
- changed: true,
303
+ changed,
304
+ ...(runtimeChanged ? { detail: `updated graft mcp server runtime to ${server.runtime}` } : {}),
211
305
  };
212
306
  }
213
307
 
214
- function ensureJsonMcpConfig(filePath: string, label: string): InitAction {
308
+ function isContinueServerEntryForRuntime(value: JsonObjectValue, runtime: GraftMcpServer["runtime"]): boolean {
309
+ const { name, ...entry } = value;
310
+ void name;
311
+ return isGraftMcpServerEntryForRuntime(entry as JsonValue, runtime);
312
+ }
313
+
314
+ function ensureJsonMcpConfig(
315
+ filePath: string,
316
+ label: string,
317
+ server: GraftMcpServer,
318
+ updateExisting: boolean,
319
+ ): InitAction {
215
320
  if (!fs.existsSync(filePath)) {
216
- const created = JsonMcpConfigDocument.create(filePath, label, GRAFT_MCP_SERVER);
321
+ const created = JsonMcpConfigDocument.create(filePath, label, server, updateExisting);
217
322
  created.write();
218
323
  return InitAction.create(label, "wrote graft mcp server");
219
324
  }
220
325
  return JsonMcpConfigDocument
221
- .open(filePath, label, GRAFT_MCP_SERVER)
326
+ .open(filePath, label, server, updateExisting)
222
327
  .ensureGraftServer();
223
328
  }
224
329
 
225
- export function mergeClaudeMcpConfig(cwd: string): InitAction {
330
+ export function mergeClaudeMcpConfig(
331
+ cwd: string,
332
+ server = GRAFT_MCP_SERVER,
333
+ updateExisting = false,
334
+ ): InitAction {
226
335
  const label = ".mcp.json";
227
336
  const filePath = path.join(cwd, label);
228
- return ensureJsonMcpConfig(filePath, label);
337
+ return ensureJsonMcpConfig(filePath, label, server, updateExisting);
229
338
  }
230
339
 
231
- export function mergeCursorMcpConfig(cwd: string): InitAction {
340
+ export function mergeCursorMcpConfig(
341
+ cwd: string,
342
+ server = GRAFT_MCP_SERVER,
343
+ updateExisting = false,
344
+ ): InitAction {
232
345
  const label = ".cursor/mcp.json";
233
346
  const filePath = path.join(cwd, ".cursor", "mcp.json");
234
- return ensureJsonMcpConfig(filePath, label);
347
+ return ensureJsonMcpConfig(filePath, label, server, updateExisting);
235
348
  }
236
349
 
237
- export function mergeWindsurfMcpConfig(cwd: string): InitAction {
350
+ export function mergeWindsurfMcpConfig(
351
+ cwd: string,
352
+ server = GRAFT_MCP_SERVER,
353
+ updateExisting = false,
354
+ ): InitAction {
238
355
  const label = ".codeium/windsurf/mcp_config.json";
239
356
  const filePath = path.join(cwd, ".codeium", "windsurf", "mcp_config.json");
240
- return ensureJsonMcpConfig(filePath, label);
357
+ return ensureJsonMcpConfig(filePath, label, server, updateExisting);
241
358
  }
242
359
 
243
- export function mergeClineMcpConfig(cwd: string): InitAction {
360
+ export function mergeClineMcpConfig(
361
+ cwd: string,
362
+ server = GRAFT_MCP_SERVER,
363
+ updateExisting = false,
364
+ ): InitAction {
244
365
  const label = ".vscode/cline_mcp_settings.json";
245
366
  const filePath = path.join(cwd, ".vscode", "cline_mcp_settings.json");
246
- return ensureJsonMcpConfig(filePath, label);
367
+ return ensureJsonMcpConfig(filePath, label, server, updateExisting);
247
368
  }
248
369
 
249
370
  export function mergeClaudeHooksConfig(cwd: string): InitAction {
@@ -257,35 +378,43 @@ export function mergeClaudeHooksConfig(cwd: string): InitAction {
257
378
  return ClaudeHooksDocument.open(filePath, label, GRAFT_HOOKS_CONFIG).ensureGraftHooks();
258
379
  }
259
380
 
260
- export function mergeContinueMcpConfig(cwd: string): InitAction {
381
+ export function mergeContinueMcpConfig(
382
+ cwd: string,
383
+ server = GRAFT_MCP_SERVER,
384
+ updateExisting = false,
385
+ ): InitAction {
261
386
  const label = ".continue/config.json";
262
387
  const filePath = path.join(cwd, ".continue", "config.json");
263
388
  if (!fs.existsSync(filePath)) {
264
- const created = ContinueMcpConfigDocument.create(filePath, label, GRAFT_MCP_SERVER);
389
+ const created = ContinueMcpConfigDocument.create(filePath, label, server, updateExisting);
265
390
  created.write();
266
391
  return InitAction.create(label, "wrote graft mcp server");
267
392
  }
268
393
  return ContinueMcpConfigDocument
269
- .open(filePath, label, GRAFT_MCP_SERVER)
394
+ .open(filePath, label, server, updateExisting)
270
395
  .ensureGraftServer();
271
396
  }
272
397
 
273
- export function mergeCodexMcpConfig(cwd: string): InitAction {
398
+ export function mergeCodexMcpConfig(
399
+ cwd: string,
400
+ server = GRAFT_MCP_SERVER,
401
+ updateExisting = false,
402
+ ): InitAction {
274
403
  const label = ".codex/config.toml";
275
404
  const filePath = path.join(cwd, ".codex", "config.toml");
276
405
  const marker = "[mcp_servers.graft]";
277
406
  if (!fs.existsSync(filePath)) {
278
407
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
279
- fs.writeFileSync(filePath, GRAFT_MCP_SERVER.toCodexTomlBlock());
408
+ fs.writeFileSync(filePath, server.toCodexTomlBlock());
280
409
  return InitAction.create(label, "wrote graft mcp server");
281
410
  }
282
411
 
283
412
  const existing = fs.readFileSync(filePath, "utf-8");
284
413
  if (existing.includes(marker)) {
285
- const ensured = ensureCodexStartupTimeout(existing);
414
+ const ensured = ensureCodexMcpServerBlock(existing, server, updateExisting);
286
415
  if (ensured.changed) {
287
416
  fs.writeFileSync(filePath, ensured.content);
288
- return InitAction.append(label, "added graft startup timeout");
417
+ return InitAction.append(label, ensured.detail ?? "added graft startup timeout");
289
418
  }
290
419
  return InitAction.exists(label, "already has graft mcp server");
291
420
  }
@@ -293,7 +422,7 @@ export function mergeCodexMcpConfig(cwd: string): InitAction {
293
422
  const separator = existing.endsWith("\n") ? "\n" : "\n\n";
294
423
  fs.writeFileSync(
295
424
  filePath,
296
- `${existing}${separator}${GRAFT_MCP_SERVER.toCodexTomlBlock()}`,
425
+ `${existing}${separator}${server.toCodexTomlBlock()}`,
297
426
  );
298
427
  return InitAction.append(label, "appended graft mcp server");
299
428
  }
@@ -7,6 +7,7 @@ export interface JsonObjectValue {
7
7
  }
8
8
 
9
9
  type InitActionKind = "exists" | "create" | "append";
10
+ export type GraftMcpRuntime = "repo-local" | "daemon";
10
11
 
11
12
  export class InitAction {
12
13
  constructor(
@@ -54,9 +55,33 @@ function consumeFlag(args: string[], flag: string): boolean {
54
55
  return true;
55
56
  }
56
57
 
58
+ function consumeOption(args: string[], flag: string): string | undefined {
59
+ const index = args.indexOf(flag);
60
+ if (index === -1) {
61
+ return undefined;
62
+ }
63
+ if (index === args.length - 1) {
64
+ throw new Error(`Missing value for ${flag}`);
65
+ }
66
+ const [value] = args.splice(index, 2).slice(1);
67
+ return value;
68
+ }
69
+
70
+ function parseMcpRuntime(raw: string | undefined): { runtime: GraftMcpRuntime; explicit: boolean } {
71
+ if (raw === undefined) {
72
+ return { runtime: "repo-local", explicit: false };
73
+ }
74
+ if (raw === "repo-local" || raw === "daemon") {
75
+ return { runtime: raw, explicit: true };
76
+ }
77
+ throw new Error(`--mcp-runtime must be repo-local or daemon, got ${raw}`);
78
+ }
79
+
57
80
  export class ParsedInitArgs {
58
81
  constructor(
59
82
  readonly json: boolean,
83
+ readonly mcpRuntime: GraftMcpRuntime,
84
+ readonly mcpRuntimeExplicit: boolean,
60
85
  readonly writeClaudeMcp: boolean,
61
86
  readonly writeClaudeHooks: boolean,
62
87
  readonly writeTargetGitHooks: boolean,
@@ -69,8 +94,11 @@ export class ParsedInitArgs {
69
94
 
70
95
  static parse(rawArgs: readonly string[]): ParsedInitArgs {
71
96
  const args = [...rawArgs];
97
+ const runtime = parseMcpRuntime(consumeOption(args, "--mcp-runtime"));
72
98
  const parsed = new ParsedInitArgs(
73
99
  consumeFlag(args, "--json"),
100
+ runtime.runtime,
101
+ runtime.explicit,
74
102
  consumeFlag(args, "--write-claude-mcp"),
75
103
  consumeFlag(args, "--write-claude-hooks"),
76
104
  consumeFlag(args, "--write-target-git-hooks"),
@@ -101,9 +129,16 @@ export class ParsedInitArgs {
101
129
  export class GraftMcpServer {
102
130
  readonly name = "graft";
103
131
  readonly command = "npx";
104
- readonly args = ["-y", "@flyingrobots/graft", "serve"] as const;
105
132
  readonly codexStartupTimeoutSec = 120;
106
133
 
134
+ constructor(readonly runtime: GraftMcpRuntime = "repo-local") {}
135
+
136
+ get args(): readonly string[] {
137
+ return this.runtime === "daemon"
138
+ ? ["-y", "@flyingrobots/graft", "serve", "--runtime", "daemon"]
139
+ : ["-y", "@flyingrobots/graft", "serve"];
140
+ }
141
+
107
142
  toJsonServerEntry(): JsonObjectValue {
108
143
  return {
109
144
  command: this.command,
@@ -137,11 +172,15 @@ export class GraftMcpServer {
137
172
  return [
138
173
  "[mcp_servers.graft]",
139
174
  "command = \"npx\"",
140
- "args = [\"-y\", \"@flyingrobots/graft\", \"serve\"]",
175
+ this.toCodexTomlArgsLine(),
141
176
  `startup_timeout_sec = ${String(this.codexStartupTimeoutSec)}`,
142
177
  "",
143
178
  ].join("\n");
144
179
  }
180
+
181
+ toCodexTomlArgsLine(): string {
182
+ return `args = [${this.args.map((arg) => `"${arg}"`).join(", ")}]`;
183
+ }
145
184
  }
146
185
 
147
186
  export class GraftHookCommand {
@@ -227,3 +266,19 @@ export function isJsonObjectValue(value: unknown): value is JsonObjectValue {
227
266
  export function cloneJsonValue<T>(value: T): T {
228
267
  return JSON.parse(JSON.stringify(value)) as T;
229
268
  }
269
+
270
+ export function isGraftMcpServerEntryForRuntime(
271
+ value: JsonValue | undefined,
272
+ runtime: GraftMcpRuntime,
273
+ ): boolean {
274
+ if (!isJsonObjectValue(value)) {
275
+ return false;
276
+ }
277
+ const command = value["command"];
278
+ const args = value["args"];
279
+ const expected = new GraftMcpServer(runtime);
280
+ return command === expected.command
281
+ && Array.isArray(args)
282
+ && args.length === expected.args.length
283
+ && args.every((arg, index) => arg === expected.args[index]);
284
+ }
@@ -1,6 +1,6 @@
1
1
  import { CanonicalJsonCodec } from "../adapters/canonical-json.js";
2
2
  import { attachCliSchemaMeta, validateCliOutput } from "../contracts/output-schemas.js";
3
- import { GRAFT_HOOKS_CONFIG, GRAFT_MCP_SERVER, InitFailure, InitResult, ParsedInitArgs, type JsonObjectValue } from "./init-model.js";
3
+ import { GRAFT_HOOKS_CONFIG, InitFailure, InitResult, ParsedInitArgs, type JsonObjectValue } from "./init-model.js";
4
4
 
5
5
  const codec = new CanonicalJsonCodec();
6
6
 
@@ -37,7 +37,7 @@ export function renderInitText(result: InitResult, args: ParsedInitArgs, writer:
37
37
  if (!args.writesAnyMcpConfig) {
38
38
  writeLine(writer, "Done. Add graft to your MCP config:");
39
39
  writeLine(writer);
40
- writeLine(writer, indentJson(GRAFT_MCP_SERVER.toJsonMcpConfig()));
40
+ writeLine(writer, indentJson(result.suggestedMcpServer.toJsonMcpConfig()));
41
41
  writeLine(writer);
42
42
  writeLine(writer, "Use explicit --write-*-mcp flags or --write-claude-hooks");
43
43
  writeLine(writer, "or --write-target-git-hooks for one-step bootstrap into project-local config files.");