@imdigitalashish/zpi 0.1.1

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 (604) hide show
  1. package/CHANGELOG.md +2801 -0
  2. package/README.md +95 -0
  3. package/dist/cli/args.d.ts +47 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +293 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/config-selector.d.ts +14 -0
  8. package/dist/cli/config-selector.d.ts.map +1 -0
  9. package/dist/cli/config-selector.js +31 -0
  10. package/dist/cli/config-selector.js.map +1 -0
  11. package/dist/cli/file-processor.d.ts +15 -0
  12. package/dist/cli/file-processor.d.ts.map +1 -0
  13. package/dist/cli/file-processor.js +79 -0
  14. package/dist/cli/file-processor.js.map +1 -0
  15. package/dist/cli/list-models.d.ts +9 -0
  16. package/dist/cli/list-models.d.ts.map +1 -0
  17. package/dist/cli/list-models.js +92 -0
  18. package/dist/cli/list-models.js.map +1 -0
  19. package/dist/cli/session-picker.d.ts +9 -0
  20. package/dist/cli/session-picker.d.ts.map +1 -0
  21. package/dist/cli/session-picker.js +34 -0
  22. package/dist/cli/session-picker.js.map +1 -0
  23. package/dist/cli.d.ts +3 -0
  24. package/dist/cli.d.ts.map +1 -0
  25. package/dist/cli.js +11 -0
  26. package/dist/cli.js.map +1 -0
  27. package/dist/config.d.ts +68 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +203 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/core/agent-session.d.ts +571 -0
  32. package/dist/core/agent-session.d.ts.map +1 -0
  33. package/dist/core/agent-session.js +2353 -0
  34. package/dist/core/agent-session.js.map +1 -0
  35. package/dist/core/auth-storage.d.ts +129 -0
  36. package/dist/core/auth-storage.d.ts.map +1 -0
  37. package/dist/core/auth-storage.js +394 -0
  38. package/dist/core/auth-storage.js.map +1 -0
  39. package/dist/core/bash-executor.d.ts +47 -0
  40. package/dist/core/bash-executor.d.ts.map +1 -0
  41. package/dist/core/bash-executor.js +212 -0
  42. package/dist/core/bash-executor.js.map +1 -0
  43. package/dist/core/compaction/branch-summarization.d.ts +86 -0
  44. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  45. package/dist/core/compaction/branch-summarization.js +242 -0
  46. package/dist/core/compaction/branch-summarization.js.map +1 -0
  47. package/dist/core/compaction/compaction.d.ts +121 -0
  48. package/dist/core/compaction/compaction.d.ts.map +1 -0
  49. package/dist/core/compaction/compaction.js +607 -0
  50. package/dist/core/compaction/compaction.js.map +1 -0
  51. package/dist/core/compaction/index.d.ts +7 -0
  52. package/dist/core/compaction/index.d.ts.map +1 -0
  53. package/dist/core/compaction/index.js +7 -0
  54. package/dist/core/compaction/index.js.map +1 -0
  55. package/dist/core/compaction/utils.d.ts +35 -0
  56. package/dist/core/compaction/utils.d.ts.map +1 -0
  57. package/dist/core/compaction/utils.js +138 -0
  58. package/dist/core/compaction/utils.js.map +1 -0
  59. package/dist/core/defaults.d.ts +3 -0
  60. package/dist/core/defaults.d.ts.map +1 -0
  61. package/dist/core/defaults.js +2 -0
  62. package/dist/core/defaults.js.map +1 -0
  63. package/dist/core/diagnostics.d.ts +15 -0
  64. package/dist/core/diagnostics.d.ts.map +1 -0
  65. package/dist/core/diagnostics.js +2 -0
  66. package/dist/core/diagnostics.js.map +1 -0
  67. package/dist/core/event-bus.d.ts +9 -0
  68. package/dist/core/event-bus.d.ts.map +1 -0
  69. package/dist/core/event-bus.js +25 -0
  70. package/dist/core/event-bus.js.map +1 -0
  71. package/dist/core/exec.d.ts +29 -0
  72. package/dist/core/exec.d.ts.map +1 -0
  73. package/dist/core/exec.js +71 -0
  74. package/dist/core/exec.js.map +1 -0
  75. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  76. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  77. package/dist/core/export-html/ansi-to-html.js +249 -0
  78. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  79. package/dist/core/export-html/index.d.ts +34 -0
  80. package/dist/core/export-html/index.d.ts.map +1 -0
  81. package/dist/core/export-html/index.js +222 -0
  82. package/dist/core/export-html/index.js.map +1 -0
  83. package/dist/core/export-html/template.css +971 -0
  84. package/dist/core/export-html/template.html +54 -0
  85. package/dist/core/export-html/template.js +1586 -0
  86. package/dist/core/export-html/tool-renderer.d.ts +35 -0
  87. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  88. package/dist/core/export-html/tool-renderer.js +57 -0
  89. package/dist/core/export-html/tool-renderer.js.map +1 -0
  90. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  91. package/dist/core/export-html/vendor/marked.min.js +6 -0
  92. package/dist/core/extensions/index.d.ts +11 -0
  93. package/dist/core/extensions/index.d.ts.map +1 -0
  94. package/dist/core/extensions/index.js +9 -0
  95. package/dist/core/extensions/index.js.map +1 -0
  96. package/dist/core/extensions/loader.d.ts +25 -0
  97. package/dist/core/extensions/loader.d.ts.map +1 -0
  98. package/dist/core/extensions/loader.js +402 -0
  99. package/dist/core/extensions/loader.js.map +1 -0
  100. package/dist/core/extensions/runner.d.ts +146 -0
  101. package/dist/core/extensions/runner.d.ts.map +1 -0
  102. package/dist/core/extensions/runner.js +626 -0
  103. package/dist/core/extensions/runner.js.map +1 -0
  104. package/dist/core/extensions/types.d.ts +984 -0
  105. package/dist/core/extensions/types.d.ts.map +1 -0
  106. package/dist/core/extensions/types.js +35 -0
  107. package/dist/core/extensions/types.js.map +1 -0
  108. package/dist/core/extensions/wrapper.d.ts +27 -0
  109. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  110. package/dist/core/extensions/wrapper.js +102 -0
  111. package/dist/core/extensions/wrapper.js.map +1 -0
  112. package/dist/core/footer-data-provider.d.ts +32 -0
  113. package/dist/core/footer-data-provider.d.ts.map +1 -0
  114. package/dist/core/footer-data-provider.js +134 -0
  115. package/dist/core/footer-data-provider.js.map +1 -0
  116. package/dist/core/index.d.ts +9 -0
  117. package/dist/core/index.d.ts.map +1 -0
  118. package/dist/core/index.js +9 -0
  119. package/dist/core/index.js.map +1 -0
  120. package/dist/core/keybindings.d.ts +55 -0
  121. package/dist/core/keybindings.d.ts.map +1 -0
  122. package/dist/core/keybindings.js +153 -0
  123. package/dist/core/keybindings.js.map +1 -0
  124. package/dist/core/memory.d.ts +64 -0
  125. package/dist/core/memory.d.ts.map +1 -0
  126. package/dist/core/memory.js +247 -0
  127. package/dist/core/memory.js.map +1 -0
  128. package/dist/core/messages.d.ts +77 -0
  129. package/dist/core/messages.d.ts.map +1 -0
  130. package/dist/core/messages.js +149 -0
  131. package/dist/core/messages.js.map +1 -0
  132. package/dist/core/model-registry.d.ts +102 -0
  133. package/dist/core/model-registry.d.ts.map +1 -0
  134. package/dist/core/model-registry.js +515 -0
  135. package/dist/core/model-registry.js.map +1 -0
  136. package/dist/core/model-resolver.d.ts +104 -0
  137. package/dist/core/model-resolver.d.ts.map +1 -0
  138. package/dist/core/model-resolver.js +403 -0
  139. package/dist/core/model-resolver.js.map +1 -0
  140. package/dist/core/package-manager.d.ts +151 -0
  141. package/dist/core/package-manager.d.ts.map +1 -0
  142. package/dist/core/package-manager.js +1426 -0
  143. package/dist/core/package-manager.js.map +1 -0
  144. package/dist/core/prompt-templates.d.ts +50 -0
  145. package/dist/core/prompt-templates.d.ts.map +1 -0
  146. package/dist/core/prompt-templates.js +251 -0
  147. package/dist/core/prompt-templates.js.map +1 -0
  148. package/dist/core/resolve-config-value.d.ts +17 -0
  149. package/dist/core/resolve-config-value.d.ts.map +1 -0
  150. package/dist/core/resolve-config-value.js +59 -0
  151. package/dist/core/resolve-config-value.js.map +1 -0
  152. package/dist/core/resource-loader.d.ts +184 -0
  153. package/dist/core/resource-loader.d.ts.map +1 -0
  154. package/dist/core/resource-loader.js +673 -0
  155. package/dist/core/resource-loader.js.map +1 -0
  156. package/dist/core/sdk.d.ts +90 -0
  157. package/dist/core/sdk.d.ts.map +1 -0
  158. package/dist/core/sdk.js +238 -0
  159. package/dist/core/sdk.js.map +1 -0
  160. package/dist/core/session-manager.d.ts +323 -0
  161. package/dist/core/session-manager.d.ts.map +1 -0
  162. package/dist/core/session-manager.js +1091 -0
  163. package/dist/core/session-manager.js.map +1 -0
  164. package/dist/core/settings-manager.d.ts +230 -0
  165. package/dist/core/settings-manager.d.ts.map +1 -0
  166. package/dist/core/settings-manager.js +656 -0
  167. package/dist/core/settings-manager.js.map +1 -0
  168. package/dist/core/skills.d.ts +58 -0
  169. package/dist/core/skills.d.ts.map +1 -0
  170. package/dist/core/skills.js +364 -0
  171. package/dist/core/skills.js.map +1 -0
  172. package/dist/core/slash-commands.d.ts +15 -0
  173. package/dist/core/slash-commands.d.ts.map +1 -0
  174. package/dist/core/slash-commands.js +23 -0
  175. package/dist/core/slash-commands.js.map +1 -0
  176. package/dist/core/system-prompt.d.ts +26 -0
  177. package/dist/core/system-prompt.d.ts.map +1 -0
  178. package/dist/core/system-prompt.js +150 -0
  179. package/dist/core/system-prompt.js.map +1 -0
  180. package/dist/core/timings.d.ts +7 -0
  181. package/dist/core/timings.d.ts.map +1 -0
  182. package/dist/core/timings.js +25 -0
  183. package/dist/core/timings.js.map +1 -0
  184. package/dist/core/tools/bash.d.ts +55 -0
  185. package/dist/core/tools/bash.d.ts.map +1 -0
  186. package/dist/core/tools/bash.js +242 -0
  187. package/dist/core/tools/bash.js.map +1 -0
  188. package/dist/core/tools/edit-diff.d.ts +63 -0
  189. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  190. package/dist/core/tools/edit-diff.js +243 -0
  191. package/dist/core/tools/edit-diff.js.map +1 -0
  192. package/dist/core/tools/edit.d.ts +39 -0
  193. package/dist/core/tools/edit.d.ts.map +1 -0
  194. package/dist/core/tools/edit.js +146 -0
  195. package/dist/core/tools/edit.js.map +1 -0
  196. package/dist/core/tools/find.d.ts +39 -0
  197. package/dist/core/tools/find.d.ts.map +1 -0
  198. package/dist/core/tools/find.js +206 -0
  199. package/dist/core/tools/find.js.map +1 -0
  200. package/dist/core/tools/grep.d.ts +45 -0
  201. package/dist/core/tools/grep.d.ts.map +1 -0
  202. package/dist/core/tools/grep.js +239 -0
  203. package/dist/core/tools/grep.js.map +1 -0
  204. package/dist/core/tools/index.d.ts +102 -0
  205. package/dist/core/tools/index.d.ts.map +1 -0
  206. package/dist/core/tools/index.js +71 -0
  207. package/dist/core/tools/index.js.map +1 -0
  208. package/dist/core/tools/ls.d.ts +40 -0
  209. package/dist/core/tools/ls.d.ts.map +1 -0
  210. package/dist/core/tools/ls.js +118 -0
  211. package/dist/core/tools/ls.js.map +1 -0
  212. package/dist/core/tools/memory.d.ts +45 -0
  213. package/dist/core/tools/memory.d.ts.map +1 -0
  214. package/dist/core/tools/memory.js +346 -0
  215. package/dist/core/tools/memory.js.map +1 -0
  216. package/dist/core/tools/path-utils.d.ts +8 -0
  217. package/dist/core/tools/path-utils.d.ts.map +1 -0
  218. package/dist/core/tools/path-utils.js +81 -0
  219. package/dist/core/tools/path-utils.js.map +1 -0
  220. package/dist/core/tools/read.d.ts +39 -0
  221. package/dist/core/tools/read.d.ts.map +1 -0
  222. package/dist/core/tools/read.js +166 -0
  223. package/dist/core/tools/read.js.map +1 -0
  224. package/dist/core/tools/truncate.d.ts +70 -0
  225. package/dist/core/tools/truncate.d.ts.map +1 -0
  226. package/dist/core/tools/truncate.js +205 -0
  227. package/dist/core/tools/truncate.js.map +1 -0
  228. package/dist/core/tools/write.d.ts +29 -0
  229. package/dist/core/tools/write.d.ts.map +1 -0
  230. package/dist/core/tools/write.js +78 -0
  231. package/dist/core/tools/write.js.map +1 -0
  232. package/dist/index.d.ts +28 -0
  233. package/dist/index.d.ts.map +1 -0
  234. package/dist/index.js +43 -0
  235. package/dist/index.js.map +1 -0
  236. package/dist/main.d.ts +8 -0
  237. package/dist/main.d.ts.map +1 -0
  238. package/dist/main.js +651 -0
  239. package/dist/main.js.map +1 -0
  240. package/dist/migrations.d.ts +33 -0
  241. package/dist/migrations.d.ts.map +1 -0
  242. package/dist/migrations.js +261 -0
  243. package/dist/migrations.js.map +1 -0
  244. package/dist/modes/index.d.ts +9 -0
  245. package/dist/modes/index.d.ts.map +1 -0
  246. package/dist/modes/index.js +8 -0
  247. package/dist/modes/index.js.map +1 -0
  248. package/dist/modes/interactive/components/armin.d.ts +34 -0
  249. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  250. package/dist/modes/interactive/components/armin.js +333 -0
  251. package/dist/modes/interactive/components/armin.js.map +1 -0
  252. package/dist/modes/interactive/components/assistant-message.d.ts +16 -0
  253. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  254. package/dist/modes/interactive/components/assistant-message.js +96 -0
  255. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  256. package/dist/modes/interactive/components/bash-execution.d.ts +35 -0
  257. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  258. package/dist/modes/interactive/components/bash-execution.js +162 -0
  259. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  260. package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  261. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  262. package/dist/modes/interactive/components/bordered-loader.js +51 -0
  263. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  264. package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  265. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  266. package/dist/modes/interactive/components/branch-summary-message.js +44 -0
  267. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  268. package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  269. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  270. package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
  271. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  272. package/dist/modes/interactive/components/config-selector.d.ts +71 -0
  273. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  274. package/dist/modes/interactive/components/config-selector.js +479 -0
  275. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  276. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  277. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  278. package/dist/modes/interactive/components/countdown-timer.js +33 -0
  279. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  280. package/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  281. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  282. package/dist/modes/interactive/components/custom-editor.js +70 -0
  283. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  284. package/dist/modes/interactive/components/custom-message.d.ts +20 -0
  285. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  286. package/dist/modes/interactive/components/custom-message.js +79 -0
  287. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  288. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  289. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  290. package/dist/modes/interactive/components/daxnuts.js +140 -0
  291. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  292. package/dist/modes/interactive/components/diff.d.ts +12 -0
  293. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  294. package/dist/modes/interactive/components/diff.js +133 -0
  295. package/dist/modes/interactive/components/diff.js.map +1 -0
  296. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  297. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  298. package/dist/modes/interactive/components/dynamic-border.js +21 -0
  299. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  300. package/dist/modes/interactive/components/extension-editor.d.ts +17 -0
  301. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  302. package/dist/modes/interactive/components/extension-editor.js +102 -0
  303. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  304. package/dist/modes/interactive/components/extension-input.d.ts +23 -0
  305. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  306. package/dist/modes/interactive/components/extension-input.js +61 -0
  307. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  308. package/dist/modes/interactive/components/extension-selector.d.ts +24 -0
  309. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  310. package/dist/modes/interactive/components/extension-selector.js +78 -0
  311. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  312. package/dist/modes/interactive/components/footer.d.ts +26 -0
  313. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  314. package/dist/modes/interactive/components/footer.js +213 -0
  315. package/dist/modes/interactive/components/footer.js.map +1 -0
  316. package/dist/modes/interactive/components/index.d.ts +32 -0
  317. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  318. package/dist/modes/interactive/components/index.js +33 -0
  319. package/dist/modes/interactive/components/index.js.map +1 -0
  320. package/dist/modes/interactive/components/keybinding-hints.d.ts +41 -0
  321. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  322. package/dist/modes/interactive/components/keybinding-hints.js +61 -0
  323. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  324. package/dist/modes/interactive/components/login-dialog.d.ts +42 -0
  325. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  326. package/dist/modes/interactive/components/login-dialog.js +145 -0
  327. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  328. package/dist/modes/interactive/components/model-selector.d.ts +47 -0
  329. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  330. package/dist/modes/interactive/components/model-selector.js +271 -0
  331. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  332. package/dist/modes/interactive/components/oauth-selector.d.ts +19 -0
  333. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  334. package/dist/modes/interactive/components/oauth-selector.js +97 -0
  335. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  336. package/dist/modes/interactive/components/scoped-models-selector.d.ts +49 -0
  337. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  338. package/dist/modes/interactive/components/scoped-models-selector.js +275 -0
  339. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  340. package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  341. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  342. package/dist/modes/interactive/components/session-selector-search.js +155 -0
  343. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  344. package/dist/modes/interactive/components/session-selector.d.ts +95 -0
  345. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  346. package/dist/modes/interactive/components/session-selector.js +851 -0
  347. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  348. package/dist/modes/interactive/components/settings-selector.d.ts +58 -0
  349. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  350. package/dist/modes/interactive/components/settings-selector.js +299 -0
  351. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  352. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  353. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  354. package/dist/modes/interactive/components/show-images-selector.js +35 -0
  355. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  356. package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  357. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  358. package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
  359. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  360. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  361. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  362. package/dist/modes/interactive/components/theme-selector.js +46 -0
  363. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  364. package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  365. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  366. package/dist/modes/interactive/components/thinking-selector.js +47 -0
  367. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  368. package/dist/modes/interactive/components/tool-execution.d.ts +70 -0
  369. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  370. package/dist/modes/interactive/components/tool-execution.js +636 -0
  371. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  372. package/dist/modes/interactive/components/tree-selector.d.ts +68 -0
  373. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  374. package/dist/modes/interactive/components/tree-selector.js +934 -0
  375. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  376. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  377. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  378. package/dist/modes/interactive/components/user-message-selector.js +113 -0
  379. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  380. package/dist/modes/interactive/components/user-message.d.ts +8 -0
  381. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  382. package/dist/modes/interactive/components/user-message.js +16 -0
  383. package/dist/modes/interactive/components/user-message.js.map +1 -0
  384. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  385. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  386. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  387. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  388. package/dist/modes/interactive/interactive-mode.d.ts +316 -0
  389. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  390. package/dist/modes/interactive/interactive-mode.js +3848 -0
  391. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  392. package/dist/modes/interactive/theme/dark.json +85 -0
  393. package/dist/modes/interactive/theme/light.json +84 -0
  394. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  395. package/dist/modes/interactive/theme/theme.d.ts +78 -0
  396. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  397. package/dist/modes/interactive/theme/theme.js +944 -0
  398. package/dist/modes/interactive/theme/theme.js.map +1 -0
  399. package/dist/modes/print-mode.d.ts +28 -0
  400. package/dist/modes/print-mode.d.ts.map +1 -0
  401. package/dist/modes/print-mode.js +101 -0
  402. package/dist/modes/print-mode.js.map +1 -0
  403. package/dist/modes/rpc/rpc-client.d.ts +217 -0
  404. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  405. package/dist/modes/rpc/rpc-client.js +405 -0
  406. package/dist/modes/rpc/rpc-client.js.map +1 -0
  407. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  408. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  409. package/dist/modes/rpc/rpc-mode.js +511 -0
  410. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  411. package/dist/modes/rpc/rpc-types.d.ts +409 -0
  412. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  413. package/dist/modes/rpc/rpc-types.js +8 -0
  414. package/dist/modes/rpc/rpc-types.js.map +1 -0
  415. package/dist/utils/changelog.d.ts +21 -0
  416. package/dist/utils/changelog.d.ts.map +1 -0
  417. package/dist/utils/changelog.js +87 -0
  418. package/dist/utils/changelog.js.map +1 -0
  419. package/dist/utils/clipboard-image.d.ts +11 -0
  420. package/dist/utils/clipboard-image.d.ts.map +1 -0
  421. package/dist/utils/clipboard-image.js +162 -0
  422. package/dist/utils/clipboard-image.js.map +1 -0
  423. package/dist/utils/clipboard-native.d.ts +7 -0
  424. package/dist/utils/clipboard-native.d.ts.map +1 -0
  425. package/dist/utils/clipboard-native.js +14 -0
  426. package/dist/utils/clipboard-native.js.map +1 -0
  427. package/dist/utils/clipboard.d.ts +2 -0
  428. package/dist/utils/clipboard.d.ts.map +1 -0
  429. package/dist/utils/clipboard.js +67 -0
  430. package/dist/utils/clipboard.js.map +1 -0
  431. package/dist/utils/frontmatter.d.ts +8 -0
  432. package/dist/utils/frontmatter.d.ts.map +1 -0
  433. package/dist/utils/frontmatter.js +26 -0
  434. package/dist/utils/frontmatter.js.map +1 -0
  435. package/dist/utils/git.d.ts +26 -0
  436. package/dist/utils/git.d.ts.map +1 -0
  437. package/dist/utils/git.js +163 -0
  438. package/dist/utils/git.js.map +1 -0
  439. package/dist/utils/image-convert.d.ts +9 -0
  440. package/dist/utils/image-convert.d.ts.map +1 -0
  441. package/dist/utils/image-convert.js +35 -0
  442. package/dist/utils/image-convert.js.map +1 -0
  443. package/dist/utils/image-resize.d.ts +36 -0
  444. package/dist/utils/image-resize.d.ts.map +1 -0
  445. package/dist/utils/image-resize.js +181 -0
  446. package/dist/utils/image-resize.js.map +1 -0
  447. package/dist/utils/mime.d.ts +2 -0
  448. package/dist/utils/mime.d.ts.map +1 -0
  449. package/dist/utils/mime.js +26 -0
  450. package/dist/utils/mime.js.map +1 -0
  451. package/dist/utils/photon.d.ts +21 -0
  452. package/dist/utils/photon.d.ts.map +1 -0
  453. package/dist/utils/photon.js +121 -0
  454. package/dist/utils/photon.js.map +1 -0
  455. package/dist/utils/shell.d.ts +26 -0
  456. package/dist/utils/shell.d.ts.map +1 -0
  457. package/dist/utils/shell.js +186 -0
  458. package/dist/utils/shell.js.map +1 -0
  459. package/dist/utils/sleep.d.ts +5 -0
  460. package/dist/utils/sleep.d.ts.map +1 -0
  461. package/dist/utils/sleep.js +17 -0
  462. package/dist/utils/sleep.js.map +1 -0
  463. package/dist/utils/tools-manager.d.ts +3 -0
  464. package/dist/utils/tools-manager.d.ts.map +1 -0
  465. package/dist/utils/tools-manager.js +207 -0
  466. package/dist/utils/tools-manager.js.map +1 -0
  467. package/docs/compaction.md +390 -0
  468. package/docs/custom-provider.md +548 -0
  469. package/docs/development.md +69 -0
  470. package/docs/extensions.md +1935 -0
  471. package/docs/images/doom-extension.png +0 -0
  472. package/docs/images/exy.png +0 -0
  473. package/docs/images/interactive-mode.png +0 -0
  474. package/docs/images/tree-view.png +0 -0
  475. package/docs/json.md +79 -0
  476. package/docs/keybindings.md +174 -0
  477. package/docs/models.md +293 -0
  478. package/docs/packages.md +209 -0
  479. package/docs/prompt-templates.md +67 -0
  480. package/docs/providers.md +186 -0
  481. package/docs/rpc.md +1317 -0
  482. package/docs/sdk.md +968 -0
  483. package/docs/session.md +412 -0
  484. package/docs/settings.md +223 -0
  485. package/docs/shell-aliases.md +13 -0
  486. package/docs/skills.md +231 -0
  487. package/docs/terminal-setup.md +70 -0
  488. package/docs/termux.md +127 -0
  489. package/docs/themes.md +295 -0
  490. package/docs/tree.md +219 -0
  491. package/docs/tui.md +887 -0
  492. package/docs/windows.md +17 -0
  493. package/examples/README.md +25 -0
  494. package/examples/extensions/README.md +203 -0
  495. package/examples/extensions/antigravity-image-gen.ts +413 -0
  496. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  497. package/examples/extensions/bash-spawn-hook.ts +30 -0
  498. package/examples/extensions/bookmark.ts +50 -0
  499. package/examples/extensions/claude-rules.ts +86 -0
  500. package/examples/extensions/commands.ts +72 -0
  501. package/examples/extensions/confirm-destructive.ts +59 -0
  502. package/examples/extensions/custom-compaction.ts +114 -0
  503. package/examples/extensions/custom-footer.ts +64 -0
  504. package/examples/extensions/custom-header.ts +73 -0
  505. package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  506. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  507. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  508. package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
  509. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  510. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  511. package/examples/extensions/custom-provider-qwen-cli/index.ts +345 -0
  512. package/examples/extensions/custom-provider-qwen-cli/package.json +16 -0
  513. package/examples/extensions/dirty-repo-guard.ts +56 -0
  514. package/examples/extensions/doom-overlay/README.md +46 -0
  515. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  516. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  517. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  518. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  519. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  520. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  521. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  522. package/examples/extensions/doom-overlay/index.ts +74 -0
  523. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  524. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  525. package/examples/extensions/dynamic-resources/dynamic.json +79 -0
  526. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  527. package/examples/extensions/dynamic-resources/index.ts +15 -0
  528. package/examples/extensions/event-bus.ts +43 -0
  529. package/examples/extensions/file-trigger.ts +41 -0
  530. package/examples/extensions/git-checkpoint.ts +53 -0
  531. package/examples/extensions/handoff.ts +150 -0
  532. package/examples/extensions/hello.ts +25 -0
  533. package/examples/extensions/inline-bash.ts +94 -0
  534. package/examples/extensions/input-transform.ts +43 -0
  535. package/examples/extensions/interactive-shell.ts +196 -0
  536. package/examples/extensions/mac-system-theme.ts +47 -0
  537. package/examples/extensions/message-renderer.ts +59 -0
  538. package/examples/extensions/minimal-mode.ts +426 -0
  539. package/examples/extensions/modal-editor.ts +85 -0
  540. package/examples/extensions/model-status.ts +31 -0
  541. package/examples/extensions/notify.ts +55 -0
  542. package/examples/extensions/overlay-qa-tests.ts +881 -0
  543. package/examples/extensions/overlay-test.ts +150 -0
  544. package/examples/extensions/permission-gate.ts +34 -0
  545. package/examples/extensions/pirate.ts +47 -0
  546. package/examples/extensions/plan-mode/README.md +65 -0
  547. package/examples/extensions/plan-mode/index.ts +340 -0
  548. package/examples/extensions/plan-mode/utils.ts +168 -0
  549. package/examples/extensions/preset.ts +398 -0
  550. package/examples/extensions/protected-paths.ts +30 -0
  551. package/examples/extensions/qna.ts +119 -0
  552. package/examples/extensions/question.ts +264 -0
  553. package/examples/extensions/questionnaire.ts +427 -0
  554. package/examples/extensions/rainbow-editor.ts +88 -0
  555. package/examples/extensions/reload-runtime.ts +37 -0
  556. package/examples/extensions/rpc-demo.ts +124 -0
  557. package/examples/extensions/sandbox/index.ts +318 -0
  558. package/examples/extensions/sandbox/package-lock.json +92 -0
  559. package/examples/extensions/sandbox/package.json +19 -0
  560. package/examples/extensions/send-user-message.ts +97 -0
  561. package/examples/extensions/session-name.ts +27 -0
  562. package/examples/extensions/shutdown-command.ts +63 -0
  563. package/examples/extensions/snake.ts +343 -0
  564. package/examples/extensions/space-invaders.ts +560 -0
  565. package/examples/extensions/ssh.ts +220 -0
  566. package/examples/extensions/status-line.ts +40 -0
  567. package/examples/extensions/subagent/README.md +172 -0
  568. package/examples/extensions/subagent/agents/planner.md +37 -0
  569. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  570. package/examples/extensions/subagent/agents/scout.md +50 -0
  571. package/examples/extensions/subagent/agents/worker.md +24 -0
  572. package/examples/extensions/subagent/agents.ts +127 -0
  573. package/examples/extensions/subagent/index.ts +964 -0
  574. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  575. package/examples/extensions/subagent/prompts/implement.md +10 -0
  576. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  577. package/examples/extensions/summarize.ts +195 -0
  578. package/examples/extensions/system-prompt-header.ts +17 -0
  579. package/examples/extensions/timed-confirm.ts +70 -0
  580. package/examples/extensions/titlebar-spinner.ts +58 -0
  581. package/examples/extensions/todo.ts +299 -0
  582. package/examples/extensions/tool-override.ts +143 -0
  583. package/examples/extensions/tools.ts +146 -0
  584. package/examples/extensions/trigger-compact.ts +40 -0
  585. package/examples/extensions/truncated-tool.ts +192 -0
  586. package/examples/extensions/widget-placement.ts +17 -0
  587. package/examples/extensions/with-deps/index.ts +36 -0
  588. package/examples/extensions/with-deps/package-lock.json +31 -0
  589. package/examples/extensions/with-deps/package.json +22 -0
  590. package/examples/rpc-extension-ui.ts +632 -0
  591. package/examples/sdk/01-minimal.ts +22 -0
  592. package/examples/sdk/02-custom-model.ts +49 -0
  593. package/examples/sdk/03-custom-prompt.ts +55 -0
  594. package/examples/sdk/04-skills.ts +46 -0
  595. package/examples/sdk/05-tools.ts +56 -0
  596. package/examples/sdk/06-extensions.ts +88 -0
  597. package/examples/sdk/07-context-files.ts +40 -0
  598. package/examples/sdk/08-prompt-templates.ts +47 -0
  599. package/examples/sdk/09-api-keys-and-oauth.ts +48 -0
  600. package/examples/sdk/10-settings.ts +51 -0
  601. package/examples/sdk/11-sessions.ts +48 -0
  602. package/examples/sdk/12-full-control.ts +82 -0
  603. package/examples/sdk/README.md +144 -0
  604. package/package.json +96 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../../src/core/tools/ls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAItD,OAAO,EAAiC,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAEnG,QAAA,MAAM,QAAQ;;;EAGZ,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAC;AAIlD,MAAM,WAAW,aAAa;IAC7B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B,2BAA2B;IAC3B,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC7D,qDAAqD;IACrD,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,OAAO,CAAA;KAAE,CAAC,GAAG;QAAE,WAAW,EAAE,MAAM,OAAO,CAAA;KAAE,CAAC;IACzG,6BAA6B;IAC7B,OAAO,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC;CAChE;AAQD,MAAM,WAAW,aAAa;IAC7B,yEAAyE;IACzE,UAAU,CAAC,EAAE,YAAY,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC,OAAO,QAAQ,CAAC,CAyH7F;AAED,wEAAwE;AACxE,eAAO,MAAM,MAAM;;;QAA8B,CAAC","sourcesContent":["import type { AgentTool } from \"@mariozechner/pi-agent-core\";\r\nimport { type Static, Type } from \"@sinclair/typebox\";\r\nimport { existsSync, readdirSync, statSync } from \"fs\";\r\nimport nodePath from \"path\";\r\nimport { resolveToCwd } from \"./path-utils.js\";\r\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.js\";\r\n\r\nconst lsSchema = Type.Object({\r\n\tpath: Type.Optional(Type.String({ description: \"Directory to list (default: current directory)\" })),\r\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of entries to return (default: 500)\" })),\r\n});\r\n\r\nexport type LsToolInput = Static<typeof lsSchema>;\r\n\r\nconst DEFAULT_LIMIT = 500;\r\n\r\nexport interface LsToolDetails {\r\n\ttruncation?: TruncationResult;\r\n\tentryLimitReached?: number;\r\n}\r\n\r\n/**\r\n * Pluggable operations for the ls tool.\r\n * Override these to delegate directory listing to remote systems (e.g., SSH).\r\n */\r\nexport interface LsOperations {\r\n\t/** Check if path exists */\r\n\texists: (absolutePath: string) => Promise<boolean> | boolean;\r\n\t/** Get file/directory stats. Throws if not found. */\r\n\tstat: (absolutePath: string) => Promise<{ isDirectory: () => boolean }> | { isDirectory: () => boolean };\r\n\t/** Read directory entries */\r\n\treaddir: (absolutePath: string) => Promise<string[]> | string[];\r\n}\r\n\r\nconst defaultLsOperations: LsOperations = {\r\n\texists: existsSync,\r\n\tstat: statSync,\r\n\treaddir: readdirSync,\r\n};\r\n\r\nexport interface LsToolOptions {\r\n\t/** Custom operations for directory listing. Default: local filesystem */\r\n\toperations?: LsOperations;\r\n}\r\n\r\nexport function createLsTool(cwd: string, options?: LsToolOptions): AgentTool<typeof lsSchema> {\r\n\tconst ops = options?.operations ?? defaultLsOperations;\r\n\r\n\treturn {\r\n\t\tname: \"ls\",\r\n\t\tlabel: \"ls\",\r\n\t\tdescription: `List directory contents. Returns entries sorted alphabetically, with '/' suffix for directories. Includes dotfiles. Output is truncated to ${DEFAULT_LIMIT} entries or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\r\n\t\tparameters: lsSchema,\r\n\t\texecute: async (\r\n\t\t\t_toolCallId: string,\r\n\t\t\t{ path, limit }: { path?: string; limit?: number },\r\n\t\t\tsignal?: AbortSignal,\r\n\t\t) => {\r\n\t\t\treturn new Promise((resolve, reject) => {\r\n\t\t\t\tif (signal?.aborted) {\r\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst onAbort = () => reject(new Error(\"Operation aborted\"));\r\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\r\n\r\n\t\t\t\t(async () => {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconst dirPath = resolveToCwd(path || \".\", cwd);\r\n\t\t\t\t\t\tconst effectiveLimit = limit ?? DEFAULT_LIMIT;\r\n\r\n\t\t\t\t\t\t// Check if path exists\r\n\t\t\t\t\t\tif (!(await ops.exists(dirPath))) {\r\n\t\t\t\t\t\t\treject(new Error(`Path not found: ${dirPath}`));\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Check if path is a directory\r\n\t\t\t\t\t\tconst stat = await ops.stat(dirPath);\r\n\t\t\t\t\t\tif (!stat.isDirectory()) {\r\n\t\t\t\t\t\t\treject(new Error(`Not a directory: ${dirPath}`));\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Read directory entries\r\n\t\t\t\t\t\tlet entries: string[];\r\n\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\tentries = await ops.readdir(dirPath);\r\n\t\t\t\t\t\t} catch (e: any) {\r\n\t\t\t\t\t\t\treject(new Error(`Cannot read directory: ${e.message}`));\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Sort alphabetically (case-insensitive)\r\n\t\t\t\t\t\tentries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));\r\n\r\n\t\t\t\t\t\t// Format entries with directory indicators\r\n\t\t\t\t\t\tconst results: string[] = [];\r\n\t\t\t\t\t\tlet entryLimitReached = false;\r\n\r\n\t\t\t\t\t\tfor (const entry of entries) {\r\n\t\t\t\t\t\t\tif (results.length >= effectiveLimit) {\r\n\t\t\t\t\t\t\t\tentryLimitReached = true;\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tconst fullPath = nodePath.join(dirPath, entry);\r\n\t\t\t\t\t\t\tlet suffix = \"\";\r\n\r\n\t\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\t\tconst entryStat = await ops.stat(fullPath);\r\n\t\t\t\t\t\t\t\tif (entryStat.isDirectory()) {\r\n\t\t\t\t\t\t\t\t\tsuffix = \"/\";\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t} catch {\r\n\t\t\t\t\t\t\t\t// Skip entries we can't stat\r\n\t\t\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tresults.push(entry + suffix);\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\r\n\r\n\t\t\t\t\t\tif (results.length === 0) {\r\n\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"(empty directory)\" }], details: undefined });\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Apply byte truncation (no line limit since we already have entry limit)\r\n\t\t\t\t\t\tconst rawOutput = results.join(\"\\n\");\r\n\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\r\n\r\n\t\t\t\t\t\tlet output = truncation.content;\r\n\t\t\t\t\t\tconst details: LsToolDetails = {};\r\n\r\n\t\t\t\t\t\t// Build notices\r\n\t\t\t\t\t\tconst notices: string[] = [];\r\n\r\n\t\t\t\t\t\tif (entryLimitReached) {\r\n\t\t\t\t\t\t\tnotices.push(`${effectiveLimit} entries limit reached. Use limit=${effectiveLimit * 2} for more`);\r\n\t\t\t\t\t\t\tdetails.entryLimitReached = effectiveLimit;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif (truncation.truncated) {\r\n\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\r\n\t\t\t\t\t\t\tdetails.truncation = truncation;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif (notices.length > 0) {\r\n\t\t\t\t\t\t\toutput += `\\n\\n[${notices.join(\". \")}]`;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tresolve({\r\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: output }],\r\n\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t} catch (e: any) {\r\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\r\n\t\t\t\t\t\treject(e);\r\n\t\t\t\t\t}\r\n\t\t\t\t})();\r\n\t\t\t});\r\n\t\t},\r\n\t};\r\n}\r\n\r\n/** Default ls tool using process.cwd() - for backwards compatibility */\r\nexport const lsTool = createLsTool(process.cwd());\r\n"]}
@@ -0,0 +1,118 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import { existsSync, readdirSync, statSync } from "fs";
3
+ import nodePath from "path";
4
+ import { resolveToCwd } from "./path-utils.js";
5
+ import { DEFAULT_MAX_BYTES, formatSize, truncateHead } from "./truncate.js";
6
+ const lsSchema = Type.Object({
7
+ path: Type.Optional(Type.String({ description: "Directory to list (default: current directory)" })),
8
+ limit: Type.Optional(Type.Number({ description: "Maximum number of entries to return (default: 500)" })),
9
+ });
10
+ const DEFAULT_LIMIT = 500;
11
+ const defaultLsOperations = {
12
+ exists: existsSync,
13
+ stat: statSync,
14
+ readdir: readdirSync,
15
+ };
16
+ export function createLsTool(cwd, options) {
17
+ const ops = options?.operations ?? defaultLsOperations;
18
+ return {
19
+ name: "ls",
20
+ label: "ls",
21
+ description: `List directory contents. Returns entries sorted alphabetically, with '/' suffix for directories. Includes dotfiles. Output is truncated to ${DEFAULT_LIMIT} entries or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,
22
+ parameters: lsSchema,
23
+ execute: async (_toolCallId, { path, limit }, signal) => {
24
+ return new Promise((resolve, reject) => {
25
+ if (signal?.aborted) {
26
+ reject(new Error("Operation aborted"));
27
+ return;
28
+ }
29
+ const onAbort = () => reject(new Error("Operation aborted"));
30
+ signal?.addEventListener("abort", onAbort, { once: true });
31
+ (async () => {
32
+ try {
33
+ const dirPath = resolveToCwd(path || ".", cwd);
34
+ const effectiveLimit = limit ?? DEFAULT_LIMIT;
35
+ // Check if path exists
36
+ if (!(await ops.exists(dirPath))) {
37
+ reject(new Error(`Path not found: ${dirPath}`));
38
+ return;
39
+ }
40
+ // Check if path is a directory
41
+ const stat = await ops.stat(dirPath);
42
+ if (!stat.isDirectory()) {
43
+ reject(new Error(`Not a directory: ${dirPath}`));
44
+ return;
45
+ }
46
+ // Read directory entries
47
+ let entries;
48
+ try {
49
+ entries = await ops.readdir(dirPath);
50
+ }
51
+ catch (e) {
52
+ reject(new Error(`Cannot read directory: ${e.message}`));
53
+ return;
54
+ }
55
+ // Sort alphabetically (case-insensitive)
56
+ entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
57
+ // Format entries with directory indicators
58
+ const results = [];
59
+ let entryLimitReached = false;
60
+ for (const entry of entries) {
61
+ if (results.length >= effectiveLimit) {
62
+ entryLimitReached = true;
63
+ break;
64
+ }
65
+ const fullPath = nodePath.join(dirPath, entry);
66
+ let suffix = "";
67
+ try {
68
+ const entryStat = await ops.stat(fullPath);
69
+ if (entryStat.isDirectory()) {
70
+ suffix = "/";
71
+ }
72
+ }
73
+ catch {
74
+ // Skip entries we can't stat
75
+ continue;
76
+ }
77
+ results.push(entry + suffix);
78
+ }
79
+ signal?.removeEventListener("abort", onAbort);
80
+ if (results.length === 0) {
81
+ resolve({ content: [{ type: "text", text: "(empty directory)" }], details: undefined });
82
+ return;
83
+ }
84
+ // Apply byte truncation (no line limit since we already have entry limit)
85
+ const rawOutput = results.join("\n");
86
+ const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
87
+ let output = truncation.content;
88
+ const details = {};
89
+ // Build notices
90
+ const notices = [];
91
+ if (entryLimitReached) {
92
+ notices.push(`${effectiveLimit} entries limit reached. Use limit=${effectiveLimit * 2} for more`);
93
+ details.entryLimitReached = effectiveLimit;
94
+ }
95
+ if (truncation.truncated) {
96
+ notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
97
+ details.truncation = truncation;
98
+ }
99
+ if (notices.length > 0) {
100
+ output += `\n\n[${notices.join(". ")}]`;
101
+ }
102
+ resolve({
103
+ content: [{ type: "text", text: output }],
104
+ details: Object.keys(details).length > 0 ? details : undefined,
105
+ });
106
+ }
107
+ catch (e) {
108
+ signal?.removeEventListener("abort", onAbort);
109
+ reject(e);
110
+ }
111
+ })();
112
+ });
113
+ },
114
+ };
115
+ }
116
+ /** Default ls tool using process.cwd() - for backwards compatibility */
117
+ export const lsTool = createLsTool(process.cwd());
118
+ //# sourceMappingURL=ls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ls.js","sourceRoot":"","sources":["../../../src/core/tools/ls.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@mariozechner/pi-agent-core\";\r\nimport { type Static, Type } from \"@sinclair/typebox\";\r\nimport { existsSync, readdirSync, statSync } from \"fs\";\r\nimport nodePath from \"path\";\r\nimport { resolveToCwd } from \"./path-utils.js\";\r\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.js\";\r\n\r\nconst lsSchema = Type.Object({\r\n\tpath: Type.Optional(Type.String({ description: \"Directory to list (default: current directory)\" })),\r\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of entries to return (default: 500)\" })),\r\n});\r\n\r\nexport type LsToolInput = Static<typeof lsSchema>;\r\n\r\nconst DEFAULT_LIMIT = 500;\r\n\r\nexport interface LsToolDetails {\r\n\ttruncation?: TruncationResult;\r\n\tentryLimitReached?: number;\r\n}\r\n\r\n/**\r\n * Pluggable operations for the ls tool.\r\n * Override these to delegate directory listing to remote systems (e.g., SSH).\r\n */\r\nexport interface LsOperations {\r\n\t/** Check if path exists */\r\n\texists: (absolutePath: string) => Promise<boolean> | boolean;\r\n\t/** Get file/directory stats. Throws if not found. */\r\n\tstat: (absolutePath: string) => Promise<{ isDirectory: () => boolean }> | { isDirectory: () => boolean };\r\n\t/** Read directory entries */\r\n\treaddir: (absolutePath: string) => Promise<string[]> | string[];\r\n}\r\n\r\nconst defaultLsOperations: LsOperations = {\r\n\texists: existsSync,\r\n\tstat: statSync,\r\n\treaddir: readdirSync,\r\n};\r\n\r\nexport interface LsToolOptions {\r\n\t/** Custom operations for directory listing. Default: local filesystem */\r\n\toperations?: LsOperations;\r\n}\r\n\r\nexport function createLsTool(cwd: string, options?: LsToolOptions): AgentTool<typeof lsSchema> {\r\n\tconst ops = options?.operations ?? defaultLsOperations;\r\n\r\n\treturn {\r\n\t\tname: \"ls\",\r\n\t\tlabel: \"ls\",\r\n\t\tdescription: `List directory contents. Returns entries sorted alphabetically, with '/' suffix for directories. Includes dotfiles. Output is truncated to ${DEFAULT_LIMIT} entries or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\r\n\t\tparameters: lsSchema,\r\n\t\texecute: async (\r\n\t\t\t_toolCallId: string,\r\n\t\t\t{ path, limit }: { path?: string; limit?: number },\r\n\t\t\tsignal?: AbortSignal,\r\n\t\t) => {\r\n\t\t\treturn new Promise((resolve, reject) => {\r\n\t\t\t\tif (signal?.aborted) {\r\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst onAbort = () => reject(new Error(\"Operation aborted\"));\r\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\r\n\r\n\t\t\t\t(async () => {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconst dirPath = resolveToCwd(path || \".\", cwd);\r\n\t\t\t\t\t\tconst effectiveLimit = limit ?? DEFAULT_LIMIT;\r\n\r\n\t\t\t\t\t\t// Check if path exists\r\n\t\t\t\t\t\tif (!(await ops.exists(dirPath))) {\r\n\t\t\t\t\t\t\treject(new Error(`Path not found: ${dirPath}`));\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Check if path is a directory\r\n\t\t\t\t\t\tconst stat = await ops.stat(dirPath);\r\n\t\t\t\t\t\tif (!stat.isDirectory()) {\r\n\t\t\t\t\t\t\treject(new Error(`Not a directory: ${dirPath}`));\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Read directory entries\r\n\t\t\t\t\t\tlet entries: string[];\r\n\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\tentries = await ops.readdir(dirPath);\r\n\t\t\t\t\t\t} catch (e: any) {\r\n\t\t\t\t\t\t\treject(new Error(`Cannot read directory: ${e.message}`));\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Sort alphabetically (case-insensitive)\r\n\t\t\t\t\t\tentries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));\r\n\r\n\t\t\t\t\t\t// Format entries with directory indicators\r\n\t\t\t\t\t\tconst results: string[] = [];\r\n\t\t\t\t\t\tlet entryLimitReached = false;\r\n\r\n\t\t\t\t\t\tfor (const entry of entries) {\r\n\t\t\t\t\t\t\tif (results.length >= effectiveLimit) {\r\n\t\t\t\t\t\t\t\tentryLimitReached = true;\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tconst fullPath = nodePath.join(dirPath, entry);\r\n\t\t\t\t\t\t\tlet suffix = \"\";\r\n\r\n\t\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\t\tconst entryStat = await ops.stat(fullPath);\r\n\t\t\t\t\t\t\t\tif (entryStat.isDirectory()) {\r\n\t\t\t\t\t\t\t\t\tsuffix = \"/\";\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t} catch {\r\n\t\t\t\t\t\t\t\t// Skip entries we can't stat\r\n\t\t\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tresults.push(entry + suffix);\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\r\n\r\n\t\t\t\t\t\tif (results.length === 0) {\r\n\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"(empty directory)\" }], details: undefined });\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Apply byte truncation (no line limit since we already have entry limit)\r\n\t\t\t\t\t\tconst rawOutput = results.join(\"\\n\");\r\n\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\r\n\r\n\t\t\t\t\t\tlet output = truncation.content;\r\n\t\t\t\t\t\tconst details: LsToolDetails = {};\r\n\r\n\t\t\t\t\t\t// Build notices\r\n\t\t\t\t\t\tconst notices: string[] = [];\r\n\r\n\t\t\t\t\t\tif (entryLimitReached) {\r\n\t\t\t\t\t\t\tnotices.push(`${effectiveLimit} entries limit reached. Use limit=${effectiveLimit * 2} for more`);\r\n\t\t\t\t\t\t\tdetails.entryLimitReached = effectiveLimit;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif (truncation.truncated) {\r\n\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\r\n\t\t\t\t\t\t\tdetails.truncation = truncation;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif (notices.length > 0) {\r\n\t\t\t\t\t\t\toutput += `\\n\\n[${notices.join(\". \")}]`;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tresolve({\r\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: output }],\r\n\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t} catch (e: any) {\r\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\r\n\t\t\t\t\t\treject(e);\r\n\t\t\t\t\t}\r\n\t\t\t\t})();\r\n\t\t\t});\r\n\t\t},\r\n\t};\r\n}\r\n\r\n/** Default ls tool using process.cwd() - for backwards compatibility */\r\nexport const lsTool = createLsTool(process.cwd());\r\n"]}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Built-in memory tools: memory_write, memory_read, memory_update, memory_delete
3
+ */
4
+ import type { AgentTool } from "@mariozechner/pi-agent-core";
5
+ export interface MemoryToolContext {
6
+ cwd: string;
7
+ sessionId: string;
8
+ }
9
+ export declare function setMemoryToolContext(ctx: MemoryToolContext): void;
10
+ declare const memoryWriteSchema: import("@sinclair/typebox").TObject<{
11
+ type: import("@sinclair/typebox").TUnsafe<"episodic" | "procedural" | "semantic">;
12
+ name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
13
+ trigger: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
14
+ steps: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
15
+ summary: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
16
+ details: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
17
+ category: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnsafe<"architecture" | "convention" | "fact" | "preference">>;
18
+ text: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
19
+ tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
20
+ reflection_mistakes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
21
+ reflection_lessons: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
22
+ }>;
23
+ declare const memoryReadSchema: import("@sinclair/typebox").TObject<{
24
+ type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnsafe<"all" | "episodic" | "procedural" | "semantic">>;
25
+ id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
26
+ query: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
27
+ }>;
28
+ declare const memoryUpdateSchema: import("@sinclair/typebox").TObject<{
29
+ id: import("@sinclair/typebox").TString;
30
+ text: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
31
+ steps: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
32
+ trigger: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
33
+ tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
34
+ }>;
35
+ declare const memoryDeleteSchema: import("@sinclair/typebox").TObject<{
36
+ id: import("@sinclair/typebox").TString;
37
+ }>;
38
+ export declare const memoryWriteTool: AgentTool<typeof memoryWriteSchema>;
39
+ export declare const memoryReadTool: AgentTool<typeof memoryReadSchema>;
40
+ export declare const memoryUpdateTool: AgentTool<typeof memoryUpdateSchema>;
41
+ export declare const memoryDeleteTool: AgentTool<typeof memoryDeleteSchema>;
42
+ /** All memory tools */
43
+ export declare const memoryTools: AgentTool<any>[];
44
+ export {};
45
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/core/tools/memory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAiB7D,MAAM,WAAW,iBAAiB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CAClB;AAID,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAEjE;AAMD,QAAA,MAAM,iBAAiB;;;;;;;;;;;;EAsBrB,CAAC;AAIH,QAAA,MAAM,gBAAgB;;;;EAIpB,CAAC;AAIH,QAAA,MAAM,kBAAkB;;;;;;EAMtB,CAAC;AAIH,QAAA,MAAM,kBAAkB;;EAEtB,CAAC;AAQH,eAAO,MAAM,eAAe,EAAE,SAAS,CAAC,OAAO,iBAAiB,CAuH/D,CAAC;AAMF,eAAO,MAAM,cAAc,EAAE,SAAS,CAAC,OAAO,gBAAgB,CAyG7D,CAAC;AAMF,eAAO,MAAM,gBAAgB,EAAE,SAAS,CAAC,OAAO,kBAAkB,CAqDjE,CAAC;AAMF,eAAO,MAAM,gBAAgB,EAAE,SAAS,CAAC,OAAO,kBAAkB,CA6BjE,CAAC;AAEF,uBAAuB;AACvB,eAAO,MAAM,WAAW,EAAE,SAAS,CAAC,GAAG,CAAC,EAA0E,CAAC","sourcesContent":["/**\r\n * Built-in memory tools: memory_write, memory_read, memory_update, memory_delete\r\n */\r\n\r\nimport type { AgentTool } from \"@mariozechner/pi-agent-core\";\r\nimport { StringEnum } from \"@mariozechner/pi-ai\";\r\nimport { type Static, Type } from \"@sinclair/typebox\";\r\nimport {\r\n\ttype EpisodicMemory,\r\n\tformatEpisodicForDisplay,\r\n\tformatProceduralForDisplay,\r\n\tformatSemanticForDisplay,\r\n\tgenerateId,\r\n\tloadStore,\r\n\tnowISO,\r\n\ttype ProceduralMemory,\r\n\ttype SemanticMemory,\r\n\tsaveStore,\r\n\tsearchMemories,\r\n} from \"../memory.js\";\r\n\r\nexport interface MemoryToolContext {\r\n\tcwd: string;\r\n\tsessionId: string;\r\n}\r\n\r\nlet memoryContext: MemoryToolContext = { cwd: process.cwd(), sessionId: `session_${Date.now()}` };\r\n\r\nexport function setMemoryToolContext(ctx: MemoryToolContext): void {\r\n\tmemoryContext = ctx;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Schemas\r\n// ---------------------------------------------------------------------------\r\n\r\nconst memoryWriteSchema = Type.Object({\r\n\ttype: StringEnum([\"procedural\", \"episodic\", \"semantic\"] as const),\r\n\tname: Type.Optional(Type.String({ description: \"Name for procedural memories (e.g., 'deploy-service')\" })),\r\n\ttrigger: Type.Optional(\r\n\t\tType.String({ description: \"When to invoke this procedure (e.g., 'user asks to deploy a service')\" }),\r\n\t),\r\n\tsteps: Type.Optional(Type.Array(Type.String(), { description: \"Steps for procedural memory\" })),\r\n\tsummary: Type.Optional(Type.String({ description: \"Summary for episodic memory\" })),\r\n\tdetails: Type.Optional(Type.Array(Type.String(), { description: \"Details for episodic memory\" })),\r\n\tcategory: Type.Optional(\r\n\t\tStringEnum([\"preference\", \"architecture\", \"convention\", \"fact\"] as const, {\r\n\t\t\tdescription: \"Category for semantic memory\",\r\n\t\t}),\r\n\t),\r\n\ttext: Type.Optional(Type.String({ description: \"Text content for semantic memory\" })),\r\n\ttags: Type.Optional(Type.Array(Type.String(), { description: \"Tags for searchability\" })),\r\n\treflection_mistakes: Type.Optional(\r\n\t\tType.Array(Type.String(), { description: \"Mistakes made (for episodic reflection)\" }),\r\n\t),\r\n\treflection_lessons: Type.Optional(\r\n\t\tType.Array(Type.String(), { description: \"Lessons learned (for episodic reflection)\" }),\r\n\t),\r\n});\r\n\r\ntype MemoryWriteInput = Static<typeof memoryWriteSchema>;\r\n\r\nconst memoryReadSchema = Type.Object({\r\n\ttype: Type.Optional(StringEnum([\"procedural\", \"episodic\", \"semantic\", \"all\"] as const)),\r\n\tid: Type.Optional(Type.String({ description: \"Specific memory ID to retrieve\" })),\r\n\tquery: Type.Optional(Type.String({ description: \"Search query to find relevant memories\" })),\r\n});\r\n\r\ntype MemoryReadInput = Static<typeof memoryReadSchema>;\r\n\r\nconst memoryUpdateSchema = Type.Object({\r\n\tid: Type.String({ description: \"Memory ID to update\" }),\r\n\ttext: Type.Optional(Type.String({ description: \"New text (for semantic memories)\" })),\r\n\tsteps: Type.Optional(Type.Array(Type.String(), { description: \"New steps (for procedural memories)\" })),\r\n\ttrigger: Type.Optional(Type.String({ description: \"New trigger (for procedural memories)\" })),\r\n\ttags: Type.Optional(Type.Array(Type.String(), { description: \"Replace tags\" })),\r\n});\r\n\r\ntype MemoryUpdateInput = Static<typeof memoryUpdateSchema>;\r\n\r\nconst memoryDeleteSchema = Type.Object({\r\n\tid: Type.String({ description: \"Memory ID to delete (e.g., 'proc_001', 'sem_003')\" }),\r\n});\r\n\r\ntype MemoryDeleteInput = Static<typeof memoryDeleteSchema>;\r\n\r\n// ---------------------------------------------------------------------------\r\n// memory_write\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const memoryWriteTool: AgentTool<typeof memoryWriteSchema> = {\r\n\tname: \"memory_write\",\r\n\tlabel: \"Write Memory\",\r\n\tdescription:\r\n\t\t\"Save a memory to the persistent memory system. Use this automatically when: \" +\r\n\t\t\"(1) the user teaches you a multi-step workflow — save as 'procedural', \" +\r\n\t\t\"(2) the user states a preference, rule, or fact — save as 'semantic', \" +\r\n\t\t\"(3) a significant task completes — save as 'episodic'. \" +\r\n\t\t\"Do NOT ask the user for permission to save unless there is a conflict with an existing memory.\",\r\n\tparameters: memoryWriteSchema,\r\n\texecute: async (_toolCallId: string, params: MemoryWriteInput) => {\r\n\t\tconst { cwd, sessionId } = memoryContext;\r\n\t\tconst tags = params.tags ?? [];\r\n\r\n\t\tif (params.type === \"procedural\") {\r\n\t\t\tif (!params.name || !params.trigger || !params.steps?.length) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"Error: procedural memory requires name, trigger, and steps.\" }],\r\n\t\t\t\t\tdetails: {},\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\tconst store = loadStore<ProceduralMemory>(cwd, \"procedural.json\");\r\n\t\t\tconst existing = store.memories.find((m) => m.name === params.name);\r\n\t\t\tif (existing) {\r\n\t\t\t\texisting.steps = params.steps;\r\n\t\t\t\texisting.trigger = params.trigger;\r\n\t\t\t\texisting.tags = [...new Set([...existing.tags, ...tags])];\r\n\t\t\t\texisting.updated = nowISO();\r\n\t\t\t\tsaveStore(cwd, \"procedural.json\", store);\r\n\t\t\t\treturn {\r\n\t\t\t\t\tcontent: [{ type: \"text\", text: `Updated procedural memory [${existing.id}] \"${params.name}\".` }],\r\n\t\t\t\t\tdetails: { action: \"updated\", id: existing.id },\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\tconst id = generateId(\"proc\", store);\r\n\t\t\tstore.memories.push({\r\n\t\t\t\tid,\r\n\t\t\t\tname: params.name,\r\n\t\t\t\ttrigger: params.trigger,\r\n\t\t\t\tsteps: params.steps,\r\n\t\t\t\ttags,\r\n\t\t\t\tcreated: nowISO(),\r\n\t\t\t\tupdated: nowISO(),\r\n\t\t\t\tsourceSession: sessionId,\r\n\t\t\t});\r\n\t\t\tsaveStore(cwd, \"procedural.json\", store);\r\n\t\t\treturn {\r\n\t\t\t\tcontent: [{ type: \"text\", text: `Saved procedural memory [${id}] \"${params.name}\".` }],\r\n\t\t\t\tdetails: { action: \"created\", id },\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tif (params.type === \"episodic\") {\r\n\t\t\tif (!params.summary) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"Error: episodic memory requires a summary.\" }],\r\n\t\t\t\t\tdetails: {},\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\tconst store = loadStore<EpisodicMemory>(cwd, \"episodic.json\");\r\n\t\t\tconst id = generateId(\"ep\", store);\r\n\t\t\tconst reflection =\r\n\t\t\t\tparams.reflection_mistakes?.length || params.reflection_lessons?.length\r\n\t\t\t\t\t? { mistakes: params.reflection_mistakes ?? [], lessons: params.reflection_lessons ?? [] }\r\n\t\t\t\t\t: undefined;\r\n\t\t\tstore.memories.push({\r\n\t\t\t\tid,\r\n\t\t\t\tsummary: params.summary,\r\n\t\t\t\tdetails: params.details ?? [],\r\n\t\t\t\treflection,\r\n\t\t\t\ttags,\r\n\t\t\t\tdate: new Date().toISOString().split(\"T\")[0],\r\n\t\t\t\tsourceSession: sessionId,\r\n\t\t\t});\r\n\t\t\tsaveStore(cwd, \"episodic.json\", store);\r\n\t\t\treturn {\r\n\t\t\t\tcontent: [{ type: \"text\", text: `Saved episodic memory [${id}] \"${params.summary}\".` }],\r\n\t\t\t\tdetails: { action: \"created\", id },\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tif (params.type === \"semantic\") {\r\n\t\t\tif (!params.text || !params.category) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"Error: semantic memory requires text and category.\" }],\r\n\t\t\t\t\tdetails: {},\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\tconst store = loadStore<SemanticMemory>(cwd, \"semantic.json\");\r\n\t\t\tconst existing = store.memories.find(\r\n\t\t\t\t(m) => m.category === params.category && m.text.toLowerCase() === params.text!.toLowerCase(),\r\n\t\t\t);\r\n\t\t\tif (existing) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tcontent: [{ type: \"text\", text: `This semantic memory already exists [${existing.id}].` }],\r\n\t\t\t\t\tdetails: { action: \"duplicate\", id: existing.id },\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\tconst id = generateId(\"sem\", store);\r\n\t\t\tstore.memories.push({\r\n\t\t\t\tid,\r\n\t\t\t\tcategory: params.category,\r\n\t\t\t\ttext: params.text,\r\n\t\t\t\ttags,\r\n\t\t\t\tcreated: nowISO(),\r\n\t\t\t\tsourceSession: sessionId,\r\n\t\t\t});\r\n\t\t\tsaveStore(cwd, \"semantic.json\", store);\r\n\t\t\treturn {\r\n\t\t\t\tcontent: [{ type: \"text\", text: `Saved semantic memory [${id}] (${params.category}): \"${params.text}\".` }],\r\n\t\t\t\tdetails: { action: \"created\", id },\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\tcontent: [{ type: \"text\", text: `Unknown memory type: ${params.type}` }],\r\n\t\t\tdetails: {},\r\n\t\t};\r\n\t},\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// memory_read\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const memoryReadTool: AgentTool<typeof memoryReadSchema> = {\r\n\tname: \"memory_read\",\r\n\tlabel: \"Read Memory\",\r\n\tdescription:\r\n\t\t\"Read memories from the persistent memory system. Use this when you need to recall \" +\r\n\t\t\"past workflows, user preferences, or what happened in previous sessions. \" +\r\n\t\t\"You can read all memories of a type, a specific memory by ID, or search by query.\",\r\n\tparameters: memoryReadSchema,\r\n\texecute: async (_toolCallId: string, params: MemoryReadInput) => {\r\n\t\tconst { cwd } = memoryContext;\r\n\r\n\t\tif (params.id) {\r\n\t\t\tconst allStores: Array<{ file: string; format: (m: any) => string }> = [\r\n\t\t\t\t{ file: \"procedural.json\", format: formatProceduralForDisplay },\r\n\t\t\t\t{ file: \"episodic.json\", format: formatEpisodicForDisplay },\r\n\t\t\t\t{ file: \"semantic.json\", format: formatSemanticForDisplay },\r\n\t\t\t];\r\n\t\t\tfor (const { file, format } of allStores) {\r\n\t\t\t\tconst store = loadStore<{ id: string }>(cwd, file);\r\n\t\t\t\tconst found = store.memories.find((m) => m.id === params.id);\r\n\t\t\t\tif (found) {\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: format(found) }],\r\n\t\t\t\t\t\tdetails: { found: true },\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn {\r\n\t\t\t\tcontent: [{ type: \"text\", text: `No memory found with ID \"${params.id}\".` }],\r\n\t\t\t\tdetails: { found: false },\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tif (params.query) {\r\n\t\t\tconst results: string[] = [];\r\n\t\t\tconst type = params.type ?? \"all\";\r\n\r\n\t\t\tif (type === \"all\" || type === \"procedural\") {\r\n\t\t\t\tconst store = loadStore<ProceduralMemory>(cwd, \"procedural.json\");\r\n\t\t\t\tconst matches = searchMemories(\r\n\t\t\t\t\tstore.memories,\r\n\t\t\t\t\tparams.query,\r\n\t\t\t\t\t(m) => `${m.name} ${m.trigger} ${m.steps.join(\" \")}`,\r\n\t\t\t\t);\r\n\t\t\t\tresults.push(...matches.map(formatProceduralForDisplay));\r\n\t\t\t}\r\n\t\t\tif (type === \"all\" || type === \"episodic\") {\r\n\t\t\t\tconst store = loadStore<EpisodicMemory>(cwd, \"episodic.json\");\r\n\t\t\t\tconst matches = searchMemories(store.memories, params.query, (m) => `${m.summary} ${m.details.join(\" \")}`);\r\n\t\t\t\tresults.push(...matches.map(formatEpisodicForDisplay));\r\n\t\t\t}\r\n\t\t\tif (type === \"all\" || type === \"semantic\") {\r\n\t\t\t\tconst store = loadStore<SemanticMemory>(cwd, \"semantic.json\");\r\n\t\t\t\tconst matches = searchMemories(store.memories, params.query, (m) => `${m.category} ${m.text}`);\r\n\t\t\t\tresults.push(...matches.map(formatSemanticForDisplay));\r\n\t\t\t}\r\n\r\n\t\t\tif (results.length === 0) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tcontent: [{ type: \"text\", text: `No memories found matching \"${params.query}\".` }],\r\n\t\t\t\t\tdetails: { count: 0 },\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\treturn {\r\n\t\t\t\tcontent: [{ type: \"text\", text: results.join(\"\\n\\n\") }],\r\n\t\t\t\tdetails: { count: results.length },\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tconst type = params.type ?? \"all\";\r\n\t\tconst results: string[] = [];\r\n\r\n\t\tif (type === \"all\" || type === \"procedural\") {\r\n\t\t\tconst store = loadStore<ProceduralMemory>(cwd, \"procedural.json\");\r\n\t\t\tif (store.memories.length > 0) {\r\n\t\t\t\tresults.push(\"=== Procedural Memories ===\");\r\n\t\t\t\tresults.push(...store.memories.map(formatProceduralForDisplay));\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (type === \"all\" || type === \"episodic\") {\r\n\t\t\tconst store = loadStore<EpisodicMemory>(cwd, \"episodic.json\");\r\n\t\t\tif (store.memories.length > 0) {\r\n\t\t\t\tresults.push(\"=== Episodic Memories ===\");\r\n\t\t\t\tresults.push(...store.memories.map(formatEpisodicForDisplay));\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (type === \"all\" || type === \"semantic\") {\r\n\t\t\tconst store = loadStore<SemanticMemory>(cwd, \"semantic.json\");\r\n\t\t\tif (store.memories.length > 0) {\r\n\t\t\t\tresults.push(\"=== Semantic Memories ===\");\r\n\t\t\t\tresults.push(...store.memories.map(formatSemanticForDisplay));\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (results.length === 0) {\r\n\t\t\treturn {\r\n\t\t\t\tcontent: [{ type: \"text\", text: \"No memories stored yet.\" }],\r\n\t\t\t\tdetails: { count: 0 },\r\n\t\t\t};\r\n\t\t}\r\n\t\treturn {\r\n\t\t\tcontent: [{ type: \"text\", text: results.join(\"\\n\\n\") }],\r\n\t\t\tdetails: { count: results.length },\r\n\t\t};\r\n\t},\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// memory_update\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const memoryUpdateTool: AgentTool<typeof memoryUpdateSchema> = {\r\n\tname: \"memory_update\",\r\n\tlabel: \"Update Memory\",\r\n\tdescription:\r\n\t\t\"Update an existing memory. Use this when the user confirms a change to a \" +\r\n\t\t\"previously stored preference, procedure step, or fact. Always ask for \" +\r\n\t\t\"confirmation before updating if there is a conflict.\",\r\n\tparameters: memoryUpdateSchema,\r\n\texecute: async (_toolCallId: string, params: MemoryUpdateInput) => {\r\n\t\tconst { cwd } = memoryContext;\r\n\r\n\t\tconst procStore = loadStore<ProceduralMemory>(cwd, \"procedural.json\");\r\n\t\tconst proc = procStore.memories.find((m) => m.id === params.id);\r\n\t\tif (proc) {\r\n\t\t\tif (params.steps) proc.steps = params.steps;\r\n\t\t\tif (params.trigger) proc.trigger = params.trigger;\r\n\t\t\tif (params.tags) proc.tags = params.tags;\r\n\t\t\tproc.updated = nowISO();\r\n\t\t\tsaveStore(cwd, \"procedural.json\", procStore);\r\n\t\t\treturn {\r\n\t\t\t\tcontent: [{ type: \"text\", text: `Updated procedural memory [${params.id}].` }],\r\n\t\t\t\tdetails: { updated: true },\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tconst semStore = loadStore<SemanticMemory>(cwd, \"semantic.json\");\r\n\t\tconst sem = semStore.memories.find((m) => m.id === params.id);\r\n\t\tif (sem) {\r\n\t\t\tif (params.text) sem.text = params.text;\r\n\t\t\tif (params.tags) sem.tags = params.tags;\r\n\t\t\tsaveStore(cwd, \"semantic.json\", semStore);\r\n\t\t\treturn {\r\n\t\t\t\tcontent: [{ type: \"text\", text: `Updated semantic memory [${params.id}].` }],\r\n\t\t\t\tdetails: { updated: true },\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tconst epStore = loadStore<EpisodicMemory>(cwd, \"episodic.json\");\r\n\t\tconst ep = epStore.memories.find((m) => m.id === params.id);\r\n\t\tif (ep) {\r\n\t\t\tif (params.tags) ep.tags = params.tags;\r\n\t\t\tsaveStore(cwd, \"episodic.json\", epStore);\r\n\t\t\treturn {\r\n\t\t\t\tcontent: [{ type: \"text\", text: `Updated episodic memory [${params.id}].` }],\r\n\t\t\t\tdetails: { updated: true },\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\tcontent: [{ type: \"text\", text: `No memory found with ID \"${params.id}\".` }],\r\n\t\t\tdetails: { updated: false },\r\n\t\t};\r\n\t},\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// memory_delete\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const memoryDeleteTool: AgentTool<typeof memoryDeleteSchema> = {\r\n\tname: \"memory_delete\",\r\n\tlabel: \"Delete Memory\",\r\n\tdescription:\r\n\t\t\"Delete a specific memory by ID. Use this when the user asks to remove a memory \" +\r\n\t\t\"or when a memory is confirmed to be outdated.\",\r\n\tparameters: memoryDeleteSchema,\r\n\texecute: async (_toolCallId: string, params: MemoryDeleteInput) => {\r\n\t\tconst { cwd } = memoryContext;\r\n\t\tconst files = [\"procedural.json\", \"episodic.json\", \"semantic.json\"] as const;\r\n\r\n\t\tfor (const file of files) {\r\n\t\t\tconst store = loadStore<{ id: string }>(cwd, file);\r\n\t\t\tconst idx = store.memories.findIndex((m) => m.id === params.id);\r\n\t\t\tif (idx !== -1) {\r\n\t\t\t\tstore.memories.splice(idx, 1);\r\n\t\t\t\tsaveStore(cwd, file, store);\r\n\t\t\t\treturn {\r\n\t\t\t\t\tcontent: [{ type: \"text\", text: `Deleted memory [${params.id}] from ${file.replace(\".json\", \"\")}.` }],\r\n\t\t\t\t\tdetails: { deleted: true },\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\tcontent: [{ type: \"text\", text: `No memory found with ID \"${params.id}\".` }],\r\n\t\t\tdetails: { deleted: false },\r\n\t\t};\r\n\t},\r\n};\r\n\r\n/** All memory tools */\r\nexport const memoryTools: AgentTool<any>[] = [memoryWriteTool, memoryReadTool, memoryUpdateTool, memoryDeleteTool];\r\n"]}
@@ -0,0 +1,346 @@
1
+ /**
2
+ * Built-in memory tools: memory_write, memory_read, memory_update, memory_delete
3
+ */
4
+ import { StringEnum } from "@mariozechner/pi-ai";
5
+ import { Type } from "@sinclair/typebox";
6
+ import { formatEpisodicForDisplay, formatProceduralForDisplay, formatSemanticForDisplay, generateId, loadStore, nowISO, saveStore, searchMemories, } from "../memory.js";
7
+ let memoryContext = { cwd: process.cwd(), sessionId: `session_${Date.now()}` };
8
+ export function setMemoryToolContext(ctx) {
9
+ memoryContext = ctx;
10
+ }
11
+ // ---------------------------------------------------------------------------
12
+ // Schemas
13
+ // ---------------------------------------------------------------------------
14
+ const memoryWriteSchema = Type.Object({
15
+ type: StringEnum(["procedural", "episodic", "semantic"]),
16
+ name: Type.Optional(Type.String({ description: "Name for procedural memories (e.g., 'deploy-service')" })),
17
+ trigger: Type.Optional(Type.String({ description: "When to invoke this procedure (e.g., 'user asks to deploy a service')" })),
18
+ steps: Type.Optional(Type.Array(Type.String(), { description: "Steps for procedural memory" })),
19
+ summary: Type.Optional(Type.String({ description: "Summary for episodic memory" })),
20
+ details: Type.Optional(Type.Array(Type.String(), { description: "Details for episodic memory" })),
21
+ category: Type.Optional(StringEnum(["preference", "architecture", "convention", "fact"], {
22
+ description: "Category for semantic memory",
23
+ })),
24
+ text: Type.Optional(Type.String({ description: "Text content for semantic memory" })),
25
+ tags: Type.Optional(Type.Array(Type.String(), { description: "Tags for searchability" })),
26
+ reflection_mistakes: Type.Optional(Type.Array(Type.String(), { description: "Mistakes made (for episodic reflection)" })),
27
+ reflection_lessons: Type.Optional(Type.Array(Type.String(), { description: "Lessons learned (for episodic reflection)" })),
28
+ });
29
+ const memoryReadSchema = Type.Object({
30
+ type: Type.Optional(StringEnum(["procedural", "episodic", "semantic", "all"])),
31
+ id: Type.Optional(Type.String({ description: "Specific memory ID to retrieve" })),
32
+ query: Type.Optional(Type.String({ description: "Search query to find relevant memories" })),
33
+ });
34
+ const memoryUpdateSchema = Type.Object({
35
+ id: Type.String({ description: "Memory ID to update" }),
36
+ text: Type.Optional(Type.String({ description: "New text (for semantic memories)" })),
37
+ steps: Type.Optional(Type.Array(Type.String(), { description: "New steps (for procedural memories)" })),
38
+ trigger: Type.Optional(Type.String({ description: "New trigger (for procedural memories)" })),
39
+ tags: Type.Optional(Type.Array(Type.String(), { description: "Replace tags" })),
40
+ });
41
+ const memoryDeleteSchema = Type.Object({
42
+ id: Type.String({ description: "Memory ID to delete (e.g., 'proc_001', 'sem_003')" }),
43
+ });
44
+ // ---------------------------------------------------------------------------
45
+ // memory_write
46
+ // ---------------------------------------------------------------------------
47
+ export const memoryWriteTool = {
48
+ name: "memory_write",
49
+ label: "Write Memory",
50
+ description: "Save a memory to the persistent memory system. Use this automatically when: " +
51
+ "(1) the user teaches you a multi-step workflow — save as 'procedural', " +
52
+ "(2) the user states a preference, rule, or fact — save as 'semantic', " +
53
+ "(3) a significant task completes — save as 'episodic'. " +
54
+ "Do NOT ask the user for permission to save unless there is a conflict with an existing memory.",
55
+ parameters: memoryWriteSchema,
56
+ execute: async (_toolCallId, params) => {
57
+ const { cwd, sessionId } = memoryContext;
58
+ const tags = params.tags ?? [];
59
+ if (params.type === "procedural") {
60
+ if (!params.name || !params.trigger || !params.steps?.length) {
61
+ return {
62
+ content: [{ type: "text", text: "Error: procedural memory requires name, trigger, and steps." }],
63
+ details: {},
64
+ };
65
+ }
66
+ const store = loadStore(cwd, "procedural.json");
67
+ const existing = store.memories.find((m) => m.name === params.name);
68
+ if (existing) {
69
+ existing.steps = params.steps;
70
+ existing.trigger = params.trigger;
71
+ existing.tags = [...new Set([...existing.tags, ...tags])];
72
+ existing.updated = nowISO();
73
+ saveStore(cwd, "procedural.json", store);
74
+ return {
75
+ content: [{ type: "text", text: `Updated procedural memory [${existing.id}] "${params.name}".` }],
76
+ details: { action: "updated", id: existing.id },
77
+ };
78
+ }
79
+ const id = generateId("proc", store);
80
+ store.memories.push({
81
+ id,
82
+ name: params.name,
83
+ trigger: params.trigger,
84
+ steps: params.steps,
85
+ tags,
86
+ created: nowISO(),
87
+ updated: nowISO(),
88
+ sourceSession: sessionId,
89
+ });
90
+ saveStore(cwd, "procedural.json", store);
91
+ return {
92
+ content: [{ type: "text", text: `Saved procedural memory [${id}] "${params.name}".` }],
93
+ details: { action: "created", id },
94
+ };
95
+ }
96
+ if (params.type === "episodic") {
97
+ if (!params.summary) {
98
+ return {
99
+ content: [{ type: "text", text: "Error: episodic memory requires a summary." }],
100
+ details: {},
101
+ };
102
+ }
103
+ const store = loadStore(cwd, "episodic.json");
104
+ const id = generateId("ep", store);
105
+ const reflection = params.reflection_mistakes?.length || params.reflection_lessons?.length
106
+ ? { mistakes: params.reflection_mistakes ?? [], lessons: params.reflection_lessons ?? [] }
107
+ : undefined;
108
+ store.memories.push({
109
+ id,
110
+ summary: params.summary,
111
+ details: params.details ?? [],
112
+ reflection,
113
+ tags,
114
+ date: new Date().toISOString().split("T")[0],
115
+ sourceSession: sessionId,
116
+ });
117
+ saveStore(cwd, "episodic.json", store);
118
+ return {
119
+ content: [{ type: "text", text: `Saved episodic memory [${id}] "${params.summary}".` }],
120
+ details: { action: "created", id },
121
+ };
122
+ }
123
+ if (params.type === "semantic") {
124
+ if (!params.text || !params.category) {
125
+ return {
126
+ content: [{ type: "text", text: "Error: semantic memory requires text and category." }],
127
+ details: {},
128
+ };
129
+ }
130
+ const store = loadStore(cwd, "semantic.json");
131
+ const existing = store.memories.find((m) => m.category === params.category && m.text.toLowerCase() === params.text.toLowerCase());
132
+ if (existing) {
133
+ return {
134
+ content: [{ type: "text", text: `This semantic memory already exists [${existing.id}].` }],
135
+ details: { action: "duplicate", id: existing.id },
136
+ };
137
+ }
138
+ const id = generateId("sem", store);
139
+ store.memories.push({
140
+ id,
141
+ category: params.category,
142
+ text: params.text,
143
+ tags,
144
+ created: nowISO(),
145
+ sourceSession: sessionId,
146
+ });
147
+ saveStore(cwd, "semantic.json", store);
148
+ return {
149
+ content: [{ type: "text", text: `Saved semantic memory [${id}] (${params.category}): "${params.text}".` }],
150
+ details: { action: "created", id },
151
+ };
152
+ }
153
+ return {
154
+ content: [{ type: "text", text: `Unknown memory type: ${params.type}` }],
155
+ details: {},
156
+ };
157
+ },
158
+ };
159
+ // ---------------------------------------------------------------------------
160
+ // memory_read
161
+ // ---------------------------------------------------------------------------
162
+ export const memoryReadTool = {
163
+ name: "memory_read",
164
+ label: "Read Memory",
165
+ description: "Read memories from the persistent memory system. Use this when you need to recall " +
166
+ "past workflows, user preferences, or what happened in previous sessions. " +
167
+ "You can read all memories of a type, a specific memory by ID, or search by query.",
168
+ parameters: memoryReadSchema,
169
+ execute: async (_toolCallId, params) => {
170
+ const { cwd } = memoryContext;
171
+ if (params.id) {
172
+ const allStores = [
173
+ { file: "procedural.json", format: formatProceduralForDisplay },
174
+ { file: "episodic.json", format: formatEpisodicForDisplay },
175
+ { file: "semantic.json", format: formatSemanticForDisplay },
176
+ ];
177
+ for (const { file, format } of allStores) {
178
+ const store = loadStore(cwd, file);
179
+ const found = store.memories.find((m) => m.id === params.id);
180
+ if (found) {
181
+ return {
182
+ content: [{ type: "text", text: format(found) }],
183
+ details: { found: true },
184
+ };
185
+ }
186
+ }
187
+ return {
188
+ content: [{ type: "text", text: `No memory found with ID "${params.id}".` }],
189
+ details: { found: false },
190
+ };
191
+ }
192
+ if (params.query) {
193
+ const results = [];
194
+ const type = params.type ?? "all";
195
+ if (type === "all" || type === "procedural") {
196
+ const store = loadStore(cwd, "procedural.json");
197
+ const matches = searchMemories(store.memories, params.query, (m) => `${m.name} ${m.trigger} ${m.steps.join(" ")}`);
198
+ results.push(...matches.map(formatProceduralForDisplay));
199
+ }
200
+ if (type === "all" || type === "episodic") {
201
+ const store = loadStore(cwd, "episodic.json");
202
+ const matches = searchMemories(store.memories, params.query, (m) => `${m.summary} ${m.details.join(" ")}`);
203
+ results.push(...matches.map(formatEpisodicForDisplay));
204
+ }
205
+ if (type === "all" || type === "semantic") {
206
+ const store = loadStore(cwd, "semantic.json");
207
+ const matches = searchMemories(store.memories, params.query, (m) => `${m.category} ${m.text}`);
208
+ results.push(...matches.map(formatSemanticForDisplay));
209
+ }
210
+ if (results.length === 0) {
211
+ return {
212
+ content: [{ type: "text", text: `No memories found matching "${params.query}".` }],
213
+ details: { count: 0 },
214
+ };
215
+ }
216
+ return {
217
+ content: [{ type: "text", text: results.join("\n\n") }],
218
+ details: { count: results.length },
219
+ };
220
+ }
221
+ const type = params.type ?? "all";
222
+ const results = [];
223
+ if (type === "all" || type === "procedural") {
224
+ const store = loadStore(cwd, "procedural.json");
225
+ if (store.memories.length > 0) {
226
+ results.push("=== Procedural Memories ===");
227
+ results.push(...store.memories.map(formatProceduralForDisplay));
228
+ }
229
+ }
230
+ if (type === "all" || type === "episodic") {
231
+ const store = loadStore(cwd, "episodic.json");
232
+ if (store.memories.length > 0) {
233
+ results.push("=== Episodic Memories ===");
234
+ results.push(...store.memories.map(formatEpisodicForDisplay));
235
+ }
236
+ }
237
+ if (type === "all" || type === "semantic") {
238
+ const store = loadStore(cwd, "semantic.json");
239
+ if (store.memories.length > 0) {
240
+ results.push("=== Semantic Memories ===");
241
+ results.push(...store.memories.map(formatSemanticForDisplay));
242
+ }
243
+ }
244
+ if (results.length === 0) {
245
+ return {
246
+ content: [{ type: "text", text: "No memories stored yet." }],
247
+ details: { count: 0 },
248
+ };
249
+ }
250
+ return {
251
+ content: [{ type: "text", text: results.join("\n\n") }],
252
+ details: { count: results.length },
253
+ };
254
+ },
255
+ };
256
+ // ---------------------------------------------------------------------------
257
+ // memory_update
258
+ // ---------------------------------------------------------------------------
259
+ export const memoryUpdateTool = {
260
+ name: "memory_update",
261
+ label: "Update Memory",
262
+ description: "Update an existing memory. Use this when the user confirms a change to a " +
263
+ "previously stored preference, procedure step, or fact. Always ask for " +
264
+ "confirmation before updating if there is a conflict.",
265
+ parameters: memoryUpdateSchema,
266
+ execute: async (_toolCallId, params) => {
267
+ const { cwd } = memoryContext;
268
+ const procStore = loadStore(cwd, "procedural.json");
269
+ const proc = procStore.memories.find((m) => m.id === params.id);
270
+ if (proc) {
271
+ if (params.steps)
272
+ proc.steps = params.steps;
273
+ if (params.trigger)
274
+ proc.trigger = params.trigger;
275
+ if (params.tags)
276
+ proc.tags = params.tags;
277
+ proc.updated = nowISO();
278
+ saveStore(cwd, "procedural.json", procStore);
279
+ return {
280
+ content: [{ type: "text", text: `Updated procedural memory [${params.id}].` }],
281
+ details: { updated: true },
282
+ };
283
+ }
284
+ const semStore = loadStore(cwd, "semantic.json");
285
+ const sem = semStore.memories.find((m) => m.id === params.id);
286
+ if (sem) {
287
+ if (params.text)
288
+ sem.text = params.text;
289
+ if (params.tags)
290
+ sem.tags = params.tags;
291
+ saveStore(cwd, "semantic.json", semStore);
292
+ return {
293
+ content: [{ type: "text", text: `Updated semantic memory [${params.id}].` }],
294
+ details: { updated: true },
295
+ };
296
+ }
297
+ const epStore = loadStore(cwd, "episodic.json");
298
+ const ep = epStore.memories.find((m) => m.id === params.id);
299
+ if (ep) {
300
+ if (params.tags)
301
+ ep.tags = params.tags;
302
+ saveStore(cwd, "episodic.json", epStore);
303
+ return {
304
+ content: [{ type: "text", text: `Updated episodic memory [${params.id}].` }],
305
+ details: { updated: true },
306
+ };
307
+ }
308
+ return {
309
+ content: [{ type: "text", text: `No memory found with ID "${params.id}".` }],
310
+ details: { updated: false },
311
+ };
312
+ },
313
+ };
314
+ // ---------------------------------------------------------------------------
315
+ // memory_delete
316
+ // ---------------------------------------------------------------------------
317
+ export const memoryDeleteTool = {
318
+ name: "memory_delete",
319
+ label: "Delete Memory",
320
+ description: "Delete a specific memory by ID. Use this when the user asks to remove a memory " +
321
+ "or when a memory is confirmed to be outdated.",
322
+ parameters: memoryDeleteSchema,
323
+ execute: async (_toolCallId, params) => {
324
+ const { cwd } = memoryContext;
325
+ const files = ["procedural.json", "episodic.json", "semantic.json"];
326
+ for (const file of files) {
327
+ const store = loadStore(cwd, file);
328
+ const idx = store.memories.findIndex((m) => m.id === params.id);
329
+ if (idx !== -1) {
330
+ store.memories.splice(idx, 1);
331
+ saveStore(cwd, file, store);
332
+ return {
333
+ content: [{ type: "text", text: `Deleted memory [${params.id}] from ${file.replace(".json", "")}.` }],
334
+ details: { deleted: true },
335
+ };
336
+ }
337
+ }
338
+ return {
339
+ content: [{ type: "text", text: `No memory found with ID "${params.id}".` }],
340
+ details: { deleted: false },
341
+ };
342
+ },
343
+ };
344
+ /** All memory tools */
345
+ export const memoryTools = [memoryWriteTool, memoryReadTool, memoryUpdateTool, memoryDeleteTool];
346
+ //# sourceMappingURL=memory.js.map