kairo-mcp 1.3.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 (384) hide show
  1. package/CHANGELOG.md +1122 -0
  2. package/LICENSE +21 -0
  3. package/README.md +662 -0
  4. package/dist/cli/cli.d.ts +3 -0
  5. package/dist/cli/cli.d.ts.map +1 -0
  6. package/dist/cli/cli.js +226 -0
  7. package/dist/cli/cli.js.map +1 -0
  8. package/dist/cli/commands.d.ts +10 -0
  9. package/dist/cli/commands.d.ts.map +1 -0
  10. package/dist/cli/commands.js +938 -0
  11. package/dist/cli/commands.js.map +1 -0
  12. package/dist/cli/flags.d.ts +30 -0
  13. package/dist/cli/flags.d.ts.map +1 -0
  14. package/dist/cli/flags.js +90 -0
  15. package/dist/cli/flags.js.map +1 -0
  16. package/dist/cli/output.d.ts +69 -0
  17. package/dist/cli/output.d.ts.map +1 -0
  18. package/dist/cli/output.js +166 -0
  19. package/dist/cli/output.js.map +1 -0
  20. package/dist/cli/types.d.ts +34 -0
  21. package/dist/cli/types.d.ts.map +1 -0
  22. package/dist/cli/types.js +2 -0
  23. package/dist/cli/types.js.map +1 -0
  24. package/dist/contracts/migrations.d.ts +31 -0
  25. package/dist/contracts/migrations.d.ts.map +1 -0
  26. package/dist/contracts/migrations.js +71 -0
  27. package/dist/contracts/migrations.js.map +1 -0
  28. package/dist/contracts/schemas.d.ts +53 -0
  29. package/dist/contracts/schemas.d.ts.map +1 -0
  30. package/dist/contracts/schemas.js +27 -0
  31. package/dist/contracts/schemas.js.map +1 -0
  32. package/dist/contracts/stability.d.ts +32 -0
  33. package/dist/contracts/stability.d.ts.map +1 -0
  34. package/dist/contracts/stability.js +140 -0
  35. package/dist/contracts/stability.js.map +1 -0
  36. package/dist/contracts/zodSchemas.d.ts +811 -0
  37. package/dist/contracts/zodSchemas.d.ts.map +1 -0
  38. package/dist/contracts/zodSchemas.js +139 -0
  39. package/dist/contracts/zodSchemas.js.map +1 -0
  40. package/dist/core/brief/budget.d.ts +21 -0
  41. package/dist/core/brief/budget.d.ts.map +1 -0
  42. package/dist/core/brief/budget.js +42 -0
  43. package/dist/core/brief/budget.js.map +1 -0
  44. package/dist/core/checkpoint/checkpointManager.d.ts +29 -0
  45. package/dist/core/checkpoint/checkpointManager.d.ts.map +1 -0
  46. package/dist/core/checkpoint/checkpointManager.js +49 -0
  47. package/dist/core/checkpoint/checkpointManager.js.map +1 -0
  48. package/dist/core/compaction/compactor.d.ts +40 -0
  49. package/dist/core/compaction/compactor.d.ts.map +1 -0
  50. package/dist/core/compaction/compactor.js +168 -0
  51. package/dist/core/compaction/compactor.js.map +1 -0
  52. package/dist/core/continuation/continuationBuilder.d.ts +19 -0
  53. package/dist/core/continuation/continuationBuilder.d.ts.map +1 -0
  54. package/dist/core/continuation/continuationBuilder.js +184 -0
  55. package/dist/core/continuation/continuationBuilder.js.map +1 -0
  56. package/dist/core/coordination/coordinationManager.d.ts +34 -0
  57. package/dist/core/coordination/coordinationManager.d.ts.map +1 -0
  58. package/dist/core/coordination/coordinationManager.js +253 -0
  59. package/dist/core/coordination/coordinationManager.js.map +1 -0
  60. package/dist/core/coordination/types.d.ts +52 -0
  61. package/dist/core/coordination/types.d.ts.map +1 -0
  62. package/dist/core/coordination/types.js +6 -0
  63. package/dist/core/coordination/types.js.map +1 -0
  64. package/dist/core/github/changelog.d.ts +9 -0
  65. package/dist/core/github/changelog.d.ts.map +1 -0
  66. package/dist/core/github/changelog.js +41 -0
  67. package/dist/core/github/changelog.js.map +1 -0
  68. package/dist/core/github/commitMessage.d.ts +4 -0
  69. package/dist/core/github/commitMessage.d.ts.map +1 -0
  70. package/dist/core/github/commitMessage.js +125 -0
  71. package/dist/core/github/commitMessage.js.map +1 -0
  72. package/dist/core/github/gitContext.d.ts +3 -0
  73. package/dist/core/github/gitContext.d.ts.map +1 -0
  74. package/dist/core/github/gitContext.js +67 -0
  75. package/dist/core/github/gitContext.js.map +1 -0
  76. package/dist/core/github/releasePlan.d.ts +8 -0
  77. package/dist/core/github/releasePlan.d.ts.map +1 -0
  78. package/dist/core/github/releasePlan.js +56 -0
  79. package/dist/core/github/releasePlan.js.map +1 -0
  80. package/dist/core/github/semver.d.ts +11 -0
  81. package/dist/core/github/semver.d.ts.map +1 -0
  82. package/dist/core/github/semver.js +23 -0
  83. package/dist/core/github/semver.js.map +1 -0
  84. package/dist/core/github/types.d.ts +36 -0
  85. package/dist/core/github/types.d.ts.map +1 -0
  86. package/dist/core/github/types.js +2 -0
  87. package/dist/core/github/types.js.map +1 -0
  88. package/dist/core/graph/derived.d.ts +6 -0
  89. package/dist/core/graph/derived.d.ts.map +1 -0
  90. package/dist/core/graph/derived.js +133 -0
  91. package/dist/core/graph/derived.js.map +1 -0
  92. package/dist/core/graph/graphEngine.d.ts +11 -0
  93. package/dist/core/graph/graphEngine.d.ts.map +1 -0
  94. package/dist/core/graph/graphEngine.js +28 -0
  95. package/dist/core/graph/graphEngine.js.map +1 -0
  96. package/dist/core/graph/imports.d.ts +19 -0
  97. package/dist/core/graph/imports.d.ts.map +1 -0
  98. package/dist/core/graph/imports.js +0 -0
  99. package/dist/core/graph/imports.js.map +1 -0
  100. package/dist/core/graph/mermaid.d.ts +6 -0
  101. package/dist/core/graph/mermaid.d.ts.map +1 -0
  102. package/dist/core/graph/mermaid.js +40 -0
  103. package/dist/core/graph/mermaid.js.map +1 -0
  104. package/dist/core/graph/moduleGraph.d.ts +27 -0
  105. package/dist/core/graph/moduleGraph.d.ts.map +1 -0
  106. package/dist/core/graph/moduleGraph.js +186 -0
  107. package/dist/core/graph/moduleGraph.js.map +1 -0
  108. package/dist/core/graph/types.d.ts +32 -0
  109. package/dist/core/graph/types.d.ts.map +1 -0
  110. package/dist/core/graph/types.js +2 -0
  111. package/dist/core/graph/types.js.map +1 -0
  112. package/dist/core/query/queryEngine.d.ts +26 -0
  113. package/dist/core/query/queryEngine.d.ts.map +1 -0
  114. package/dist/core/query/queryEngine.js +258 -0
  115. package/dist/core/query/queryEngine.js.map +1 -0
  116. package/dist/core/query/types.d.ts +70 -0
  117. package/dist/core/query/types.d.ts.map +1 -0
  118. package/dist/core/query/types.js +6 -0
  119. package/dist/core/query/types.js.map +1 -0
  120. package/dist/core/repo/fingerprint.d.ts +0 -0
  121. package/dist/core/repo/fingerprint.d.ts.map +1 -0
  122. package/dist/core/repo/fingerprint.js +17 -0
  123. package/dist/core/repo/fingerprint.js.map +1 -0
  124. package/dist/core/repo/frameworkDetectors.d.ts +14 -0
  125. package/dist/core/repo/frameworkDetectors.d.ts.map +1 -0
  126. package/dist/core/repo/frameworkDetectors.js +151 -0
  127. package/dist/core/repo/frameworkDetectors.js.map +1 -0
  128. package/dist/core/repo/repoScanner.d.ts +20 -0
  129. package/dist/core/repo/repoScanner.d.ts.map +1 -0
  130. package/dist/core/repo/repoScanner.js +290 -0
  131. package/dist/core/repo/repoScanner.js.map +1 -0
  132. package/dist/core/repo/summary.d.ts +7 -0
  133. package/dist/core/repo/summary.d.ts.map +1 -0
  134. package/dist/core/repo/summary.js +34 -0
  135. package/dist/core/repo/summary.js.map +1 -0
  136. package/dist/core/repo/types.d.ts +62 -0
  137. package/dist/core/repo/types.d.ts.map +1 -0
  138. package/dist/core/repo/types.js +10 -0
  139. package/dist/core/repo/types.js.map +1 -0
  140. package/dist/core/risk/guardrail.d.ts +3 -0
  141. package/dist/core/risk/guardrail.d.ts.map +1 -0
  142. package/dist/core/risk/guardrail.js +47 -0
  143. package/dist/core/risk/guardrail.js.map +1 -0
  144. package/dist/core/risk/riskEngine.d.ts +8 -0
  145. package/dist/core/risk/riskEngine.d.ts.map +1 -0
  146. package/dist/core/risk/riskEngine.js +112 -0
  147. package/dist/core/risk/riskEngine.js.map +1 -0
  148. package/dist/core/risk/riskHeuristics.d.ts +4 -0
  149. package/dist/core/risk/riskHeuristics.d.ts.map +1 -0
  150. package/dist/core/risk/riskHeuristics.js +36 -0
  151. package/dist/core/risk/riskHeuristics.js.map +1 -0
  152. package/dist/core/salience/config.d.ts +14 -0
  153. package/dist/core/salience/config.d.ts.map +1 -0
  154. package/dist/core/salience/config.js +87 -0
  155. package/dist/core/salience/config.js.map +1 -0
  156. package/dist/core/salience/salienceEngine.d.ts +16 -0
  157. package/dist/core/salience/salienceEngine.d.ts.map +1 -0
  158. package/dist/core/salience/salienceEngine.js +64 -0
  159. package/dist/core/salience/salienceEngine.js.map +1 -0
  160. package/dist/core/salience/signals.d.ts +4 -0
  161. package/dist/core/salience/signals.d.ts.map +1 -0
  162. package/dist/core/salience/signals.js +143 -0
  163. package/dist/core/salience/signals.js.map +1 -0
  164. package/dist/core/salience/types.d.ts +69 -0
  165. package/dist/core/salience/types.d.ts.map +1 -0
  166. package/dist/core/salience/types.js +7 -0
  167. package/dist/core/salience/types.js.map +1 -0
  168. package/dist/core/session/eventPayloads.d.ts +92 -0
  169. package/dist/core/session/eventPayloads.d.ts.map +1 -0
  170. package/dist/core/session/eventPayloads.js +2 -0
  171. package/dist/core/session/eventPayloads.js.map +1 -0
  172. package/dist/core/session/reducer.d.ts +14 -0
  173. package/dist/core/session/reducer.d.ts.map +1 -0
  174. package/dist/core/session/reducer.js +181 -0
  175. package/dist/core/session/reducer.js.map +1 -0
  176. package/dist/core/session/sessionManager.d.ts +252 -0
  177. package/dist/core/session/sessionManager.d.ts.map +1 -0
  178. package/dist/core/session/sessionManager.js +655 -0
  179. package/dist/core/session/sessionManager.js.map +1 -0
  180. package/dist/core/telemetry/analytics.d.ts +24 -0
  181. package/dist/core/telemetry/analytics.d.ts.map +1 -0
  182. package/dist/core/telemetry/analytics.js +167 -0
  183. package/dist/core/telemetry/analytics.js.map +1 -0
  184. package/dist/core/telemetry/exporter.d.ts +17 -0
  185. package/dist/core/telemetry/exporter.d.ts.map +1 -0
  186. package/dist/core/telemetry/exporter.js +31 -0
  187. package/dist/core/telemetry/exporter.js.map +1 -0
  188. package/dist/core/telemetry/recorder.d.ts +19 -0
  189. package/dist/core/telemetry/recorder.d.ts.map +1 -0
  190. package/dist/core/telemetry/recorder.js +43 -0
  191. package/dist/core/telemetry/recorder.js.map +1 -0
  192. package/dist/core/telemetry/reports.d.ts +6 -0
  193. package/dist/core/telemetry/reports.d.ts.map +1 -0
  194. package/dist/core/telemetry/reports.js +84 -0
  195. package/dist/core/telemetry/reports.js.map +1 -0
  196. package/dist/core/telemetry/types.d.ts +82 -0
  197. package/dist/core/telemetry/types.d.ts.map +1 -0
  198. package/dist/core/telemetry/types.js +9 -0
  199. package/dist/core/telemetry/types.js.map +1 -0
  200. package/dist/core/vector/chunking/memoryChunker.d.ts +10 -0
  201. package/dist/core/vector/chunking/memoryChunker.d.ts.map +1 -0
  202. package/dist/core/vector/chunking/memoryChunker.js +202 -0
  203. package/dist/core/vector/chunking/memoryChunker.js.map +1 -0
  204. package/dist/core/vector/compression/architectureDigest.d.ts +12 -0
  205. package/dist/core/vector/compression/architectureDigest.d.ts.map +1 -0
  206. package/dist/core/vector/compression/architectureDigest.js +37 -0
  207. package/dist/core/vector/compression/architectureDigest.js.map +1 -0
  208. package/dist/core/vector/embedding/deterministicEmbedder.d.ts +10 -0
  209. package/dist/core/vector/embedding/deterministicEmbedder.d.ts.map +1 -0
  210. package/dist/core/vector/embedding/deterministicEmbedder.js +84 -0
  211. package/dist/core/vector/embedding/deterministicEmbedder.js.map +1 -0
  212. package/dist/core/vector/memory/memoryEngine.d.ts +56 -0
  213. package/dist/core/vector/memory/memoryEngine.d.ts.map +1 -0
  214. package/dist/core/vector/memory/memoryEngine.js +204 -0
  215. package/dist/core/vector/memory/memoryEngine.js.map +1 -0
  216. package/dist/core/vector/memory/memoryFingerprint.d.ts +12 -0
  217. package/dist/core/vector/memory/memoryFingerprint.d.ts.map +1 -0
  218. package/dist/core/vector/memory/memoryFingerprint.js +33 -0
  219. package/dist/core/vector/memory/memoryFingerprint.js.map +1 -0
  220. package/dist/core/vector/providers/deterministicProvider.d.ts +14 -0
  221. package/dist/core/vector/providers/deterministicProvider.d.ts.map +1 -0
  222. package/dist/core/vector/providers/deterministicProvider.js +22 -0
  223. package/dist/core/vector/providers/deterministicProvider.js.map +1 -0
  224. package/dist/core/vector/providers/httpEmbeddingProvider.d.ts +32 -0
  225. package/dist/core/vector/providers/httpEmbeddingProvider.d.ts.map +1 -0
  226. package/dist/core/vector/providers/httpEmbeddingProvider.js +93 -0
  227. package/dist/core/vector/providers/httpEmbeddingProvider.js.map +1 -0
  228. package/dist/core/vector/providers/registry.d.ts +9 -0
  229. package/dist/core/vector/providers/registry.d.ts.map +1 -0
  230. package/dist/core/vector/providers/registry.js +79 -0
  231. package/dist/core/vector/providers/registry.js.map +1 -0
  232. package/dist/core/vector/providers/types.d.ts +23 -0
  233. package/dist/core/vector/providers/types.d.ts.map +1 -0
  234. package/dist/core/vector/providers/types.js +2 -0
  235. package/dist/core/vector/providers/types.js.map +1 -0
  236. package/dist/core/vector/retrieval/hybridRetriever.d.ts +37 -0
  237. package/dist/core/vector/retrieval/hybridRetriever.d.ts.map +1 -0
  238. package/dist/core/vector/retrieval/hybridRetriever.js +131 -0
  239. package/dist/core/vector/retrieval/hybridRetriever.js.map +1 -0
  240. package/dist/core/vector/types.d.ts +87 -0
  241. package/dist/core/vector/types.d.ts.map +1 -0
  242. package/dist/core/vector/types.js +6 -0
  243. package/dist/core/vector/types.js.map +1 -0
  244. package/dist/index.d.ts +3 -0
  245. package/dist/index.d.ts.map +1 -0
  246. package/dist/index.js +30 -0
  247. package/dist/index.js.map +1 -0
  248. package/dist/inspect/cli.d.ts +3 -0
  249. package/dist/inspect/cli.d.ts.map +1 -0
  250. package/dist/inspect/cli.js +40 -0
  251. package/dist/inspect/cli.js.map +1 -0
  252. package/dist/inspect/projections.d.ts +141 -0
  253. package/dist/inspect/projections.d.ts.map +1 -0
  254. package/dist/inspect/projections.js +311 -0
  255. package/dist/inspect/projections.js.map +1 -0
  256. package/dist/inspect/render.d.ts +27 -0
  257. package/dist/inspect/render.d.ts.map +1 -0
  258. package/dist/inspect/render.js +325 -0
  259. package/dist/inspect/render.js.map +1 -0
  260. package/dist/inspect/server.d.ts +18 -0
  261. package/dist/inspect/server.d.ts.map +1 -0
  262. package/dist/inspect/server.js +112 -0
  263. package/dist/inspect/server.js.map +1 -0
  264. package/dist/perf/index.d.ts +24 -0
  265. package/dist/perf/index.d.ts.map +1 -0
  266. package/dist/perf/index.js +38 -0
  267. package/dist/perf/index.js.map +1 -0
  268. package/dist/perf/report.d.ts +8 -0
  269. package/dist/perf/report.d.ts.map +1 -0
  270. package/dist/perf/report.js +52 -0
  271. package/dist/perf/report.js.map +1 -0
  272. package/dist/perf/runner.d.ts +29 -0
  273. package/dist/perf/runner.d.ts.map +1 -0
  274. package/dist/perf/runner.js +74 -0
  275. package/dist/perf/runner.js.map +1 -0
  276. package/dist/perf/scenarios.d.ts +8 -0
  277. package/dist/perf/scenarios.d.ts.map +1 -0
  278. package/dist/perf/scenarios.js +119 -0
  279. package/dist/perf/scenarios.js.map +1 -0
  280. package/dist/perf/types.d.ts +32 -0
  281. package/dist/perf/types.d.ts.map +1 -0
  282. package/dist/perf/types.js +6 -0
  283. package/dist/perf/types.js.map +1 -0
  284. package/dist/plugins/loader.d.ts +78 -0
  285. package/dist/plugins/loader.d.ts.map +1 -0
  286. package/dist/plugins/loader.js +193 -0
  287. package/dist/plugins/loader.js.map +1 -0
  288. package/dist/plugins/types.d.ts +38 -0
  289. package/dist/plugins/types.d.ts.map +1 -0
  290. package/dist/plugins/types.js +10 -0
  291. package/dist/plugins/types.js.map +1 -0
  292. package/dist/pressure/pressureModel.d.ts +6 -0
  293. package/dist/pressure/pressureModel.d.ts.map +1 -0
  294. package/dist/pressure/pressureModel.js +102 -0
  295. package/dist/pressure/pressureModel.js.map +1 -0
  296. package/dist/prompts/continuityPrompt.d.ts +7 -0
  297. package/dist/prompts/continuityPrompt.d.ts.map +1 -0
  298. package/dist/prompts/continuityPrompt.js +43 -0
  299. package/dist/prompts/continuityPrompt.js.map +1 -0
  300. package/dist/sdk/index.d.ts +53 -0
  301. package/dist/sdk/index.d.ts.map +1 -0
  302. package/dist/sdk/index.js +130 -0
  303. package/dist/sdk/index.js.map +1 -0
  304. package/dist/security/patterns.d.ts +16 -0
  305. package/dist/security/patterns.d.ts.map +1 -0
  306. package/dist/security/patterns.js +61 -0
  307. package/dist/security/patterns.js.map +1 -0
  308. package/dist/security/redactor.d.ts +20 -0
  309. package/dist/security/redactor.d.ts.map +1 -0
  310. package/dist/security/redactor.js +58 -0
  311. package/dist/security/redactor.js.map +1 -0
  312. package/dist/server/createServer.d.ts +10 -0
  313. package/dist/server/createServer.d.ts.map +1 -0
  314. package/dist/server/createServer.js +60 -0
  315. package/dist/server/createServer.js.map +1 -0
  316. package/dist/server/registerTools.d.ts +4 -0
  317. package/dist/server/registerTools.d.ts.map +1 -0
  318. package/dist/server/registerTools.js +1086 -0
  319. package/dist/server/registerTools.js.map +1 -0
  320. package/dist/server/responses.d.ts +17 -0
  321. package/dist/server/responses.d.ts.map +1 -0
  322. package/dist/server/responses.js +21 -0
  323. package/dist/server/responses.js.map +1 -0
  324. package/dist/snapshot/export.d.ts +26 -0
  325. package/dist/snapshot/export.d.ts.map +1 -0
  326. package/dist/snapshot/export.js +164 -0
  327. package/dist/snapshot/export.js.map +1 -0
  328. package/dist/snapshot/import.d.ts +34 -0
  329. package/dist/snapshot/import.d.ts.map +1 -0
  330. package/dist/snapshot/import.js +114 -0
  331. package/dist/snapshot/import.js.map +1 -0
  332. package/dist/snapshot/types.d.ts +63 -0
  333. package/dist/snapshot/types.d.ts.map +1 -0
  334. package/dist/snapshot/types.js +2 -0
  335. package/dist/snapshot/types.js.map +1 -0
  336. package/dist/storage/faultAdapter.d.ts +64 -0
  337. package/dist/storage/faultAdapter.d.ts.map +1 -0
  338. package/dist/storage/faultAdapter.js +134 -0
  339. package/dist/storage/faultAdapter.js.map +1 -0
  340. package/dist/storage/fileStorageAdapter.d.ts +55 -0
  341. package/dist/storage/fileStorageAdapter.d.ts.map +1 -0
  342. package/dist/storage/fileStorageAdapter.js +219 -0
  343. package/dist/storage/fileStorageAdapter.js.map +1 -0
  344. package/dist/storage/paths.d.ts +30 -0
  345. package/dist/storage/paths.d.ts.map +1 -0
  346. package/dist/storage/paths.js +32 -0
  347. package/dist/storage/paths.js.map +1 -0
  348. package/dist/storage/quarantine.d.ts +36 -0
  349. package/dist/storage/quarantine.d.ts.map +1 -0
  350. package/dist/storage/quarantine.js +26 -0
  351. package/dist/storage/quarantine.js.map +1 -0
  352. package/dist/storage/redactingAdapter.d.ts +13 -0
  353. package/dist/storage/redactingAdapter.d.ts.map +1 -0
  354. package/dist/storage/redactingAdapter.js +91 -0
  355. package/dist/storage/redactingAdapter.js.map +1 -0
  356. package/dist/storage/storageAdapter.d.ts +46 -0
  357. package/dist/storage/storageAdapter.d.ts.map +1 -0
  358. package/dist/storage/storageAdapter.js +2 -0
  359. package/dist/storage/storageAdapter.js.map +1 -0
  360. package/dist/types/domain.d.ts +139 -0
  361. package/dist/types/domain.d.ts.map +1 -0
  362. package/dist/types/domain.js +9 -0
  363. package/dist/types/domain.js.map +1 -0
  364. package/dist/types/events.d.ts +28 -0
  365. package/dist/types/events.d.ts.map +1 -0
  366. package/dist/types/events.js +7 -0
  367. package/dist/types/events.js.map +1 -0
  368. package/dist/utils/errors.d.ts +6 -0
  369. package/dist/utils/errors.d.ts.map +1 -0
  370. package/dist/utils/errors.js +10 -0
  371. package/dist/utils/errors.js.map +1 -0
  372. package/dist/utils/ids.d.ts +7 -0
  373. package/dist/utils/ids.d.ts.map +1 -0
  374. package/dist/utils/ids.js +22 -0
  375. package/dist/utils/ids.js.map +1 -0
  376. package/dist/utils/logger.d.ts +7 -0
  377. package/dist/utils/logger.d.ts.map +1 -0
  378. package/dist/utils/logger.js +26 -0
  379. package/dist/utils/logger.js.map +1 -0
  380. package/dist/utils/time.d.ts +8 -0
  381. package/dist/utils/time.d.ts.map +1 -0
  382. package/dist/utils/time.js +11 -0
  383. package/dist/utils/time.js.map +1 -0
  384. package/package.json +79 -0
@@ -0,0 +1,1086 @@
1
+ import { z } from 'zod';
2
+ import { summarizeIntelligence } from '../core/repo/summary.js';
3
+ import { ok, fail } from './responses.js';
4
+ import { KairoError } from '../utils/errors.js';
5
+ import { exportSnapshot } from '../snapshot/export.js';
6
+ import { importSnapshot } from '../snapshot/import.js';
7
+ import { runBenchmark } from '../perf/index.js';
8
+ import { compact } from '../core/compaction/compactor.js';
9
+ import { readFile } from 'node:fs/promises';
10
+ import { kairoPaths } from '../storage/paths.js';
11
+ import { loadPlugins } from '../plugins/loader.js';
12
+ import { stabilityOf, STABILITY } from '../contracts/stability.js';
13
+ function projectRootFrom(explicit) {
14
+ return explicit ?? process.env.KAIRO_PROJECT_ROOT ?? process.cwd();
15
+ }
16
+ const RECORD_KINDS = [
17
+ 'file',
18
+ 'decision',
19
+ 'command',
20
+ 'error',
21
+ 'error-resolved',
22
+ 'retry',
23
+ 'note',
24
+ 'compaction',
25
+ 'clarification',
26
+ 'completed',
27
+ 'pending',
28
+ 'blocker',
29
+ ];
30
+ const CHANGE_KINDS = ['created', 'modified', 'deleted', 'renamed'];
31
+ const RISKS = ['low', 'medium', 'high'];
32
+ const CHECKPOINT_REASONS = ['manual', 'pressure', 'session-end'];
33
+ /** Maps the flat `kairo_record` input onto the typed RecordKind union. */
34
+ function toRecordInput(i) {
35
+ const need = (v, field) => {
36
+ if (v === undefined || v === '') {
37
+ throw new KairoError(`kairo_record kind="${i.kind}" requires "${field}".`);
38
+ }
39
+ return v;
40
+ };
41
+ switch (i.kind) {
42
+ case 'file':
43
+ return {
44
+ kind: 'file',
45
+ path: need(i.path, 'path'),
46
+ ...(i.changeKind ? { changeKind: i.changeKind } : {}),
47
+ ...(i.risk ? { risk: i.risk } : {}),
48
+ ...(i.bytes !== undefined ? { bytes: i.bytes } : {}),
49
+ ...(i.note !== undefined ? { note: i.note } : {}),
50
+ };
51
+ case 'decision':
52
+ return {
53
+ kind: 'decision',
54
+ summary: need(i.summary, 'summary'),
55
+ ...(i.rationale !== undefined ? { rationale: i.rationale } : {}),
56
+ };
57
+ case 'command':
58
+ return {
59
+ kind: 'command',
60
+ command: need(i.command, 'command'),
61
+ ...(i.exitCode !== undefined ? { exitCode: i.exitCode } : {}),
62
+ ...(i.note !== undefined ? { note: i.note } : {}),
63
+ };
64
+ case 'error':
65
+ return {
66
+ kind: 'error',
67
+ message: need(i.message, 'message'),
68
+ ...(i.context !== undefined ? { context: i.context } : {}),
69
+ };
70
+ case 'error-resolved':
71
+ return { kind: 'error-resolved', message: need(i.message, 'message') };
72
+ case 'retry':
73
+ return { kind: 'retry', ...(i.what !== undefined ? { what: i.what } : {}) };
74
+ case 'note':
75
+ return { kind: 'note', note: need(i.note, 'note') };
76
+ case 'compaction':
77
+ return { kind: 'compaction', ...(i.note !== undefined ? { note: i.note } : {}) };
78
+ case 'clarification':
79
+ return { kind: 'clarification', ...(i.note !== undefined ? { note: i.note } : {}) };
80
+ case 'completed':
81
+ return { kind: 'completed', item: need(i.item, 'item') };
82
+ case 'pending':
83
+ return { kind: 'pending', item: need(i.item, 'item') };
84
+ case 'blocker':
85
+ return { kind: 'blocker', item: need(i.item, 'item') };
86
+ }
87
+ }
88
+ export function registerTools(server, sessions) {
89
+ server.registerTool('kairo_session_start', {
90
+ title: 'Start / resume a Kairo session',
91
+ description: 'Begin a Kairo session. Returns the continuation brief from prior work so you ' +
92
+ 'can resume WITHOUT rescanning the repository. Call this before any other Kairo ' +
93
+ 'tool. Storage location is fixed by KAIRO_PROJECT_ROOT (or cwd) at server launch; ' +
94
+ 'projectRoot here is recorded for the brief.',
95
+ inputSchema: {
96
+ agent: z.string().min(1).describe('Agent identifier, e.g. "claude-code".'),
97
+ task: z.string().min(1).describe('What this session is trying to accomplish.'),
98
+ projectRoot: z.string().optional().describe('Informational project root path.'),
99
+ worker: z
100
+ .string()
101
+ .optional()
102
+ .describe('Coordination worker id for multi-agent work (default: agent).'),
103
+ namespace: z
104
+ .string()
105
+ .optional()
106
+ .describe('Memory namespace; default isolates this worker. Use "workspace" to share.'),
107
+ },
108
+ }, async ({ agent, task, projectRoot, worker, namespace }) => {
109
+ try {
110
+ const r = await sessions.startSession({
111
+ agent,
112
+ task,
113
+ projectRoot: projectRootFrom(projectRoot),
114
+ ...(worker !== undefined ? { worker } : {}),
115
+ ...(namespace !== undefined ? { namespace } : {}),
116
+ });
117
+ const summary = r.resumed
118
+ ? `Resumed. A prior continuation brief was found and is included below — resume from it; do not rescan the repo.`
119
+ : `New session started. No prior continuation brief found.`;
120
+ const intelBlock = r.intelligence
121
+ ? `\n\n--- REPO INTELLIGENCE (${r.intelligenceFromCache ? 'cached' : 'freshly scanned'}) ---\n` +
122
+ summarizeIntelligence(r.intelligence)
123
+ : '';
124
+ return ok(`${summary}\n\nSession: ${r.sessionId}` +
125
+ (r.priorBrief ? `\n\n--- PRIOR CONTINUATION BRIEF ---\n${r.priorBrief}` : '') +
126
+ intelBlock, {
127
+ sessionId: r.sessionId,
128
+ resumed: r.resumed,
129
+ intelligenceFromCache: r.intelligenceFromCache,
130
+ fingerprint: r.intelligence?.fingerprint ?? null,
131
+ }, r.pressure);
132
+ }
133
+ catch (e) {
134
+ return fail(e);
135
+ }
136
+ });
137
+ server.registerTool('kairo_session_status', {
138
+ title: 'Kairo session status',
139
+ description: 'Current session ledger summary, pressure score, and directive.',
140
+ inputSchema: {},
141
+ }, () => {
142
+ try {
143
+ const { state, pressure } = sessions.status();
144
+ const risk = sessions.sessionRisk();
145
+ return ok(`Session ${state.id} (${state.status}) — ${Object.keys(state.changedFiles).length} files changed, ` +
146
+ `${state.errors.filter((e) => !e.resolved).length} unresolved error(s). ` +
147
+ `Engineering risk: ${risk.level.toUpperCase()} (${risk.score}).`, {
148
+ id: state.id,
149
+ agent: state.agent,
150
+ task: state.task,
151
+ status: state.status,
152
+ changedFiles: Object.values(state.changedFiles),
153
+ decisions: state.decisions,
154
+ pendingWork: state.pendingWork,
155
+ completedWork: state.completedWork,
156
+ blockers: state.blockers,
157
+ errors: state.errors,
158
+ risk,
159
+ lastCheckpointId: state.lastCheckpointId ?? null,
160
+ }, pressure);
161
+ }
162
+ catch (e) {
163
+ return fail(e);
164
+ }
165
+ });
166
+ server.registerTool('kairo_record', {
167
+ title: 'Record an engineering event',
168
+ description: 'Log an event to Kairo memory: file/decision/command/error/error-resolved/' +
169
+ 'retry/note/completed/pending/blocker, plus "compaction" (report when your ' +
170
+ 'context was summarized/compacted) and "clarification" (you had to re-ask the ' +
171
+ 'user) — both are strong context-loss signals. Returns the pressure directive.',
172
+ inputSchema: {
173
+ kind: z.enum(RECORD_KINDS),
174
+ path: z.string().optional(),
175
+ changeKind: z.enum(CHANGE_KINDS).optional(),
176
+ risk: z.enum(RISKS).optional().describe('Omit to let Kairo infer from the path.'),
177
+ bytes: z.number().int().nonnegative().optional(),
178
+ note: z.string().optional(),
179
+ summary: z.string().optional(),
180
+ rationale: z.string().optional(),
181
+ command: z.string().optional(),
182
+ exitCode: z.number().int().optional(),
183
+ message: z.string().optional(),
184
+ context: z.string().optional(),
185
+ what: z.string().optional(),
186
+ item: z.string().optional(),
187
+ },
188
+ }, async (input) => {
189
+ try {
190
+ const pressure = await sessions.record(toRecordInput(input));
191
+ return ok(`Recorded ${input.kind}.`, { recorded: input.kind }, pressure);
192
+ }
193
+ catch (e) {
194
+ return fail(e);
195
+ }
196
+ });
197
+ server.registerTool('kairo_heartbeat', {
198
+ title: 'Session heartbeat',
199
+ description: 'Cheap pulse. Pass `reread` with a file path if you re-read a file you had ' +
200
+ 'already seen — repeated re-reads are the strongest context-loss signal.',
201
+ inputSchema: {
202
+ reread: z.string().optional().describe('Path of a file you re-read.'),
203
+ note: z.string().optional(),
204
+ turns: z.number().int().nonnegative().optional().describe('Turns since last heartbeat.'),
205
+ },
206
+ }, async (args) => {
207
+ try {
208
+ const pressure = await sessions.heartbeat(args);
209
+ return ok('Heartbeat recorded.', { directive: pressure.directive }, pressure);
210
+ }
211
+ catch (e) {
212
+ return fail(e);
213
+ }
214
+ });
215
+ server.registerTool('kairo_checkpoint', {
216
+ title: 'Create a durable checkpoint',
217
+ description: 'Freeze a sanitized, resumable checkpoint and generate the next-agent ' +
218
+ 'continuation brief. Call this on a CHECKPOINT_NOW directive.',
219
+ inputSchema: {
220
+ reason: z.enum(CHECKPOINT_REASONS).optional(),
221
+ completed: z.array(z.string()).optional(),
222
+ remaining: z.array(z.string()).optional(),
223
+ blockers: z.array(z.string()).optional(),
224
+ },
225
+ }, async (args) => {
226
+ try {
227
+ const r = await sessions.checkpoint({
228
+ reason: args.reason ?? 'manual',
229
+ ...(args.completed ? { completed: args.completed } : {}),
230
+ ...(args.remaining ? { remaining: args.remaining } : {}),
231
+ ...(args.blockers ? { blockers: args.blockers } : {}),
232
+ });
233
+ return ok(`Checkpoint ${r.checkpoint.id} created.\n\n--- CONTINUATION BRIEF ---\n${r.brief}`, { checkpointId: r.checkpoint.id, continuationRef: r.checkpoint.continuationRef }, r.pressure);
234
+ }
235
+ catch (e) {
236
+ return fail(e);
237
+ }
238
+ });
239
+ server.registerTool('kairo_continuation', {
240
+ title: 'Fetch latest continuation brief',
241
+ description: 'Return the most recent continuation brief (the next-agent handoff).',
242
+ inputSchema: {},
243
+ }, async () => {
244
+ try {
245
+ const brief = await sessions.latestContinuation();
246
+ if (!brief) {
247
+ return ok('No continuation brief exists yet.', { found: false });
248
+ }
249
+ return ok(brief, { found: true });
250
+ }
251
+ catch (e) {
252
+ return fail(e);
253
+ }
254
+ });
255
+ server.registerTool('kairo_session_end', {
256
+ title: 'End the Kairo session',
257
+ description: 'Write a closing checkpoint + continuation brief and finalize the session.',
258
+ inputSchema: {},
259
+ }, async () => {
260
+ try {
261
+ const r = await sessions.endSession();
262
+ return ok(`Session ended. Closing checkpoint ${r.checkpoint.id}.\n\n--- CONTINUATION BRIEF ---\n${r.brief}`, { checkpointId: r.checkpoint.id });
263
+ }
264
+ catch (e) {
265
+ return fail(e);
266
+ }
267
+ });
268
+ server.registerTool('kairo_repo_scan', {
269
+ title: 'Scan / refresh repository intelligence',
270
+ description: 'Return cached repo intelligence (frameworks, languages, entry points, ' +
271
+ 'structural fingerprint). Pass force:true to rescan. Prefer the cached result — ' +
272
+ 'rescanning is what Kairo exists to avoid.',
273
+ inputSchema: {
274
+ force: z.boolean().optional().describe('Rescan even if a cached artifact exists.'),
275
+ projectRoot: z.string().optional(),
276
+ },
277
+ }, async ({ force, projectRoot }) => {
278
+ try {
279
+ const r = await sessions.scanRepo(projectRootFrom(projectRoot), force ?? false);
280
+ const note = r.fromCache
281
+ ? 'Served from cache (no rescan).'
282
+ : r.changed
283
+ ? 'Rescanned — repository fingerprint CHANGED since last scan.'
284
+ : 'Rescanned — fingerprint unchanged.';
285
+ return ok(`${note}\n\n${summarizeIntelligence(r.intelligence)}`, {
286
+ fromCache: r.fromCache,
287
+ changed: r.changed,
288
+ fingerprint: r.intelligence.fingerprint,
289
+ frameworks: r.intelligence.frameworks,
290
+ entryPoints: r.intelligence.entryPoints,
291
+ languages: r.intelligence.languages,
292
+ inventory: r.intelligence.inventory,
293
+ });
294
+ }
295
+ catch (e) {
296
+ return fail(e);
297
+ }
298
+ });
299
+ server.registerTool('kairo_repo_intel', {
300
+ title: 'Get cached repository intelligence',
301
+ description: 'Return the cached repo intelligence summary without scanning.',
302
+ inputSchema: {},
303
+ }, async () => {
304
+ try {
305
+ const intel = await sessions.getIntelligence();
306
+ if (!intel) {
307
+ return ok('No repo intelligence cached yet. Call kairo_repo_scan.', { found: false });
308
+ }
309
+ return ok(summarizeIntelligence(intel), { found: true, fingerprint: intel.fingerprint });
310
+ }
311
+ catch (e) {
312
+ return fail(e);
313
+ }
314
+ });
315
+ server.registerTool('kairo_assess', {
316
+ title: 'Assess engineering risk vs. context-loss pressure',
317
+ description: 'Call BEFORE a risky change. Returns ALLOW / CAUTION / HOLD. Kairo gets more ' +
318
+ 'conservative as pressure rises, so the same change can flip to HOLD late in a ' +
319
+ 'session. With no files, assesses accumulated session risk.',
320
+ inputSchema: {
321
+ intent: z.string().optional().describe('What you are about to do.'),
322
+ files: z
323
+ .array(z.object({
324
+ path: z.string(),
325
+ changeKind: z.enum(CHANGE_KINDS).optional(),
326
+ risk: z.enum(RISKS).optional(),
327
+ }))
328
+ .optional(),
329
+ },
330
+ }, async ({ intent, files }) => {
331
+ try {
332
+ const g = sessions.assess({
333
+ ...(intent !== undefined ? { intent } : {}),
334
+ ...(files !== undefined ? { files } : {}),
335
+ });
336
+ await sessions.recordAssessment(g.decision, g.risk.level, g.pressure.directive);
337
+ return ok(`${g.directive}\n\n${g.reasons.join('\n')}`, {
338
+ decision: g.decision,
339
+ risk: g.risk,
340
+ pressureDirective: g.pressure.directive,
341
+ pressureScore: g.pressure.score,
342
+ }, g.pressure);
343
+ }
344
+ catch (e) {
345
+ return fail(e);
346
+ }
347
+ });
348
+ // ── GitHub engine (advisory only — Kairo never mutates the repo; ADR-0003) ──
349
+ server.registerTool('kairo_git_status', {
350
+ title: 'Read-only git context',
351
+ description: 'Branch, ahead/behind, staged/unstaged/untracked counts, last tag, recent ' +
352
+ 'commit subjects. Read-only — Kairo never stages, commits, tags, or pushes.',
353
+ inputSchema: {},
354
+ }, async () => {
355
+ try {
356
+ const g = await sessions.gitContext();
357
+ if (!g.isRepo)
358
+ return ok('Not a git repository.', { isRepo: false });
359
+ return ok(`Branch ${g.branch ?? '(detached)'} — ${g.staged} staged, ${g.unstaged} unstaged, ` +
360
+ `${g.untracked} untracked. Last tag: ${g.lastTag ?? 'none'}.`, g);
361
+ }
362
+ catch (e) {
363
+ return fail(e);
364
+ }
365
+ });
366
+ server.registerTool('kairo_commit_message', {
367
+ title: 'Propose a semantic commit message',
368
+ description: 'Generate a Conventional-Commits message from the session ledger (decisions, ' +
369
+ 'changed files, risk). Returns text only — it does NOT create a commit.',
370
+ inputSchema: {
371
+ summary: z.string().optional().describe('Optional extra summary to lead the body.'),
372
+ },
373
+ }, ({ summary }) => {
374
+ try {
375
+ const c = sessions.proposeCommitMessage(summary);
376
+ return ok(`${c.message}\n\n--- reasoning ---\n${c.reasoning.join('\n')}`, {
377
+ type: c.type,
378
+ scope: c.scope ?? null,
379
+ header: c.header,
380
+ message: c.message,
381
+ });
382
+ }
383
+ catch (e) {
384
+ return fail(e);
385
+ }
386
+ });
387
+ server.registerTool('kairo_changelog', {
388
+ title: 'Propose a changelog fragment',
389
+ description: 'Generate a Keep-a-Changelog fragment from the session. Text only — it does ' +
390
+ 'NOT edit CHANGELOG.md.',
391
+ inputSchema: {},
392
+ }, () => {
393
+ try {
394
+ const f = sessions.proposeChangelog();
395
+ return ok(f.markdown, { markdown: f.markdown });
396
+ }
397
+ catch (e) {
398
+ return fail(e);
399
+ }
400
+ });
401
+ server.registerTool('kairo_release_plan', {
402
+ title: 'Propose a release plan',
403
+ description: 'Suggest the next semver bump, tag, and release notes from the session and the ' +
404
+ "project's package.json version. Plan only — no version bump, tag, or push.",
405
+ inputSchema: {},
406
+ }, async () => {
407
+ try {
408
+ const p = await sessions.proposeReleasePlan();
409
+ return ok(`${p.currentVersion} → ${p.nextVersion} (${p.bump}), tag ${p.tag}\n\n` +
410
+ `${p.notes}\n\n--- reasoning ---\n${p.reasoning.join('\n')}`, p);
411
+ }
412
+ catch (e) {
413
+ return fail(e);
414
+ }
415
+ });
416
+ // ── Flow / graph engine (v0.5.0) ─────────────────────────────────────────
417
+ server.registerTool('kairo_graph', {
418
+ title: 'Render a repository graph as Mermaid',
419
+ description: 'Return a graph derived from cached repo intelligence (no rescan): ' +
420
+ '"module" / "service" / "architecture" / "pipeline". Mirrors are written to ' +
421
+ '.kairo/graphs/. Default response is COMPACT (summary + file path); pass ' +
422
+ 'includeFull:true to inline the full Mermaid (ADR-0010 token efficiency).',
423
+ inputSchema: {
424
+ kind: z.enum(['module', 'service', 'architecture', 'pipeline']).optional(),
425
+ includeFull: z.boolean().optional().describe('Inline full Mermaid (default false).'),
426
+ },
427
+ }, async ({ kind, includeFull }) => {
428
+ try {
429
+ const k = kind ?? 'module';
430
+ const result = await sessions.graph(k);
431
+ if (!result) {
432
+ return ok('No repo intelligence cached yet. Call kairo_repo_scan first.', {
433
+ found: false,
434
+ });
435
+ }
436
+ const summary = `${k} graph: ${result.graph.nodes.length} nodes / ${result.graph.edges.length} edges` +
437
+ `${result.graph.truncated ? ' (truncated)' : ''}. Mirror: .kairo/graphs/${k}.md`;
438
+ return ok(includeFull ? `${summary}\n\n${result.markdown}` : summary, {
439
+ found: true,
440
+ kind: result.graph.kind,
441
+ nodes: result.graph.nodes.length,
442
+ edges: result.graph.edges.length,
443
+ truncated: result.graph.truncated,
444
+ });
445
+ }
446
+ catch (e) {
447
+ return fail(e);
448
+ }
449
+ });
450
+ // ── Semantic memory (v0.6.0) ─────────────────────────────────────────────
451
+ server.registerTool('kairo_memory_search', {
452
+ title: 'Semantic architecture recall',
453
+ description: 'Hybrid, explainable recall over Kairo memory (structural/semantic/session/' +
454
+ 'decision/operational). Ranks by similarity + salience + graph centrality + ' +
455
+ 'runtime layer + recency + checkpoint overlap — a central module beats a ' +
456
+ 'lexically similar example. Use this INSTEAD of rescanning the repo.',
457
+ inputSchema: {
458
+ query: z.string().describe('What architectural context you need.'),
459
+ limit: z.number().int().min(1).max(25).optional(),
460
+ kind: z.enum(['structural', 'semantic', 'session', 'decision', 'operational']).optional(),
461
+ },
462
+ }, async ({ query, limit, kind }) => {
463
+ try {
464
+ // Token-efficient default (ADR-0010): cap at 5 results unless caller asks for more.
465
+ const effectiveLimit = limit ?? 5;
466
+ const results = await sessions.searchMemory({
467
+ text: query,
468
+ limit: effectiveLimit,
469
+ ...(kind !== undefined ? { kind } : {}),
470
+ });
471
+ if (results.length === 0) {
472
+ return ok('Memory empty/unindexed. Call kairo_memory_index (or start a session).', {
473
+ found: false,
474
+ });
475
+ }
476
+ const body = results
477
+ .map((r, i) => `${i + 1}. [${r.chunk.kind}] ${r.chunk.locator} (score ${r.score.toFixed(3)}) — ${r.why.slice(0, 120)}`)
478
+ .join('\n');
479
+ return ok(body, {
480
+ found: true,
481
+ results: results.map((r) => ({
482
+ id: r.chunk.id,
483
+ kind: r.chunk.kind,
484
+ locator: r.chunk.locator,
485
+ score: r.score,
486
+ similarity: r.similarity,
487
+ factors: r.factors,
488
+ })),
489
+ });
490
+ }
491
+ catch (e) {
492
+ return fail(e);
493
+ }
494
+ });
495
+ server.registerTool('kairo_memory_index', {
496
+ title: 'Build / refresh semantic memory',
497
+ description: 'Build the architecture memory index. Fingerprint-keyed: a cache hit does NOT ' +
498
+ 're-embed. Pass force:true to rebuild.',
499
+ inputSchema: { force: z.boolean().optional() },
500
+ }, async ({ force }) => {
501
+ try {
502
+ const r = await sessions.indexMemory(undefined, force ?? false);
503
+ if (!r) {
504
+ return ok('No repo intelligence yet. Start a session or run kairo_repo_scan.', {
505
+ indexed: false,
506
+ });
507
+ }
508
+ return ok(`${r.reused ? 'Reused cached index' : 'Rebuilt index'} — ${r.chunks} memory chunks.`, { indexed: true, ...r });
509
+ }
510
+ catch (e) {
511
+ return fail(e);
512
+ }
513
+ });
514
+ server.registerTool('kairo_memory_refresh', {
515
+ title: 'Refresh shared coordination memory',
516
+ description: 'Ensure shared memory reflects the latest decisions/checkpoints/worker state ' +
517
+ 'before retrieving (v0.7.1). Auto-invalidated by a deterministic memory ' +
518
+ 'fingerprint — rebuilds only if the chunk set changed, so repeated calls are ' +
519
+ 'idempotent. Private worker-namespace memory is never leaked.',
520
+ inputSchema: {},
521
+ }, async () => {
522
+ try {
523
+ const r = await sessions.refreshMemory();
524
+ if (!r) {
525
+ return ok('No repo intelligence yet. Start a session first.', { refreshed: false });
526
+ }
527
+ return ok(r.rebuilt
528
+ ? `Memory refreshed — rebuilt (${r.chunks} chunks); shared memory is now current.`
529
+ : `Memory already fresh — no rebuild needed (${r.chunks} chunks).`, { refreshed: true, ...r });
530
+ }
531
+ catch (e) {
532
+ return fail(e);
533
+ }
534
+ });
535
+ server.registerTool('kairo_memory_digest', {
536
+ title: 'Compressed architectural memory',
537
+ description: 'Deterministic salience-ordered architecture digest — read this instead of ' +
538
+ 'rescanning the repository. Heuristic extract (stated honestly), not an LLM summary.',
539
+ inputSchema: {},
540
+ }, async () => {
541
+ try {
542
+ const digest = await sessions.compressMemory();
543
+ return digest
544
+ ? ok(digest, { found: true })
545
+ : ok('No memory indexed yet. Call kairo_memory_index.', { found: false });
546
+ }
547
+ catch (e) {
548
+ return fail(e);
549
+ }
550
+ });
551
+ server.registerTool('kairo_brief', {
552
+ title: 'Continuation brief (token-efficient)',
553
+ description: 'Generate a continuation brief in tiny / normal / deep mode within a char budget ' +
554
+ '(ADR-0010). tiny = task/branch/changed/stop/next-3/critical-warnings only. ' +
555
+ 'normal = default, structured but trimmed. deep = full history (opt-in).',
556
+ inputSchema: {
557
+ mode: z.enum(['tiny', 'normal', 'deep']).optional(),
558
+ maxChars: z.number().int().min(200).max(50_000).optional(),
559
+ sessionId: z.string().optional().describe("Brief for this session's latest checkpoint."),
560
+ },
561
+ }, async ({ mode, maxChars, sessionId }) => {
562
+ try {
563
+ const r = await sessions.buildBrief({
564
+ ...(mode !== undefined ? { mode } : {}),
565
+ ...(maxChars !== undefined ? { maxChars } : {}),
566
+ ...(sessionId !== undefined ? { sessionId } : {}),
567
+ });
568
+ if (!r)
569
+ return ok('No checkpoint yet — nothing to brief.', { found: false });
570
+ return ok(r.markdown, { found: true, mode: r.mode, chars: r.chars });
571
+ }
572
+ catch (e) {
573
+ return fail(e);
574
+ }
575
+ });
576
+ // ── Coordinated cognition (v0.7.0) ───────────────────────────────────────
577
+ server.registerTool('kairo_lease', {
578
+ title: 'Coordinate work via a cooperative lease',
579
+ description: 'Advertise intent over a task/path/module so other workers do not collide. ' +
580
+ 'acquire returns granted|denied with an explanation and the conflicting holder. ' +
581
+ 'Advisory (ADR-0007): Kairo coordinates, it never preempts another process.',
582
+ inputSchema: {
583
+ action: z.enum(['acquire', 'renew', 'release']),
584
+ scopeKind: z.enum(['task', 'path', 'module']).optional(),
585
+ scope: z.string().optional().describe('Task text or path/module prefix.'),
586
+ leaseId: z.string().optional().describe('Required for renew/release.'),
587
+ ttlSeconds: z.number().int().min(1).max(86_400).optional(),
588
+ },
589
+ }, async ({ action, scopeKind, scope, leaseId, ttlSeconds }) => {
590
+ try {
591
+ let d;
592
+ if (action === 'acquire') {
593
+ if (!scopeKind || !scope) {
594
+ return fail(new KairoError('acquire requires scopeKind and scope.'));
595
+ }
596
+ d = await sessions.acquireLease({
597
+ scopeKind,
598
+ scope,
599
+ ...(ttlSeconds !== undefined ? { ttlSeconds } : {}),
600
+ });
601
+ }
602
+ else if (action === 'renew') {
603
+ if (!leaseId)
604
+ return fail(new KairoError('renew requires leaseId.'));
605
+ d = await sessions.renewLease(leaseId, ttlSeconds ?? 1800);
606
+ }
607
+ else {
608
+ if (!leaseId)
609
+ return fail(new KairoError('release requires leaseId.'));
610
+ d = await sessions.releaseLease(leaseId);
611
+ }
612
+ return ok(`${d.granted ? 'GRANTED' : 'DENIED'}: ${d.reason}`, {
613
+ granted: d.granted,
614
+ lease: d.lease ?? null,
615
+ conflict: d.conflict ?? null,
616
+ });
617
+ }
618
+ catch (e) {
619
+ return fail(e);
620
+ }
621
+ });
622
+ server.registerTool('kairo_coordination_status', {
623
+ title: 'Coordination status',
624
+ description: 'Active workers, held leases, and ownership across the shared engineering ' +
625
+ 'ledger — explainable conflict prevention for multi-agent work.',
626
+ inputSchema: {},
627
+ }, async () => {
628
+ try {
629
+ const s = await sessions.coordinationStatus();
630
+ const lines = [
631
+ `Workers (${s.workers.length}): ${s.workers.map((w) => `${w.workerId}[${w.namespace}]`).join(', ') || 'none'}`,
632
+ `Active leases (${s.activeLeases.length}):`,
633
+ ...s.activeLeases.map((l) => ` - ${l.scopeKind}:"${l.scope}" → ${l.workerId} (until ${l.expiresAt})`),
634
+ ];
635
+ return ok(lines.join('\n'), s);
636
+ }
637
+ catch (e) {
638
+ return fail(e);
639
+ }
640
+ });
641
+ server.registerTool('kairo_timeline', {
642
+ title: 'Engineering timeline (distributed checkpoint graph)',
643
+ description: 'Mermaid DAG of checkpoints across all workers/sessions — coherent engineering ' +
644
+ 'continuity, deterministic from the shared log.',
645
+ inputSchema: {},
646
+ }, async () => {
647
+ try {
648
+ const t = await sessions.timeline();
649
+ return ok(t.markdown, { checkpoints: t.checkpoints });
650
+ }
651
+ catch (e) {
652
+ return fail(e);
653
+ }
654
+ });
655
+ // ── Telemetry & analytics (v0.8.0) ───────────────────────────────────────
656
+ server.registerTool('kairo_telemetry_status', {
657
+ title: 'Telemetry status',
658
+ description: 'Local-only telemetry status: event counts by kind, export state. No network, ' +
659
+ 'no external analytics, secrets redacted (ADR-0008).',
660
+ inputSchema: {},
661
+ }, async () => {
662
+ try {
663
+ const s = await sessions.telemetryStatus();
664
+ return ok(`Telemetry: ${s.events} local events. Network: off. Export: ${s.exportEnabled ? 'opt-in enabled' : 'disabled'}.`, s);
665
+ }
666
+ catch (e) {
667
+ return fail(e);
668
+ }
669
+ });
670
+ server.registerTool('kairo_analytics_summary', {
671
+ title: 'Analytics summary',
672
+ description: 'Deterministic engineering analytics (sessions, checkpoints, guard holds, ' +
673
+ 'lease conflicts, cache rates, retrieval patterns). Writes ' +
674
+ '.kairo/reports/ANALYTICS_SUMMARY.md (+ TEAM_ACTIVITY/RISK_REPORT).',
675
+ inputSchema: {},
676
+ }, async () => {
677
+ try {
678
+ const { analytics } = await sessions.writeReports();
679
+ return ok(`Analytics: ${analytics.sessions} sessions, ${analytics.checkpoints} checkpoints, ` +
680
+ `${analytics.guardHoldCount} guard holds, lease conflict rate ` +
681
+ `${(analytics.leaseConflictRate * 100).toFixed(1)}%, cache hit ` +
682
+ `${(analytics.intelligenceCacheHitRate * 100).toFixed(1)}%. Reports written.`, analytics);
683
+ }
684
+ catch (e) {
685
+ return fail(e);
686
+ }
687
+ });
688
+ server.registerTool('kairo_team_activity', {
689
+ title: 'Team coordination activity',
690
+ description: 'Worker activity, lease-conflict map, and namespace usage from the shared ' +
691
+ 'ledger. Reports namespace names/counts only — never private memory contents.',
692
+ inputSchema: {},
693
+ }, async () => {
694
+ try {
695
+ const t = await sessions.teamActivity();
696
+ return ok(`${t.workers.length} worker(s), ${t.leaseConflicts.length} lease conflict(s), ` +
697
+ `namespaces: ${t.namespaces.join(', ') || '(none)'}.`, t);
698
+ }
699
+ catch (e) {
700
+ return fail(e);
701
+ }
702
+ });
703
+ server.registerTool('kairo_risk_report', {
704
+ title: 'Engineering risk report',
705
+ description: 'Risk escalations, guard holds, decision breakdown, and highest-risk modules. ' +
706
+ 'Deterministic projection.',
707
+ inputSchema: {},
708
+ }, async () => {
709
+ try {
710
+ const rr = await sessions.riskReport();
711
+ return ok(`${rr.escalations} escalation(s), ${rr.guardHolds} guard hold(s), ` +
712
+ `${rr.highRiskModules.length} high-risk module(s).`, rr);
713
+ }
714
+ catch (e) {
715
+ return fail(e);
716
+ }
717
+ });
718
+ server.registerTool('kairo_module_activity', {
719
+ title: 'Module activity & risk',
720
+ description: 'Most-active and highest-risk modules, attributed from changed files via the ' +
721
+ 'module graph. Deterministic.',
722
+ inputSchema: {},
723
+ }, async () => {
724
+ try {
725
+ const mods = await sessions.moduleActivity();
726
+ const top = mods
727
+ .slice(0, 15)
728
+ .map((m) => `- ${m.module}: ${m.touches} touches, risk ${m.riskLevel}`)
729
+ .join('\n');
730
+ return ok(top || 'No module activity recorded.', { modules: mods.slice(0, 30) });
731
+ }
732
+ catch (e) {
733
+ return fail(e);
734
+ }
735
+ });
736
+ // ── Historical introspection (v0.8.1) ────────────────────────────────────
737
+ const TIMELINE_KINDS = [
738
+ 'sessions',
739
+ 'checkpoints',
740
+ 'lease-conflicts',
741
+ 'retrievals',
742
+ 'memory-refresh',
743
+ ];
744
+ const EVENT_SOURCES = ['event', 'telemetry', 'audit'];
745
+ server.registerTool('kairo_query_events', {
746
+ title: 'Query historical events',
747
+ description: 'Deterministic, replay-safe filter over the unified event + telemetry + audit ' +
748
+ 'streams. Namespace-safe (private memory of other workers is filtered).',
749
+ inputSchema: {
750
+ sources: z.array(z.enum(EVENT_SOURCES)).optional(),
751
+ kinds: z.array(z.string()).optional().describe('Exact kind, or prefix*.'),
752
+ sessionIds: z.array(z.string()).optional(),
753
+ workers: z.array(z.string()).optional(),
754
+ since: z.string().optional(),
755
+ until: z.string().optional(),
756
+ limit: z.number().int().min(0).max(1000).optional(),
757
+ },
758
+ }, async (args) => {
759
+ try {
760
+ const out = await sessions.queryEvents(args);
761
+ return ok(`${out.length} event(s):\n` +
762
+ out
763
+ .slice(0, 20)
764
+ .map((e) => `${e.ts} [${e.source}/${e.kind}] ${e.worker ?? '-'} ${e.sessionId}`)
765
+ .join('\n'), { count: out.length, events: out });
766
+ }
767
+ catch (e) {
768
+ return fail(e);
769
+ }
770
+ });
771
+ server.registerTool('kairo_timeline_query', {
772
+ title: 'Engineering timeline',
773
+ description: 'Deterministic timeline view: sessions, checkpoints, lease conflicts, retrievals, ' +
774
+ 'or memory refreshes. Namespace-safe.',
775
+ inputSchema: { kind: z.enum(TIMELINE_KINDS) },
776
+ }, async ({ kind }) => {
777
+ try {
778
+ const out = await sessions.timelineQuery(kind);
779
+ return ok(out.map((e) => `${e.ts} [${e.worker ?? '-'}] ${e.summary}`).join('\n') ||
780
+ `(no ${kind} yet)`, { count: out.length, entries: out });
781
+ }
782
+ catch (e) {
783
+ return fail(e);
784
+ }
785
+ });
786
+ server.registerTool('kairo_checkpoint_lineage', {
787
+ title: 'Checkpoint lineage (DAG path)',
788
+ description: 'Walk parentCheckpointId from a given checkpoint back to its root — the engineering ' +
789
+ 'continuity chain across workers/sessions.',
790
+ inputSchema: { checkpointId: z.string() },
791
+ }, async ({ checkpointId }) => {
792
+ try {
793
+ const out = await sessions.checkpointLineage(checkpointId);
794
+ return ok(out.length === 0
795
+ ? `Checkpoint ${checkpointId} not found.`
796
+ : out
797
+ .map((n, i) => `${i === 0 ? 'root' : `+${i}`} ${n.id} worker=${n.workerId} ` +
798
+ `risk=${n.riskLevel} ${n.task.slice(0, 40)} (${n.reason})`)
799
+ .join('\n'), { count: out.length, lineage: out });
800
+ }
801
+ catch (e) {
802
+ return fail(e);
803
+ }
804
+ });
805
+ server.registerTool('kairo_conflict_history', {
806
+ title: 'Lease-conflict history',
807
+ description: 'Every denied lease with the conflicting holder and (when discoverable) when the ' +
808
+ 'holder acquired it — deterministic projection of the coordination ledger.',
809
+ inputSchema: {},
810
+ }, async () => {
811
+ try {
812
+ const out = await sessions.conflictHistory();
813
+ return ok(out.length === 0
814
+ ? 'No lease conflicts recorded.'
815
+ : out
816
+ .map((c) => `${c.deniedAt} ${c.scopeKind}:${c.scope} ${c.deniedWorker} blocked by ` +
817
+ `${c.holder}${c.holderGrantedAt ? ` (held since ${c.holderGrantedAt})` : ''}`)
818
+ .join('\n'), { count: out.length, conflicts: out });
819
+ }
820
+ catch (e) {
821
+ return fail(e);
822
+ }
823
+ });
824
+ server.registerTool('kairo_retrieval_trace', {
825
+ title: 'Retrieval causality trace',
826
+ description: 'For a `retrieval.performed` telemetry event id, return the preceding session start, ' +
827
+ 'latest memory refresh, and latest checkpoint — the causal context of the retrieval.',
828
+ inputSchema: { eventId: z.string() },
829
+ }, async ({ eventId }) => {
830
+ try {
831
+ const t = await sessions.retrievalTrace(eventId);
832
+ if (!t)
833
+ return ok(`No retrieval event ${eventId}.`, { found: false });
834
+ const line = (label, e) => e
835
+ ? `${label}: ${e.ts} [${e.kind}] ${e.worker ?? '-'} ${e.sessionId}`
836
+ : `${label}: (none)`;
837
+ return ok([
838
+ `Retrieval ${t.retrieval.id} @ ${t.retrieval.ts}`,
839
+ line(' preceding session.started', t.precedingSessionStart),
840
+ line(' latest memory.refreshed ', t.latestMemoryRefresh),
841
+ line(' latest checkpoint.created', t.latestCheckpointBefore),
842
+ ].join('\n'), { found: true, trace: t });
843
+ }
844
+ catch (e) {
845
+ return fail(e);
846
+ }
847
+ });
848
+ // ── Snapshot / import / export (v0.9.2, ADR-0013) ────────────────────────
849
+ server.registerTool('kairo_snapshot_export', {
850
+ title: 'Snapshot export',
851
+ description: 'Export the full .kairo/ state to a single self-describing JSON snapshot file ' +
852
+ '(ADR-0013). Reads pass through schema migration + validation. Local-only; no network. ' +
853
+ 'Default destination: .kairo/snapshots/snapshot-{ts}.json.',
854
+ inputSchema: {
855
+ path: z.string().optional().describe('Override absolute destination path.'),
856
+ projectRoot: z.string().optional(),
857
+ },
858
+ }, async ({ path, projectRoot }) => {
859
+ try {
860
+ const root = projectRootFrom(projectRoot);
861
+ const opts = path === undefined ? {} : { path };
862
+ const r = await exportSnapshot(root, opts);
863
+ const c = r.snapshot.manifest.counts;
864
+ return ok(`Snapshot: ${r.bytes} bytes → ${r.path}. ` +
865
+ `events=${c.events} telemetry=${c.telemetry} sessions=${c.sessions} ` +
866
+ `checkpoints=${c.checkpoints} sha256=${r.contentSha256.slice(0, 12)}…`, {
867
+ path: r.path,
868
+ bytes: r.bytes,
869
+ contentSha256: r.contentSha256,
870
+ manifest: r.snapshot.manifest,
871
+ });
872
+ }
873
+ catch (e) {
874
+ return fail(e);
875
+ }
876
+ });
877
+ // ── Performance, indexing, compaction (v0.9.3, ADR-0014) ───────────────
878
+ server.registerTool('kairo_benchmark', {
879
+ title: 'Run benchmark suite',
880
+ description: 'Run the deterministic benchmark suite over the current project root and write ' +
881
+ '.kairo/reports/PERFORMANCE.md (ADR-0014). Reads-only; no mutation. Wall-clock ' +
882
+ 'timings depend on the host — use for relative comparison and regression detection.',
883
+ inputSchema: {
884
+ iterations: z.number().int().positive().optional(),
885
+ scenarios: z
886
+ .array(z.string())
887
+ .optional()
888
+ .describe('Restrict to these scenario names; default: run all.'),
889
+ projectRoot: z.string().optional(),
890
+ },
891
+ }, async ({ iterations, scenarios, projectRoot }) => {
892
+ try {
893
+ const root = projectRootFrom(projectRoot);
894
+ const opts = {};
895
+ if (iterations !== undefined)
896
+ opts.iterations = iterations;
897
+ if (scenarios !== undefined)
898
+ opts.only = scenarios;
899
+ const r = await runBenchmark(sessions, root, opts);
900
+ const fastest = [...r.report.scenarios]
901
+ .filter((s) => !s.skipped)
902
+ .sort((a, b) => a.stats.median - b.stats.median)[0];
903
+ const slowest = [...r.report.scenarios]
904
+ .filter((s) => !s.skipped)
905
+ .sort((a, b) => b.stats.median - a.stats.median)[0];
906
+ return ok(`Benchmark: ${r.report.scenarios.length} scenarios, sum-of-medians ` +
907
+ `${r.report.totalMs.toFixed(1)}ms. ` +
908
+ (fastest && slowest
909
+ ? `fastest=${fastest.name}@${fastest.stats.median.toFixed(1)}ms ` +
910
+ `slowest=${slowest.name}@${slowest.stats.median.toFixed(1)}ms. `
911
+ : '') +
912
+ `Report: ${r.reportPath}`, { reportPath: r.reportPath, report: r.report });
913
+ }
914
+ catch (e) {
915
+ return fail(e);
916
+ }
917
+ });
918
+ server.registerTool('kairo_perf_report', {
919
+ title: 'Latest performance report',
920
+ description: 'Return the path and a short summary of the latest .kairo/reports/PERFORMANCE.md ' +
921
+ '(ADR-0014). Read-only.',
922
+ inputSchema: {
923
+ projectRoot: z.string().optional(),
924
+ },
925
+ }, async ({ projectRoot }) => {
926
+ try {
927
+ const root = projectRootFrom(projectRoot);
928
+ const paths = kairoPaths(root);
929
+ const reportPath = `${paths.reportsDir}/PERFORMANCE.md`;
930
+ try {
931
+ const md = await readFile(reportPath, 'utf8');
932
+ const head = md.split('\n').slice(0, 6).join('\n');
933
+ return ok(`Performance report at ${reportPath}.\n\n${head}`, {
934
+ reportPath,
935
+ bytes: md.length,
936
+ });
937
+ }
938
+ catch {
939
+ return ok(`No performance report yet. Run kairo_benchmark first.`, {
940
+ reportPath,
941
+ exists: false,
942
+ });
943
+ }
944
+ }
945
+ catch (e) {
946
+ return fail(e);
947
+ }
948
+ });
949
+ server.registerTool('kairo_compact_memory', {
950
+ title: 'Compact stale memory',
951
+ description: 'Archive events from ended sessions older than `olderThanDays` (default 90) into ' +
952
+ '.kairo/archive/events-{ts}.jsonl. Dry-run by default — pass dryRun=false to apply. ' +
953
+ 'Compaction NEVER deletes; the archive manifest at .kairo/archive/MANIFEST.md records ' +
954
+ 'every move. Lineage-protected (events referenced by existing checkpoints are kept).',
955
+ inputSchema: {
956
+ dryRun: z.boolean().optional().describe('Default true. Pass false to apply.'),
957
+ olderThanDays: z.number().int().positive().optional(),
958
+ projectRoot: z.string().optional(),
959
+ },
960
+ }, async ({ dryRun, olderThanDays, projectRoot }) => {
961
+ try {
962
+ const root = projectRootFrom(projectRoot);
963
+ const opts = {};
964
+ if (dryRun !== undefined)
965
+ opts.dryRun = dryRun;
966
+ if (olderThanDays !== undefined)
967
+ opts.olderThanDays = olderThanDays;
968
+ const r = await compact(root, opts);
969
+ const verb = r.applied ? 'Applied' : 'Dry-run';
970
+ return ok(`${verb}: ${r.plan.candidateEvents} events archivable, ` +
971
+ `${r.plan.retainedEvents} retained, ${r.plan.candidateSessionIds.length} sessions. ` +
972
+ `Report: ${r.plan.reportPath}` +
973
+ (r.applied ? `; archive: ${r.plan.archivePath}` : ''), {
974
+ applied: r.applied,
975
+ plan: r.plan,
976
+ });
977
+ }
978
+ catch (e) {
979
+ return fail(e);
980
+ }
981
+ });
982
+ server.registerTool('kairo_index_status', {
983
+ title: 'Vector index status',
984
+ description: 'Compact summary of the current vector index: embedder id, fingerprint, ' +
985
+ 'memory fingerprint, chunk count, vector dimension (ADR-0014). Read-only.',
986
+ inputSchema: {},
987
+ }, async () => {
988
+ try {
989
+ const s = await sessions.memoryStats();
990
+ if (!s)
991
+ return ok('No vector index built yet.', { built: false });
992
+ return ok(`Index: ${s.chunks} chunks, embedder ${s.embedderId}, dim ${s.dim}. ` +
993
+ `repo=${s.fingerprint.slice(0, 12)}… memory=${s.memoryFingerprint.slice(0, 12)}…`, { built: true, ...s });
994
+ }
995
+ catch (e) {
996
+ return fail(e);
997
+ }
998
+ });
999
+ // ── Plugins + stability (v0.9.4, ADR-0015) ────────────────────────────
1000
+ server.registerTool('kairo_plugins_list', {
1001
+ title: 'List local plugins (manifest-only)',
1002
+ description: 'Read .kairo/plugins/*.json (and/or .kairo/plugins.json) and return validated ' +
1003
+ 'plugin manifests. NOTHING IS EXECUTED IN-PROCESS — plugins are external MCP ' +
1004
+ 'servers the host (Claude Desktop, Cursor, ...) loads via its own config. ' +
1005
+ 'Read-only; local-only.',
1006
+ inputSchema: {
1007
+ projectRoot: z.string().optional(),
1008
+ },
1009
+ }, async ({ projectRoot }) => {
1010
+ try {
1011
+ const root = projectRootFrom(projectRoot);
1012
+ const plugins = await loadPlugins(root);
1013
+ const compatible = plugins.filter((p) => p.compatible).length;
1014
+ return ok(`Plugins: ${plugins.length} manifest(s), ${compatible} compatible, ` +
1015
+ `${plugins.length - compatible} incompatible/invalid.`, { plugins });
1016
+ }
1017
+ catch (e) {
1018
+ return fail(e);
1019
+ }
1020
+ });
1021
+ server.registerTool('kairo_stability_of', {
1022
+ title: 'API stability lookup',
1023
+ description: 'Lookup the stability tier of any documented Kairo surface (MCP tool, prompt, ' +
1024
+ 'resource, inspect route, schema, snapshot) per ADR-0015. With no id, returns ' +
1025
+ 'the full registry. Read-only.',
1026
+ inputSchema: {
1027
+ id: z
1028
+ .string()
1029
+ .optional()
1030
+ .describe('Surface identifier (e.g. "kairo_session_start"). Omit for the full registry.'),
1031
+ },
1032
+ }, ({ id }) => {
1033
+ try {
1034
+ if (id === undefined) {
1035
+ return Promise.resolve(ok(`Stability registry: ${STABILITY.length} entries across MCP tools / ` +
1036
+ `prompts / resources / inspect routes / schemas / snapshot.`, { entries: STABILITY }));
1037
+ }
1038
+ const entry = stabilityOf(id);
1039
+ if (!entry) {
1040
+ return Promise.resolve(ok(`No registered entry for "${id}". Treat as internal.`, { entry: null }));
1041
+ }
1042
+ return Promise.resolve(ok(`${entry.id}: ${entry.tier}${entry.note ? ` (${entry.note})` : ''} ` +
1043
+ `[since ${entry.since}, ${entry.surface}]`, { entry }));
1044
+ }
1045
+ catch (e) {
1046
+ return Promise.resolve(fail(e));
1047
+ }
1048
+ });
1049
+ server.registerTool('kairo_snapshot_import', {
1050
+ title: 'Snapshot import',
1051
+ description: 'Import a Kairo snapshot JSON file into the target project root (ADR-0013). ' +
1052
+ 'Refuses to overwrite a non-empty .kairo/ unless force=true. Writes pass through ' +
1053
+ 'redaction and run records through the migration registry.',
1054
+ inputSchema: {
1055
+ path: z.string().describe('Absolute path to the snapshot JSON file.'),
1056
+ projectRoot: z.string().optional(),
1057
+ force: z
1058
+ .boolean()
1059
+ .optional()
1060
+ .describe('Allow writing on top of an existing non-empty .kairo/. Default false.'),
1061
+ redact: z
1062
+ .boolean()
1063
+ .optional()
1064
+ .describe('Run inbound records through redaction. Default true.'),
1065
+ },
1066
+ }, async ({ path, projectRoot, force, redact }) => {
1067
+ try {
1068
+ const root = projectRootFrom(projectRoot);
1069
+ const opts = {};
1070
+ if (force !== undefined)
1071
+ opts.force = force;
1072
+ if (redact !== undefined)
1073
+ opts.redact = redact;
1074
+ const r = await importSnapshot(root, path, opts);
1075
+ const c = r.ingested;
1076
+ return ok(`Imported into ${r.targetProjectRoot}: events=${c.events} telemetry=${c.telemetry} ` +
1077
+ `sessions=${c.sessions} checkpoints=${c.checkpoints} ` +
1078
+ `continuations=${c.continuations} intelligence=${c.intelligence} vector=${c.vectorIndex}.` +
1079
+ (r.warnings.length > 0 ? ` Warnings: ${r.warnings.join('; ')}` : ''), r);
1080
+ }
1081
+ catch (e) {
1082
+ return fail(e);
1083
+ }
1084
+ });
1085
+ }
1086
+ //# sourceMappingURL=registerTools.js.map