@prometheus-ai/agent 0.5.4 → 0.5.8

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 (1145) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/cli.js +25110 -0
  3. package/dist/types/async/index.d.ts +0 -1
  4. package/dist/types/async/job-manager.d.ts +33 -0
  5. package/dist/types/autolearn/controller.d.ts +25 -0
  6. package/dist/types/autolearn/managed-skills.d.ts +45 -0
  7. package/dist/types/autoresearch/state.d.ts +1 -1
  8. package/dist/types/autoresearch/tools/init-experiment.d.ts +1 -1
  9. package/dist/types/autoresearch/tools/log-experiment.d.ts +1 -1
  10. package/dist/types/autoresearch/tools/run-experiment.d.ts +1 -1
  11. package/dist/types/autoresearch/tools/update-notes.d.ts +1 -1
  12. package/dist/types/autoresearch/types.d.ts +1 -1
  13. package/dist/types/capability/context-file.d.ts +0 -13
  14. package/dist/types/capability/mcp.d.ts +1 -0
  15. package/dist/types/capability/rule-buckets.d.ts +1 -1
  16. package/dist/types/capability/rule.d.ts +6 -1
  17. package/dist/types/capability/types.d.ts +0 -4
  18. package/dist/types/cli/args.d.ts +23 -3
  19. package/dist/types/cli/bench-cli.d.ts +78 -0
  20. package/dist/types/cli/claude-trace-cli.d.ts +7 -0
  21. package/dist/types/cli/dry-balance-cli.d.ts +16 -2
  22. package/dist/types/cli/gallery-cli.d.ts +43 -0
  23. package/dist/types/cli/gallery-fixtures/agentic.d.ts +2 -0
  24. package/dist/types/cli/gallery-fixtures/codeintel.d.ts +3 -0
  25. package/dist/types/cli/gallery-fixtures/edit.d.ts +3 -0
  26. package/dist/types/cli/gallery-fixtures/fs.d.ts +2 -0
  27. package/dist/types/cli/gallery-fixtures/index.d.ts +4 -0
  28. package/dist/types/cli/gallery-fixtures/interaction.d.ts +3 -0
  29. package/dist/types/cli/gallery-fixtures/memory.d.ts +2 -0
  30. package/dist/types/cli/gallery-fixtures/misc.d.ts +3 -0
  31. package/dist/types/cli/gallery-fixtures/search.d.ts +3 -0
  32. package/dist/types/cli/gallery-fixtures/shell.d.ts +3 -0
  33. package/dist/types/cli/gallery-fixtures/types.d.ts +55 -0
  34. package/dist/types/cli/gallery-fixtures/web.d.ts +2 -0
  35. package/dist/types/cli/gallery-screenshot.d.ts +35 -0
  36. package/dist/types/cli/grievances-cli.d.ts +1 -1
  37. package/dist/types/cli/list-models.d.ts +6 -14
  38. package/dist/types/cli/models-cli.d.ts +49 -0
  39. package/dist/types/cli/session-picker.d.ts +1 -1
  40. package/dist/types/cli/setup-cli.d.ts +1 -1
  41. package/dist/types/cli/setup-model-picker.d.ts +14 -0
  42. package/dist/types/cli/startup-cwd.d.ts +2 -0
  43. package/dist/types/cli/update-cli.d.ts +13 -40
  44. package/dist/types/cli/usage-cli.d.ts +81 -0
  45. package/dist/types/cli-commands.d.ts +12 -0
  46. package/dist/types/collab/crypto.d.ts +7 -0
  47. package/dist/types/collab/guest.d.ts +37 -0
  48. package/dist/types/collab/host.d.ts +29 -0
  49. package/dist/types/collab/protocol.d.ts +119 -0
  50. package/dist/types/collab/relay-client.d.ts +22 -0
  51. package/dist/types/commands/bench.d.ts +29 -0
  52. package/dist/types/commands/gallery.d.ts +47 -0
  53. package/dist/types/commands/install.d.ts +1 -1
  54. package/dist/types/commands/join.d.ts +12 -0
  55. package/dist/types/commands/launch.d.ts +8 -4
  56. package/dist/types/commands/models.d.ts +33 -0
  57. package/dist/types/commands/read.d.ts +1 -1
  58. package/dist/types/commands/say.d.ts +24 -0
  59. package/dist/types/commands/token.d.ts +25 -0
  60. package/dist/types/commands/usage.d.ts +34 -0
  61. package/dist/types/commit/agentic/tools/analyze-file.d.ts +1 -1
  62. package/dist/types/commit/agentic/tools/git-file-diff.d.ts +1 -1
  63. package/dist/types/commit/agentic/tools/git-hunk.d.ts +1 -1
  64. package/dist/types/commit/agentic/tools/git-overview.d.ts +1 -1
  65. package/dist/types/commit/agentic/tools/propose-changelog.d.ts +1 -1
  66. package/dist/types/commit/agentic/tools/propose-commit.d.ts +1 -1
  67. package/dist/types/commit/agentic/tools/recent-commits.d.ts +1 -1
  68. package/dist/types/commit/agentic/tools/schemas.d.ts +1 -1
  69. package/dist/types/commit/agentic/tools/split-commit.d.ts +1 -1
  70. package/dist/types/commit/analysis/conventional.d.ts +2 -2
  71. package/dist/types/commit/analysis/summary.d.ts +2 -2
  72. package/dist/types/commit/changelog/generate.d.ts +3 -3
  73. package/dist/types/commit/changelog/index.d.ts +2 -2
  74. package/dist/types/commit/map-reduce/index.d.ts +3 -3
  75. package/dist/types/commit/map-reduce/map-phase.d.ts +2 -2
  76. package/dist/types/commit/map-reduce/reduce-phase.d.ts +2 -2
  77. package/dist/types/commit/model-selection.d.ts +10 -4
  78. package/dist/types/commit/shared-llm.d.ts +1 -1
  79. package/dist/types/config/api-key-resolver.d.ts +43 -0
  80. package/dist/types/config/append-only-context-mode.d.ts +2 -1
  81. package/dist/types/config/keybindings.d.ts +12 -7
  82. package/dist/types/config/model-discovery.d.ts +57 -0
  83. package/dist/types/config/model-equivalence.d.ts +1 -1
  84. package/dist/types/config/model-registry.d.ts +86 -222
  85. package/dist/types/config/model-resolver.d.ts +43 -12
  86. package/dist/types/config/model-roles.d.ts +29 -0
  87. package/dist/types/config/models-config-schema.d.ts +536 -43
  88. package/dist/types/config/models-config.d.ts +391 -0
  89. package/dist/types/config/settings-schema.d.ts +1202 -324
  90. package/dist/types/config/settings.d.ts +15 -3
  91. package/dist/types/dap/config.d.ts +14 -1
  92. package/dist/types/dap/types.d.ts +10 -0
  93. package/dist/types/debug/log-viewer.d.ts +1 -1
  94. package/dist/types/debug/raw-sse.d.ts +1 -1
  95. package/dist/types/debug/report-bundle.d.ts +3 -0
  96. package/dist/types/debug/terminal-info.d.ts +0 -1
  97. package/dist/types/discovery/at-imports.d.ts +15 -0
  98. package/dist/types/discovery/prometheus-extension-roots.d.ts +7 -7
  99. package/dist/types/edit/diff.d.ts +3 -2
  100. package/dist/types/edit/file-snapshot-store.d.ts +18 -0
  101. package/dist/types/edit/hashline/noop-loop-guard.d.ts +72 -0
  102. package/dist/types/edit/hashline/params.d.ts +1 -1
  103. package/dist/types/edit/index.d.ts +0 -1
  104. package/dist/types/edit/modes/apply-patch.d.ts +1 -1
  105. package/dist/types/edit/modes/patch.d.ts +1 -1
  106. package/dist/types/edit/modes/replace.d.ts +1 -1
  107. package/dist/types/edit/renderer.d.ts +1 -0
  108. package/dist/types/eval/__tests__/completion-bridge.test.d.ts +1 -0
  109. package/dist/types/eval/__tests__/helpers-local-roots.test.d.ts +1 -0
  110. package/dist/types/eval/__tests__/js-context-manager.test.d.ts +1 -0
  111. package/dist/types/eval/backend.d.ts +7 -2
  112. package/dist/types/eval/bridge-timeout.d.ts +1 -1
  113. package/dist/types/eval/completion-bridge.d.ts +25 -0
  114. package/dist/types/eval/idle-timeout.d.ts +1 -5
  115. package/dist/types/eval/js/context-manager.d.ts +1 -0
  116. package/dist/types/eval/js/executor.d.ts +2 -0
  117. package/dist/types/eval/js/index.d.ts +1 -1
  118. package/dist/types/eval/js/shared/helpers.d.ts +7 -1
  119. package/dist/types/eval/js/shared/rewrite-imports.d.ts +6 -6
  120. package/dist/types/eval/js/shared/runtime.d.ts +6 -1
  121. package/dist/types/eval/js/worker-protocol.d.ts +6 -0
  122. package/dist/types/eval/py/__tests__/prelude.test.d.ts +1 -0
  123. package/dist/types/eval/py/executor.d.ts +12 -0
  124. package/dist/types/eval/py/index.d.ts +1 -1
  125. package/dist/types/eval/py/kernel.d.ts +6 -1
  126. package/dist/types/eval/py/runtime.d.ts +9 -0
  127. package/dist/types/exa/index.d.ts +1 -19
  128. package/dist/types/exa/mcp-client.d.ts +10 -3
  129. package/dist/types/exa/types.d.ts +0 -83
  130. package/dist/types/exec/bash-executor.d.ts +7 -0
  131. package/dist/types/export/custom-share.d.ts +1 -2
  132. package/dist/types/export/html/index.d.ts +39 -0
  133. package/dist/types/export/html/template-js.d.ts +2 -0
  134. package/dist/types/export/share.d.ts +61 -0
  135. package/dist/types/export/ttsr.d.ts +14 -0
  136. package/dist/types/extensibility/custom-commands/types.d.ts +9 -4
  137. package/dist/types/extensibility/custom-tools/loader.d.ts +30 -4
  138. package/dist/types/extensibility/custom-tools/types.d.ts +16 -8
  139. package/dist/types/extensibility/extensions/index.d.ts +1 -1
  140. package/dist/types/extensibility/extensions/loader.d.ts +20 -1
  141. package/dist/types/extensibility/extensions/model-api.d.ts +17 -0
  142. package/dist/types/extensibility/extensions/runner.d.ts +5 -2
  143. package/dist/types/extensibility/extensions/types.d.ts +72 -11
  144. package/dist/types/extensibility/hooks/index.d.ts +2 -1
  145. package/dist/types/extensibility/hooks/loader.d.ts +1 -1
  146. package/dist/types/extensibility/hooks/types.d.ts +11 -5
  147. package/dist/types/extensibility/{legacy-pi-ai-shim.d.ts → legacy-package-ai-shim.d.ts} +2 -2
  148. package/dist/types/extensibility/plugins/{legacy-pi-compat.d.ts → legacy-package-compat.d.ts} +20 -3
  149. package/dist/types/extensibility/plugins/loader.d.ts +11 -0
  150. package/dist/types/extensibility/plugins/marketplace-auto-update.d.ts +8 -0
  151. package/dist/types/extensibility/plugins/types.d.ts +2 -2
  152. package/dist/types/extensibility/shared-events.d.ts +3 -3
  153. package/dist/types/extensibility/skills.d.ts +10 -0
  154. package/dist/types/extensibility/slash-commands.d.ts +1 -11
  155. package/dist/types/goals/guided-setup.d.ts +18 -0
  156. package/dist/types/goals/state.d.ts +1 -1
  157. package/dist/types/goals/tools/goal-tool.d.ts +1 -1
  158. package/dist/types/hindsight/mental-models.d.ts +17 -8
  159. package/dist/types/hindsight/transcript.d.ts +1 -1
  160. package/dist/types/index.d.ts +5 -0
  161. package/dist/types/internal-urls/artifact-protocol.d.ts +2 -2
  162. package/dist/types/internal-urls/history-protocol.d.ts +14 -0
  163. package/dist/types/internal-urls/index.d.ts +1 -0
  164. package/dist/types/internal-urls/local-protocol.d.ts +14 -2
  165. package/dist/types/internal-urls/types.d.ts +1 -1
  166. package/dist/types/irc/bus.d.ts +79 -0
  167. package/dist/types/lib/xai-http.d.ts +1 -1
  168. package/dist/types/lsp/client.d.ts +10 -0
  169. package/dist/types/lsp/config.d.ts +2 -2
  170. package/dist/types/lsp/edits.d.ts +9 -0
  171. package/dist/types/lsp/format-options.d.ts +32 -0
  172. package/dist/types/lsp/index.d.ts +2 -7
  173. package/dist/types/lsp/types.d.ts +13 -1
  174. package/dist/types/lsp/utils.d.ts +6 -2
  175. package/dist/types/main.d.ts +23 -8
  176. package/dist/types/mcp/json-rpc.d.ts +5 -0
  177. package/dist/types/mcp/manager.d.ts +8 -0
  178. package/dist/types/mcp/oauth-discovery.d.ts +6 -1
  179. package/dist/types/mcp/oauth-flow.d.ts +13 -3
  180. package/dist/types/mcp/startup-events.d.ts +11 -0
  181. package/dist/types/mcp/tool-bridge.d.ts +2 -0
  182. package/dist/types/mcp/transports/stdio.d.ts +13 -0
  183. package/dist/types/mcp/types.d.ts +2 -0
  184. package/dist/types/memories/index.d.ts +7 -15
  185. package/dist/types/memories/storage.d.ts +0 -10
  186. package/dist/types/memory-backend/index.d.ts +3 -1
  187. package/dist/types/memory-backend/local-backend.d.ts +4 -3
  188. package/dist/types/memory-backend/resolve.d.ts +2 -2
  189. package/dist/types/memory-backend/runtime.d.ts +4 -0
  190. package/dist/types/memory-backend/types.d.ts +67 -2
  191. package/dist/types/mnemopi/config.d.ts +31 -1
  192. package/dist/types/mnemopi/state.d.ts +40 -2
  193. package/dist/types/modes/acp/acp-agent.d.ts +1 -2
  194. package/dist/types/modes/components/agent-dashboard.d.ts +17 -1
  195. package/dist/types/modes/components/agent-hub.d.ts +82 -0
  196. package/dist/types/modes/components/assistant-message.d.ts +5 -12
  197. package/dist/types/modes/components/bash-execution.d.ts +1 -1
  198. package/dist/types/modes/components/chat-block.d.ts +64 -0
  199. package/dist/types/modes/components/collab-prompt-message.d.ts +10 -0
  200. package/dist/types/modes/components/compaction-summary-message.d.ts +25 -5
  201. package/dist/types/modes/components/copy-selector.d.ts +1 -1
  202. package/dist/types/modes/components/custom-editor.d.ts +49 -2
  203. package/dist/types/modes/components/custom-editor.test.d.ts +1 -0
  204. package/dist/types/modes/components/dynamic-border.d.ts +1 -1
  205. package/dist/types/modes/components/extensions/extension-dashboard.d.ts +1 -1
  206. package/dist/types/modes/components/extensions/extension-list.d.ts +1 -1
  207. package/dist/types/modes/components/extensions/inspector-panel.d.ts +1 -1
  208. package/dist/types/modes/components/footer.d.ts +1 -1
  209. package/dist/types/modes/components/hook-editor.d.ts +5 -0
  210. package/dist/types/modes/components/hook-input.d.ts +4 -0
  211. package/dist/types/modes/components/hook-selector.d.ts +5 -7
  212. package/dist/types/modes/components/index.d.ts +1 -0
  213. package/dist/types/modes/components/late-diagnostics-message.d.ts +20 -0
  214. package/dist/types/modes/components/logout-account-selector.d.ts +8 -0
  215. package/dist/types/modes/components/mcp-add-wizard.d.ts +2 -1
  216. package/dist/types/modes/components/model-selector.d.ts +1 -1
  217. package/dist/types/modes/components/oauth-selector.d.ts +10 -1
  218. package/dist/types/modes/components/overlay-box.d.ts +17 -0
  219. package/dist/types/modes/components/plan-review-overlay.d.ts +61 -0
  220. package/dist/types/modes/components/plan-toc.d.ts +41 -0
  221. package/dist/types/modes/components/read-tool-group.d.ts +8 -0
  222. package/dist/types/modes/components/reset-usage-selector.d.ts +12 -0
  223. package/dist/types/modes/components/segment-track.d.ts +11 -6
  224. package/dist/types/modes/components/session-selector.d.ts +18 -9
  225. package/dist/types/modes/components/settings-defs.d.ts +9 -2
  226. package/dist/types/modes/components/settings-selector.d.ts +17 -4
  227. package/dist/types/modes/components/snapcompact-shape-preview.d.ts +31 -0
  228. package/dist/types/modes/components/status-line/component.d.ts +61 -0
  229. package/dist/types/modes/components/status-line/index.d.ts +1 -0
  230. package/dist/types/modes/components/status-line/types.d.ts +47 -3
  231. package/dist/types/modes/components/tiny-title-download-progress.d.ts +1 -1
  232. package/dist/types/modes/components/tool-execution.d.ts +49 -2
  233. package/dist/types/modes/components/transcript-container.d.ts +76 -26
  234. package/dist/types/modes/components/tree-selector.d.ts +2 -2
  235. package/dist/types/modes/components/ttsr-notification.d.ts +5 -1
  236. package/dist/types/modes/components/usage-row.d.ts +3 -0
  237. package/dist/types/modes/components/user-message-selector.d.ts +1 -1
  238. package/dist/types/modes/components/user-message.d.ts +2 -1
  239. package/dist/types/modes/components/visual-truncate.d.ts +1 -1
  240. package/dist/types/modes/components/welcome.d.ts +12 -2
  241. package/dist/types/modes/controllers/command-controller.d.ts +3 -2
  242. package/dist/types/modes/controllers/event-controller.d.ts +7 -1
  243. package/dist/types/modes/controllers/extension-ui-controller.d.ts +0 -1
  244. package/dist/types/modes/controllers/input-controller.d.ts +25 -3
  245. package/dist/types/modes/controllers/mcp-command-controller.d.ts +8 -0
  246. package/dist/types/modes/controllers/selector-controller.d.ts +5 -2
  247. package/dist/types/modes/controllers/session-focus-controller.d.ts +31 -0
  248. package/dist/types/modes/controllers/streaming-reveal.d.ts +22 -0
  249. package/dist/types/modes/controllers/tan-command-controller.d.ts +6 -0
  250. package/dist/types/modes/controllers/tool-args-reveal.d.ts +43 -0
  251. package/dist/types/modes/gradient-highlight.d.ts +9 -4
  252. package/dist/types/modes/image-references.d.ts +14 -3
  253. package/dist/types/modes/index.d.ts +8 -7
  254. package/dist/types/modes/interactive-mode.d.ts +92 -16
  255. package/dist/types/modes/magic-keywords.d.ts +14 -2
  256. package/dist/types/modes/markdown-prose.d.ts +1 -1
  257. package/dist/types/modes/oauth-manual-input.d.ts +7 -0
  258. package/dist/types/modes/rpc/rpc-client.d.ts +48 -2
  259. package/dist/types/modes/rpc/rpc-mode.d.ts +67 -2
  260. package/dist/types/modes/rpc/rpc-subagents.d.ts +24 -0
  261. package/dist/types/modes/rpc/rpc-types.d.ts +113 -1
  262. package/dist/types/modes/runtime-init.d.ts +4 -0
  263. package/dist/types/modes/session-observer-registry.d.ts +9 -0
  264. package/dist/types/modes/setup-version.d.ts +11 -0
  265. package/dist/types/modes/setup-wizard/index.d.ts +7 -2
  266. package/dist/types/modes/setup-wizard/lazy.d.ts +2 -0
  267. package/dist/types/modes/setup-wizard/scenes/sign-in.d.ts +4 -1
  268. package/dist/types/modes/setup-wizard/scenes/types.d.ts +11 -2
  269. package/dist/types/modes/setup-wizard/scenes/web-search.d.ts +6 -2
  270. package/dist/types/modes/setup-wizard/wizard-overlay.d.ts +1 -1
  271. package/dist/types/modes/theme/theme.d.ts +42 -7
  272. package/dist/types/modes/types.d.ts +62 -13
  273. package/dist/types/modes/utils/context-usage.d.ts +6 -1
  274. package/dist/types/modes/utils/copy-targets.d.ts +21 -1
  275. package/dist/types/modes/utils/ui-helpers.d.ts +4 -4
  276. package/dist/types/modes/workflow.d.ts +3 -3
  277. package/dist/types/plan-mode/approved-plan.d.ts +27 -8
  278. package/dist/types/plan-mode/plan-protection.d.ts +4 -4
  279. package/dist/types/registry/agent-lifecycle.d.ts +51 -0
  280. package/dist/types/registry/agent-registry.d.ts +33 -5
  281. package/dist/types/sdk.d.ts +46 -4
  282. package/dist/types/secrets/index.d.ts +1 -1
  283. package/dist/types/secrets/obfuscator.d.ts +9 -3
  284. package/dist/types/session/agent-session.d.ts +136 -66
  285. package/dist/types/session/agent-storage.d.ts +2 -1
  286. package/dist/types/session/auth-broker-config.d.ts +4 -0
  287. package/dist/types/session/auth-storage.d.ts +1 -1
  288. package/dist/types/session/codex-auto-reset.d.ts +111 -0
  289. package/dist/types/session/indexed-session-storage.d.ts +3 -3
  290. package/dist/types/session/messages.d.ts +26 -15
  291. package/dist/types/session/session-context.d.ts +39 -0
  292. package/dist/types/session/session-entries.d.ts +159 -0
  293. package/dist/types/session/session-history-format.d.ts +12 -0
  294. package/dist/types/session/session-listing.d.ts +69 -0
  295. package/dist/types/session/session-loader.d.ts +16 -0
  296. package/dist/types/session/session-manager.d.ts +107 -440
  297. package/dist/types/session/session-migrations.d.ts +12 -0
  298. package/dist/types/session/session-paths.d.ts +25 -0
  299. package/dist/types/session/session-persistence.d.ts +8 -0
  300. package/dist/types/session/session-storage.d.ts +11 -7
  301. package/dist/types/session/snapcompact-inline.d.ts +145 -0
  302. package/dist/types/session/snapcompact-savings-journal.d.ts +46 -0
  303. package/dist/types/session/streaming-output.d.ts +46 -0
  304. package/dist/types/session/tool-choice-queue.d.ts +6 -6
  305. package/dist/types/session/yield-queue.d.ts +10 -1
  306. package/dist/types/slash-commands/acp-builtins.d.ts +16 -0
  307. package/dist/types/slash-commands/available-commands.d.ts +34 -0
  308. package/dist/types/slash-commands/builtin-registry.d.ts +10 -0
  309. package/dist/types/slash-commands/helpers/active-oauth-account.d.ts +14 -0
  310. package/dist/types/slash-commands/helpers/logout.d.ts +15 -0
  311. package/dist/types/slash-commands/helpers/reset-usage.d.ts +27 -0
  312. package/dist/types/slash-commands/helpers/stats-dashboard.d.ts +13 -0
  313. package/dist/types/slash-commands/types.d.ts +5 -9
  314. package/dist/types/ssh/connection-manager.d.ts +8 -0
  315. package/dist/types/stt/asr-client.d.ts +90 -0
  316. package/dist/types/stt/asr-protocol.d.ts +97 -0
  317. package/dist/types/stt/asr-worker.d.ts +2 -0
  318. package/dist/types/stt/downloader.d.ts +38 -0
  319. package/dist/types/stt/endpointer.d.ts +59 -0
  320. package/dist/types/stt/index.d.ts +5 -1
  321. package/dist/types/stt/models.d.ts +120 -0
  322. package/dist/types/stt/recorder.d.ts +17 -0
  323. package/dist/types/stt/stt-controller.d.ts +6 -0
  324. package/dist/types/stt/transcriber.d.ts +5 -7
  325. package/dist/types/stt/wav.d.ts +29 -0
  326. package/dist/types/system-prompt.d.ts +9 -1
  327. package/dist/types/task/commands.d.ts +1 -1
  328. package/dist/types/task/discovery.d.ts +1 -2
  329. package/dist/types/task/executor.d.ts +61 -2
  330. package/dist/types/task/index.d.ts +37 -6
  331. package/dist/types/task/output-manager.d.ts +0 -7
  332. package/dist/types/task/parallel.d.ts +2 -2
  333. package/dist/types/task/prometheus-command.d.ts +2 -2
  334. package/dist/types/task/render.d.ts +20 -7
  335. package/dist/types/task/repair-args.d.ts +8 -7
  336. package/dist/types/task/types.d.ts +109 -52
  337. package/dist/types/task/worktree.d.ts +2 -0
  338. package/dist/types/telemetry-export.d.ts +2 -2
  339. package/dist/types/thinking.d.ts +4 -0
  340. package/dist/types/tiny/models.d.ts +1 -1
  341. package/dist/types/tiny/title-client.d.ts +12 -1
  342. package/dist/types/tiny/title-protocol.d.ts +1 -0
  343. package/dist/types/tools/archive-reader.d.ts +5 -0
  344. package/dist/types/tools/ask.d.ts +6 -1
  345. package/dist/types/tools/ast-edit.d.ts +4 -1
  346. package/dist/types/tools/ast-grep.d.ts +4 -1
  347. package/dist/types/tools/bash.d.ts +5 -2
  348. package/dist/types/tools/browser/attach.d.ts +4 -4
  349. package/dist/types/tools/browser/cmux/cmux-tab.d.ts +202 -0
  350. package/dist/types/tools/browser/cmux/rpc.d.ts +70 -0
  351. package/dist/types/tools/browser/cmux/socket-client.d.ts +19 -0
  352. package/dist/types/tools/browser/registry.d.ts +17 -3
  353. package/dist/types/tools/browser/render.d.ts +2 -0
  354. package/dist/types/tools/browser/tab-protocol.d.ts +2 -0
  355. package/dist/types/tools/browser/tab-supervisor.d.ts +16 -4
  356. package/dist/types/tools/browser/tab-worker.d.ts +18 -1
  357. package/dist/types/tools/browser.d.ts +3 -1
  358. package/dist/types/tools/checkpoint.d.ts +1 -1
  359. package/dist/types/tools/conflict-detect.d.ts +16 -0
  360. package/dist/types/tools/debug.d.ts +1 -1
  361. package/dist/types/tools/eval-render.d.ts +1 -8
  362. package/dist/types/tools/eval.d.ts +9 -1
  363. package/dist/types/tools/fetch.d.ts +17 -8
  364. package/dist/types/tools/find.d.ts +1 -8
  365. package/dist/types/tools/gh-cache-invalidation.d.ts +6 -0
  366. package/dist/types/tools/gh.d.ts +4 -1
  367. package/dist/types/tools/github-cache.d.ts +19 -0
  368. package/dist/types/tools/grouped-file-output.d.ts +46 -12
  369. package/dist/types/tools/image-gen.d.ts +1 -1
  370. package/dist/types/tools/index.d.ts +89 -8
  371. package/dist/types/tools/inspect-image.d.ts +1 -1
  372. package/dist/types/tools/irc.d.ts +79 -39
  373. package/dist/types/tools/job.d.ts +8 -2
  374. package/dist/types/tools/learn.d.ts +51 -0
  375. package/dist/types/tools/manage-skill.d.ts +40 -0
  376. package/dist/types/tools/memory-edit.d.ts +2 -2
  377. package/dist/types/tools/memory-recall.d.ts +1 -1
  378. package/dist/types/tools/memory-reflect.d.ts +1 -1
  379. package/dist/types/tools/memory-render.d.ts +4 -1
  380. package/dist/types/tools/memory-retain.d.ts +1 -1
  381. package/dist/types/tools/path-utils.d.ts +17 -5
  382. package/dist/types/tools/plan-mode-guard.d.ts +18 -9
  383. package/dist/types/tools/read.d.ts +3 -2
  384. package/dist/types/tools/render-mermaid.d.ts +1 -1
  385. package/dist/types/tools/render-utils.d.ts +47 -27
  386. package/dist/types/tools/renderers.d.ts +10 -2
  387. package/dist/types/tools/report-tool-issue.d.ts +6 -1
  388. package/dist/types/tools/resolve.d.ts +1 -1
  389. package/dist/types/tools/review.d.ts +1 -1
  390. package/dist/types/tools/search-tool-bm25.d.ts +1 -1
  391. package/dist/types/tools/search.d.ts +7 -3
  392. package/dist/types/tools/sqlite-reader.d.ts +4 -0
  393. package/dist/types/tools/ssh.d.ts +2 -1
  394. package/dist/types/tools/todo.d.ts +7 -15
  395. package/dist/types/tools/tool-result.d.ts +2 -0
  396. package/dist/types/tools/tool-timeouts.d.ts +1 -1
  397. package/dist/types/tools/tts.d.ts +26 -1
  398. package/dist/types/tools/write.d.ts +6 -3
  399. package/dist/types/tools/yield.d.ts +8 -0
  400. package/dist/types/tts/downloader.d.ts +20 -0
  401. package/dist/types/tts/index.d.ts +8 -0
  402. package/dist/types/tts/models.d.ts +82 -0
  403. package/dist/types/tts/player.d.ts +32 -0
  404. package/dist/types/tts/runtime.d.ts +6 -0
  405. package/dist/types/tts/streaming-player.d.ts +41 -0
  406. package/dist/types/tts/tts-client.d.ts +93 -0
  407. package/dist/types/tts/tts-protocol.d.ts +95 -0
  408. package/dist/types/tts/tts-worker.d.ts +2 -0
  409. package/dist/types/tts/vocalizer.d.ts +41 -0
  410. package/dist/types/tts/wav.d.ts +8 -0
  411. package/dist/types/tui/code-cell.d.ts +0 -2
  412. package/dist/types/tui/hyperlink.d.ts +13 -7
  413. package/dist/types/tui/output-block.d.ts +16 -22
  414. package/dist/types/tui/status-line.d.ts +3 -0
  415. package/dist/types/utils/block-context.d.ts +35 -0
  416. package/dist/types/utils/changelog.d.ts +8 -0
  417. package/dist/types/utils/clipboard.d.ts +4 -3
  418. package/dist/types/utils/enhanced-paste.d.ts +20 -0
  419. package/dist/types/utils/file-mentions.d.ts +7 -0
  420. package/dist/types/utils/git.d.ts +22 -3
  421. package/dist/types/utils/image-loading.d.ts +30 -1
  422. package/dist/types/utils/session-color.d.ts +15 -3
  423. package/dist/types/utils/thinking-display.d.ts +17 -0
  424. package/dist/types/utils/title-generator.d.ts +3 -2
  425. package/dist/types/utils/tool-choice.d.ts +8 -0
  426. package/dist/types/utils/tools-manager.d.ts +2 -1
  427. package/dist/types/web/kagi.d.ts +2 -2
  428. package/dist/types/web/parallel.d.ts +3 -0
  429. package/dist/types/web/scrapers/github.d.ts +22 -0
  430. package/dist/types/web/scrapers/readthedocs.d.ts +3 -0
  431. package/dist/types/web/scrapers/types.d.ts +12 -0
  432. package/dist/types/web/search/index.d.ts +1 -1
  433. package/dist/types/web/search/providers/anthropic.d.ts +2 -1
  434. package/dist/types/web/search/providers/base.d.ts +2 -1
  435. package/dist/types/web/search/providers/brave.d.ts +2 -1
  436. package/dist/types/web/search/providers/codex.d.ts +2 -1
  437. package/dist/types/web/search/providers/exa.d.ts +2 -1
  438. package/dist/types/web/search/providers/gemini.d.ts +10 -6
  439. package/dist/types/web/search/providers/jina.d.ts +7 -2
  440. package/dist/types/web/search/providers/kagi.d.ts +7 -2
  441. package/dist/types/web/search/providers/kimi.d.ts +7 -2
  442. package/dist/types/web/search/providers/parallel.d.ts +2 -1
  443. package/dist/types/web/search/providers/perplexity.d.ts +10 -2
  444. package/dist/types/web/search/providers/searxng.d.ts +2 -1
  445. package/dist/types/web/search/providers/synthetic.d.ts +7 -3
  446. package/dist/types/web/search/providers/tavily.d.ts +2 -1
  447. package/dist/types/web/search/providers/zai.d.ts +2 -1
  448. package/dist/types/web/search/types.d.ts +1 -1
  449. package/examples/extensions/api-demo.ts +2 -2
  450. package/package.json +41 -15
  451. package/scripts/bench-guard.ts +71 -0
  452. package/scripts/build-binary.ts +24 -25
  453. package/scripts/bundle-dist.ts +97 -0
  454. package/scripts/generate-share-viewer.ts +34 -0
  455. package/scripts/prometheus +42 -0
  456. package/scripts/prometheus.ts +20 -0
  457. package/src/async/index.ts +0 -1
  458. package/src/async/job-manager.ts +106 -3
  459. package/src/auto-thinking/classifier.ts +2 -1
  460. package/src/autolearn/controller.ts +139 -0
  461. package/src/autolearn/managed-skills.ts +257 -0
  462. package/src/autoresearch/dashboard.ts +1 -1
  463. package/src/autoresearch/prompt-setup.md +6 -6
  464. package/src/autoresearch/prompt.md +6 -6
  465. package/src/autoresearch/state.ts +1 -1
  466. package/src/autoresearch/storage.ts +2 -1
  467. package/src/autoresearch/tools/init-experiment.ts +1 -1
  468. package/src/autoresearch/tools/log-experiment.ts +1 -1
  469. package/src/autoresearch/tools/run-experiment.ts +1 -1
  470. package/src/autoresearch/tools/update-notes.ts +1 -1
  471. package/src/autoresearch/types.ts +1 -1
  472. package/src/capability/context-file.ts +0 -14
  473. package/src/capability/fs.ts +10 -0
  474. package/src/capability/index.ts +1 -6
  475. package/src/capability/mcp.ts +1 -0
  476. package/src/capability/rule-buckets.ts +4 -2
  477. package/src/capability/rule.ts +10 -1
  478. package/src/capability/types.ts +0 -4
  479. package/src/cli/args.ts +66 -13
  480. package/src/cli/auth-broker-cli.ts +6 -7
  481. package/src/cli/auth-gateway-cli.ts +8 -9
  482. package/src/cli/bench-cli.ts +437 -0
  483. package/src/cli/claude-trace-cli.ts +28 -50
  484. package/src/cli/completion-gen.ts +28 -28
  485. package/src/cli/dry-balance-cli.ts +56 -23
  486. package/src/cli/gallery-cli.ts +231 -0
  487. package/src/cli/gallery-fixtures/agentic.ts +407 -0
  488. package/src/cli/gallery-fixtures/codeintel.ts +187 -0
  489. package/src/cli/gallery-fixtures/edit.ts +194 -0
  490. package/src/cli/gallery-fixtures/fs.ts +220 -0
  491. package/src/cli/gallery-fixtures/index.ts +40 -0
  492. package/src/cli/gallery-fixtures/interaction.ts +49 -0
  493. package/src/cli/gallery-fixtures/memory.ts +81 -0
  494. package/src/cli/gallery-fixtures/misc.ts +250 -0
  495. package/src/cli/gallery-fixtures/search.ts +213 -0
  496. package/src/cli/gallery-fixtures/shell.ts +167 -0
  497. package/src/cli/gallery-fixtures/types.ts +57 -0
  498. package/src/cli/gallery-fixtures/web.ts +158 -0
  499. package/src/cli/gallery-screenshot.ts +279 -0
  500. package/src/cli/grievances-cli.ts +1 -1
  501. package/src/cli/list-models.ts +16 -174
  502. package/src/cli/models-cli.ts +429 -0
  503. package/src/cli/session-picker.ts +2 -1
  504. package/src/cli/setup-cli.ts +148 -47
  505. package/src/cli/setup-model-picker.ts +43 -0
  506. package/src/cli/startup-cwd.ts +68 -0
  507. package/src/cli/update-cli.ts +144 -272
  508. package/src/cli/usage-cli.ts +774 -0
  509. package/src/cli-commands.ts +36 -0
  510. package/src/cli.ts +141 -32
  511. package/src/collab/crypto.ts +63 -0
  512. package/src/collab/guest.ts +451 -0
  513. package/src/collab/host.ts +565 -0
  514. package/src/collab/protocol.ts +241 -0
  515. package/src/collab/relay-client.ts +216 -0
  516. package/src/commands/bench.ts +42 -0
  517. package/src/commands/complete.ts +1 -1
  518. package/src/commands/gallery.ts +52 -0
  519. package/src/commands/install.ts +1 -1
  520. package/src/commands/join.ts +39 -0
  521. package/src/commands/launch.ts +8 -4
  522. package/src/commands/models.ts +61 -0
  523. package/src/commands/read.ts +6 -3
  524. package/src/commands/say.ts +102 -0
  525. package/src/commands/setup.ts +1 -1
  526. package/src/commands/token.ts +89 -0
  527. package/src/commands/usage.ts +43 -0
  528. package/src/commit/agentic/agent.ts +2 -1
  529. package/src/commit/agentic/tools/analyze-file.ts +42 -20
  530. package/src/commit/agentic/tools/git-file-diff.ts +1 -1
  531. package/src/commit/agentic/tools/git-hunk.ts +1 -1
  532. package/src/commit/agentic/tools/git-overview.ts +1 -1
  533. package/src/commit/agentic/tools/propose-changelog.ts +1 -1
  534. package/src/commit/agentic/tools/propose-commit.ts +1 -1
  535. package/src/commit/agentic/tools/recent-commits.ts +1 -1
  536. package/src/commit/agentic/tools/schemas.ts +1 -1
  537. package/src/commit/agentic/tools/split-commit.ts +9 -2
  538. package/src/commit/analysis/conventional.ts +2 -2
  539. package/src/commit/analysis/summary.ts +3 -3
  540. package/src/commit/changelog/generate.ts +3 -3
  541. package/src/commit/changelog/index.ts +2 -2
  542. package/src/commit/map-reduce/index.ts +3 -3
  543. package/src/commit/map-reduce/map-phase.ts +2 -2
  544. package/src/commit/map-reduce/reduce-phase.ts +2 -2
  545. package/src/commit/model-selection.ts +35 -12
  546. package/src/commit/pipeline.ts +4 -4
  547. package/src/commit/shared-llm.ts +1 -1
  548. package/src/config/api-key-resolver.ts +67 -0
  549. package/src/config/append-only-context-mode.ts +6 -12
  550. package/src/config/keybindings.ts +9 -4
  551. package/src/config/mcp-schema.json +4 -0
  552. package/src/config/model-discovery.ts +574 -0
  553. package/src/config/model-equivalence.ts +5 -4
  554. package/src/config/model-registry.ts +659 -1093
  555. package/src/config/model-resolver.ts +374 -174
  556. package/src/config/model-roles.ts +88 -0
  557. package/src/config/models-config-schema.ts +61 -9
  558. package/src/config/models-config.ts +130 -0
  559. package/src/config/settings-schema.ts +1441 -387
  560. package/src/config/settings.ts +261 -69
  561. package/src/dap/client.ts +138 -53
  562. package/src/dap/config.ts +41 -2
  563. package/src/dap/defaults.json +1 -0
  564. package/src/dap/session.ts +263 -161
  565. package/src/dap/types.ts +10 -0
  566. package/src/debug/index.ts +50 -60
  567. package/src/debug/log-viewer.ts +1 -1
  568. package/src/debug/protocol-probe.ts +1 -1
  569. package/src/debug/raw-sse-buffer.ts +7 -4
  570. package/src/debug/raw-sse.ts +1 -1
  571. package/src/debug/report-bundle.ts +9 -0
  572. package/src/debug/terminal-info.ts +0 -3
  573. package/src/discovery/agents-md.ts +25 -21
  574. package/src/discovery/agents.ts +9 -15
  575. package/src/discovery/at-imports.ts +273 -0
  576. package/src/discovery/builtin-rules/index.ts +4 -0
  577. package/src/discovery/builtin-rules/ts-no-test-timers.md +55 -0
  578. package/src/discovery/builtin-rules/ts-redundant-clear-guard.md +75 -0
  579. package/src/discovery/builtin.ts +45 -23
  580. package/src/discovery/claude-plugins.ts +44 -5
  581. package/src/discovery/helpers.ts +50 -9
  582. package/src/discovery/prometheus-extension-roots.ts +10 -10
  583. package/src/discovery/prometheus-plugins.ts +10 -10
  584. package/src/edit/diff.ts +191 -4
  585. package/src/edit/file-snapshot-store.ts +34 -1
  586. package/src/edit/hashline/block-resolver.ts +20 -1
  587. package/src/edit/hashline/diff.ts +123 -2
  588. package/src/edit/hashline/execute.ts +60 -4
  589. package/src/edit/hashline/filesystem.ts +2 -1
  590. package/src/edit/hashline/noop-loop-guard.ts +99 -0
  591. package/src/edit/hashline/params.ts +1 -1
  592. package/src/edit/index.ts +47 -18
  593. package/src/edit/modes/apply-patch.ts +1 -1
  594. package/src/edit/modes/patch.ts +59 -3
  595. package/src/edit/modes/replace.ts +58 -24
  596. package/src/edit/notebook.ts +22 -2
  597. package/src/edit/renderer.ts +315 -151
  598. package/src/eval/__tests__/agent-bridge.test.ts +105 -39
  599. package/src/eval/__tests__/budget-bridge.test.ts +1 -1
  600. package/src/eval/__tests__/completion-bridge.test.ts +412 -0
  601. package/src/eval/__tests__/helpers-local-roots.test.ts +58 -0
  602. package/src/eval/__tests__/js-context-manager.test.ts +241 -0
  603. package/src/eval/__tests__/llm-bridge.test.ts +6 -4
  604. package/src/eval/__tests__/shared-executors.test.ts +34 -92
  605. package/src/eval/agent-bridge.ts +39 -23
  606. package/src/eval/backend.ts +15 -2
  607. package/src/eval/bridge-timeout.ts +1 -1
  608. package/src/eval/completion-bridge.ts +203 -0
  609. package/src/eval/idle-timeout.ts +3 -10
  610. package/src/eval/js/context-manager.ts +108 -31
  611. package/src/eval/js/executor.ts +9 -2
  612. package/src/eval/js/index.ts +7 -3
  613. package/src/eval/js/shared/helpers.ts +59 -13
  614. package/src/eval/js/shared/local-module-loader.ts +2 -2
  615. package/src/eval/js/shared/prelude.txt +167 -30
  616. package/src/eval/js/shared/rewrite-imports.ts +58 -34
  617. package/src/eval/js/shared/runtime.ts +24 -16
  618. package/src/eval/js/tool-bridge.ts +4 -0
  619. package/src/eval/js/worker-core.ts +1 -0
  620. package/src/eval/js/worker-entry.ts +6 -0
  621. package/src/eval/js/worker-protocol.ts +6 -0
  622. package/src/eval/llm-bridge.ts +2 -1
  623. package/src/eval/py/__tests__/prelude.test.ts +19 -0
  624. package/src/eval/py/executor.ts +70 -26
  625. package/src/eval/py/index.ts +13 -4
  626. package/src/eval/py/kernel.ts +48 -9
  627. package/src/eval/py/prelude.py +73 -24
  628. package/src/eval/py/runner.py +133 -28
  629. package/src/eval/py/runtime.ts +38 -1
  630. package/src/exa/index.ts +1 -26
  631. package/src/exa/mcp-client.ts +10 -10
  632. package/src/exa/types.ts +0 -97
  633. package/src/exec/bash-executor.ts +104 -7
  634. package/src/export/custom-share.ts +1 -1
  635. package/src/export/html/index.ts +119 -17
  636. package/src/export/html/share-loader.js +102 -0
  637. package/src/export/html/template-js.ts +6 -0
  638. package/src/export/html/template.css +745 -459
  639. package/src/export/html/template.css.d.ts +2 -0
  640. package/src/export/html/template.html +6 -3
  641. package/src/export/html/template.js +277 -891
  642. package/src/export/html/tool-views.generated.d.ts +2 -0
  643. package/src/export/html/tool-views.generated.js +38 -0
  644. package/src/export/share.ts +269 -0
  645. package/src/export/ttsr.ts +122 -1
  646. package/src/extensibility/custom-commands/loader.ts +7 -4
  647. package/src/extensibility/custom-commands/types.ts +9 -4
  648. package/src/extensibility/custom-tools/loader.ts +51 -23
  649. package/src/extensibility/custom-tools/types.ts +16 -8
  650. package/src/extensibility/extensions/get-commands-handler.ts +2 -1
  651. package/src/extensibility/extensions/index.ts +1 -0
  652. package/src/extensibility/extensions/loader.ts +70 -20
  653. package/src/extensibility/extensions/model-api.ts +41 -0
  654. package/src/extensibility/extensions/runner.ts +12 -2
  655. package/src/extensibility/extensions/types.ts +83 -11
  656. package/src/extensibility/extensions/wrapper.ts +41 -5
  657. package/src/extensibility/hooks/index.ts +2 -1
  658. package/src/extensibility/hooks/loader.ts +6 -3
  659. package/src/extensibility/hooks/types.ts +11 -5
  660. package/src/extensibility/{legacy-pi-ai-shim.ts → legacy-package-ai-shim.ts} +2 -2
  661. package/src/extensibility/plugins/doctor.ts +1 -2
  662. package/src/extensibility/plugins/installer.ts +2 -2
  663. package/src/extensibility/plugins/{legacy-pi-compat.ts → legacy-package-compat.ts} +165 -77
  664. package/src/extensibility/plugins/loader.ts +34 -23
  665. package/src/extensibility/plugins/manager.ts +226 -95
  666. package/src/extensibility/plugins/marketplace-auto-update.ts +49 -0
  667. package/src/extensibility/plugins/types.ts +3 -3
  668. package/src/extensibility/shared-events.ts +3 -3
  669. package/src/extensibility/skills.ts +113 -9
  670. package/src/extensibility/slash-commands.ts +1 -97
  671. package/src/goals/guided-setup.ts +133 -0
  672. package/src/goals/state.ts +1 -1
  673. package/src/goals/tools/goal-tool.ts +38 -28
  674. package/src/hindsight/bank.ts +17 -2
  675. package/src/hindsight/client.ts +27 -2
  676. package/src/hindsight/mental-models.ts +59 -12
  677. package/src/hindsight/state.ts +12 -3
  678. package/src/hindsight/transcript.ts +1 -1
  679. package/src/index.ts +5 -0
  680. package/src/internal-urls/artifact-protocol.ts +11 -2
  681. package/src/internal-urls/docs-index.generated.ts +9 -7
  682. package/src/internal-urls/history-protocol.ts +113 -0
  683. package/src/internal-urls/index.ts +1 -0
  684. package/src/internal-urls/issue-pr-protocol.ts +22 -9
  685. package/src/internal-urls/local-protocol.ts +42 -7
  686. package/src/internal-urls/memory-protocol.ts +4 -31
  687. package/src/internal-urls/router.ts +3 -1
  688. package/src/internal-urls/types.ts +1 -1
  689. package/src/irc/bus.ts +303 -0
  690. package/src/lib/xai-http.ts +3 -3
  691. package/src/lsp/client.ts +245 -104
  692. package/src/lsp/clients/biome-client.ts +101 -39
  693. package/src/lsp/clients/lsp-linter-client.ts +2 -10
  694. package/src/lsp/config.ts +15 -5
  695. package/src/lsp/defaults.json +6 -0
  696. package/src/lsp/edits.ts +143 -95
  697. package/src/lsp/format-options.ts +119 -0
  698. package/src/lsp/index.ts +233 -93
  699. package/src/lsp/render.ts +11 -35
  700. package/src/lsp/types.ts +13 -1
  701. package/src/lsp/utils.ts +31 -12
  702. package/src/main.ts +396 -216
  703. package/src/mcp/config-writer.ts +7 -3
  704. package/src/mcp/json-rpc.ts +35 -5
  705. package/src/mcp/manager.ts +31 -16
  706. package/src/mcp/oauth-discovery.ts +34 -4
  707. package/src/mcp/oauth-flow.ts +61 -8
  708. package/src/mcp/render.ts +7 -1
  709. package/src/mcp/startup-events.ts +21 -0
  710. package/src/mcp/tool-bridge.ts +2 -0
  711. package/src/mcp/transports/stdio.ts +224 -4
  712. package/src/mcp/types.ts +2 -0
  713. package/src/memories/index.ts +174 -1128
  714. package/src/memories/storage.ts +2 -41
  715. package/src/memory-backend/index.ts +14 -1
  716. package/src/memory-backend/local-backend.ts +18 -3
  717. package/src/memory-backend/off-backend.ts +9 -0
  718. package/src/memory-backend/resolve.ts +4 -6
  719. package/src/memory-backend/runtime.ts +66 -0
  720. package/src/memory-backend/types.ts +82 -2
  721. package/src/mnemopi/backend.ts +220 -28
  722. package/src/mnemopi/config.ts +138 -33
  723. package/src/mnemopi/state.ts +91 -11
  724. package/src/modes/acp/acp-agent.ts +149 -142
  725. package/src/modes/acp/acp-event-mapper.ts +5 -1
  726. package/src/modes/components/agent-dashboard.ts +17 -11
  727. package/src/modes/components/agent-hub.ts +1346 -0
  728. package/src/modes/components/assistant-message.ts +190 -80
  729. package/src/modes/components/bash-execution.ts +1 -1
  730. package/src/modes/components/btw-panel.ts +5 -1
  731. package/src/modes/components/chat-block.ts +111 -0
  732. package/src/modes/components/collab-prompt-message.ts +30 -0
  733. package/src/modes/components/compaction-summary-message.ts +168 -33
  734. package/src/modes/components/copy-selector.ts +2 -45
  735. package/src/modes/components/custom-editor.test.ts +96 -0
  736. package/src/modes/components/custom-editor.ts +405 -118
  737. package/src/modes/components/custom-message.ts +1 -3
  738. package/src/modes/components/diff.ts +13 -2
  739. package/src/modes/components/dynamic-border.ts +12 -3
  740. package/src/modes/components/execution-shared.ts +1 -2
  741. package/src/modes/components/extensions/extension-dashboard.ts +8 -5
  742. package/src/modes/components/extensions/extension-list.ts +1 -1
  743. package/src/modes/components/extensions/inspector-panel.ts +7 -3
  744. package/src/modes/components/extensions/state-manager.ts +36 -41
  745. package/src/modes/components/footer.ts +4 -2
  746. package/src/modes/components/history-search.ts +1 -1
  747. package/src/modes/components/hook-editor.ts +8 -0
  748. package/src/modes/components/hook-input.ts +8 -0
  749. package/src/modes/components/hook-message.ts +1 -3
  750. package/src/modes/components/hook-selector.ts +6 -7
  751. package/src/modes/components/index.ts +1 -0
  752. package/src/modes/components/late-diagnostics-message.ts +60 -0
  753. package/src/modes/components/login-dialog.ts +1 -1
  754. package/src/modes/components/logout-account-selector.ts +130 -0
  755. package/src/modes/components/mcp-add-wizard.ts +14 -1
  756. package/src/modes/components/model-selector.ts +177 -75
  757. package/src/modes/components/oauth-selector.ts +102 -16
  758. package/src/modes/components/overlay-box.ts +108 -0
  759. package/src/modes/components/plan-review-overlay.ts +845 -0
  760. package/src/modes/components/plan-toc.ts +138 -0
  761. package/src/modes/components/plugin-settings.ts +22 -5
  762. package/src/modes/components/read-tool-group.ts +442 -39
  763. package/src/modes/components/reset-usage-selector.ts +161 -0
  764. package/src/modes/components/segment-track.ts +44 -7
  765. package/src/modes/components/session-selector.ts +97 -37
  766. package/src/modes/components/settings-defs.ts +28 -6
  767. package/src/modes/components/settings-selector.ts +541 -93
  768. package/src/modes/components/skill-message.ts +0 -1
  769. package/src/modes/components/snapcompact-shape-preview-doc.md +11 -0
  770. package/src/modes/components/snapcompact-shape-preview.ts +193 -0
  771. package/src/modes/components/{status-line.ts → status-line/component.ts} +205 -168
  772. package/src/modes/components/status-line/index.ts +1 -0
  773. package/src/modes/components/status-line/presets.ts +3 -3
  774. package/src/modes/components/status-line/segments.ts +26 -7
  775. package/src/modes/components/status-line/types.ts +40 -9
  776. package/src/modes/components/tiny-title-download-progress.ts +1 -1
  777. package/src/modes/components/tips.txt +7 -3
  778. package/src/modes/components/todo-reminder.ts +0 -2
  779. package/src/modes/components/tool-execution.ts +236 -103
  780. package/src/modes/components/transcript-container.ts +724 -99
  781. package/src/modes/components/tree-selector.ts +19 -4
  782. package/src/modes/components/ttsr-notification.ts +72 -30
  783. package/src/modes/components/usage-row.ts +18 -0
  784. package/src/modes/components/user-message-selector.ts +1 -1
  785. package/src/modes/components/user-message.ts +28 -12
  786. package/src/modes/components/visual-truncate.ts +1 -1
  787. package/src/modes/components/welcome.ts +80 -22
  788. package/src/modes/controllers/command-controller-shared.ts +7 -6
  789. package/src/modes/controllers/command-controller.ts +210 -180
  790. package/src/modes/controllers/event-controller.ts +352 -142
  791. package/src/modes/controllers/extension-ui-controller.ts +167 -208
  792. package/src/modes/controllers/input-controller.ts +778 -162
  793. package/src/modes/controllers/mcp-command-controller.ts +232 -80
  794. package/src/modes/controllers/selector-controller.ts +284 -145
  795. package/src/modes/controllers/session-focus-controller.ts +112 -0
  796. package/src/modes/controllers/ssh-command-controller.ts +2 -2
  797. package/src/modes/controllers/streaming-reveal.ts +295 -0
  798. package/src/modes/controllers/tan-command-controller.ts +173 -0
  799. package/src/modes/controllers/tool-args-reveal.ts +174 -0
  800. package/src/modes/gradient-highlight.ts +21 -9
  801. package/src/modes/image-references.ts +33 -7
  802. package/src/modes/index.ts +8 -25
  803. package/src/modes/interactive-mode.ts +840 -186
  804. package/src/modes/magic-keywords.ts +28 -6
  805. package/src/modes/markdown-prose.ts +1 -1
  806. package/src/modes/oauth-manual-input.ts +30 -3
  807. package/src/modes/rpc/rpc-client.ts +186 -3
  808. package/src/modes/rpc/rpc-mode.ts +318 -24
  809. package/src/modes/rpc/rpc-subagents.ts +265 -0
  810. package/src/modes/rpc/rpc-types.ts +111 -2
  811. package/src/modes/runtime-init.ts +28 -3
  812. package/src/modes/session-observer-registry.ts +72 -3
  813. package/src/modes/setup-version.ts +11 -0
  814. package/src/modes/setup-wizard/index.ts +16 -4
  815. package/src/modes/setup-wizard/lazy.ts +16 -0
  816. package/src/modes/setup-wizard/scenes/glyph.ts +25 -7
  817. package/src/modes/setup-wizard/scenes/providers.ts +45 -12
  818. package/src/modes/setup-wizard/scenes/sign-in.ts +14 -13
  819. package/src/modes/setup-wizard/scenes/splash.ts +1 -1
  820. package/src/modes/setup-wizard/scenes/theme.ts +29 -2
  821. package/src/modes/setup-wizard/scenes/types.ts +11 -2
  822. package/src/modes/setup-wizard/scenes/web-search.ts +26 -9
  823. package/src/modes/setup-wizard/wizard-overlay.ts +40 -3
  824. package/src/modes/shared.ts +2 -0
  825. package/src/modes/theme/defaults/dark-poimandres.json +1 -1
  826. package/src/modes/theme/defaults/light-poimandres.json +1 -1
  827. package/src/modes/theme/shimmer.ts +20 -9
  828. package/src/modes/theme/theme-schema.json +1 -1
  829. package/src/modes/theme/theme.ts +342 -82
  830. package/src/modes/types.ts +60 -18
  831. package/src/modes/utils/context-usage.ts +88 -8
  832. package/src/modes/utils/copy-targets.ts +133 -27
  833. package/src/modes/utils/hotkeys-markdown.ts +3 -2
  834. package/src/modes/utils/ui-helpers.ts +191 -110
  835. package/src/modes/workflow.ts +10 -10
  836. package/src/plan-mode/approved-plan.ts +66 -43
  837. package/src/plan-mode/plan-protection.ts +4 -4
  838. package/src/priority.json +5 -1
  839. package/src/prompts/agents/designer.md +1 -1
  840. package/src/prompts/agents/explore.md +3 -3
  841. package/src/prompts/agents/librarian.md +2 -3
  842. package/src/prompts/agents/oracle.md +2 -2
  843. package/src/prompts/agents/plan.md +6 -6
  844. package/src/prompts/agents/reviewer.md +1 -1
  845. package/src/prompts/agents/task.md +6 -5
  846. package/src/prompts/bench.md +12 -0
  847. package/src/prompts/ci-green-request.md +5 -7
  848. package/src/prompts/goals/goal-budget-limit.md +2 -2
  849. package/src/prompts/goals/goal-continuation.md +4 -4
  850. package/src/prompts/goals/goal-mode-active.md +1 -1
  851. package/src/prompts/goals/guided-goal-interview.md +8 -0
  852. package/src/prompts/goals/guided-goal-system.md +12 -0
  853. package/src/prompts/memories/consolidation.md +2 -7
  854. package/src/prompts/memories/consolidation_system.md +4 -0
  855. package/src/prompts/memories/identity_review.md +2 -2
  856. package/src/prompts/memories/read-path.md +11 -10
  857. package/src/prompts/memories/stage_one_system.md +2 -2
  858. package/src/prompts/review-custom-request.md +1 -1
  859. package/src/prompts/system/agent-creation-architect.md +2 -2
  860. package/src/prompts/system/auto-continue.md +1 -1
  861. package/src/prompts/system/autolearn-guidance-learn.md +1 -0
  862. package/src/prompts/system/autolearn-guidance.md +7 -0
  863. package/src/prompts/system/autolearn-nudge.md +3 -0
  864. package/src/prompts/system/background-tan-dispatch.md +8 -0
  865. package/src/prompts/system/btw-user.md +2 -2
  866. package/src/prompts/system/commit-message-system.md +13 -1
  867. package/src/prompts/system/custom-system-prompt.md +1 -1
  868. package/src/prompts/system/eager-task.md +7 -0
  869. package/src/prompts/system/eager-todo.md +11 -6
  870. package/src/prompts/system/empty-stop-retry.md +4 -6
  871. package/src/prompts/system/irc-autoreply.md +6 -0
  872. package/src/prompts/system/irc-incoming.md +3 -4
  873. package/src/prompts/system/manual-continue.md +7 -0
  874. package/src/prompts/system/omfg-user.md +3 -4
  875. package/src/prompts/system/orchestrate-notice.md +10 -10
  876. package/src/prompts/system/personalities/default.md +26 -0
  877. package/src/prompts/system/personalities/friendly.md +17 -0
  878. package/src/prompts/system/personalities/pragmatic.md +15 -0
  879. package/src/prompts/system/plan-mode-active.md +70 -77
  880. package/src/prompts/system/plan-mode-approved.md +1 -1
  881. package/src/prompts/system/plan-mode-subagent.md +4 -5
  882. package/src/prompts/system/plan-mode-tool-decision-reminder.md +1 -1
  883. package/src/prompts/system/project-prompt.md +2 -2
  884. package/src/prompts/system/snapcompact-context-frames-note.md +1 -0
  885. package/src/prompts/system/snapcompact-context-stub.md +1 -0
  886. package/src/prompts/system/snapcompact-system-frames-note.md +1 -0
  887. package/src/prompts/system/snapcompact-system-stub.md +1 -0
  888. package/src/prompts/system/snapcompact-toolresult-note.md +1 -0
  889. package/src/prompts/system/subagent-system-prompt.md +7 -8
  890. package/src/prompts/system/system-prompt.md +28 -57
  891. package/src/prompts/system/tiny-title-system.md +1 -1
  892. package/src/prompts/system/title-marker-instruction.md +1 -0
  893. package/src/prompts/system/title-system-marker.md +16 -0
  894. package/src/prompts/system/title-system.md +16 -3
  895. package/src/prompts/system/ttsr-tool-reminder.md +1 -1
  896. package/src/prompts/system/workflow-notice.md +4 -4
  897. package/src/prompts/tools/ast-edit.md +1 -1
  898. package/src/prompts/tools/ast-grep.md +2 -2
  899. package/src/prompts/tools/bash.md +16 -8
  900. package/src/prompts/tools/browser.md +33 -43
  901. package/src/prompts/tools/debug.md +1 -1
  902. package/src/prompts/tools/eval.md +31 -51
  903. package/src/prompts/tools/find.md +0 -1
  904. package/src/prompts/tools/github.md +8 -7
  905. package/src/prompts/tools/goal.md +1 -1
  906. package/src/prompts/tools/image-gen.md +1 -1
  907. package/src/prompts/tools/inspect-image-system.md +1 -1
  908. package/src/prompts/tools/irc.md +39 -31
  909. package/src/prompts/tools/job.md +2 -1
  910. package/src/prompts/tools/learn.md +7 -0
  911. package/src/prompts/tools/lsp-late-diagnostic.md +8 -0
  912. package/src/prompts/tools/lsp.md +2 -2
  913. package/src/prompts/tools/manage-skill.md +9 -0
  914. package/src/prompts/tools/memory-edit.md +1 -1
  915. package/src/prompts/tools/patch.md +2 -2
  916. package/src/prompts/tools/read.md +31 -39
  917. package/src/prompts/tools/recall.md +1 -1
  918. package/src/prompts/tools/reflect.md +1 -1
  919. package/src/prompts/tools/render-mermaid.md +2 -2
  920. package/src/prompts/tools/replace.md +4 -10
  921. package/src/prompts/tools/rewind.md +2 -2
  922. package/src/prompts/tools/search-tool-bm25.md +1 -9
  923. package/src/prompts/tools/search.md +0 -1
  924. package/src/prompts/tools/ssh.md +0 -4
  925. package/src/prompts/tools/task-summary.md +5 -16
  926. package/src/prompts/tools/task.md +47 -31
  927. package/src/prompts/tools/todo.md +6 -3
  928. package/src/registry/agent-lifecycle.ts +218 -0
  929. package/src/registry/agent-registry.ts +46 -5
  930. package/src/sdk.ts +692 -219
  931. package/src/secrets/index.ts +8 -1
  932. package/src/secrets/obfuscator.ts +40 -19
  933. package/src/session/agent-session.ts +1577 -806
  934. package/src/session/agent-storage.ts +18 -9
  935. package/src/session/auth-broker-config.ts +30 -1
  936. package/src/session/auth-storage.ts +6 -0
  937. package/src/session/codex-auto-reset.ts +202 -0
  938. package/src/session/history-storage.ts +3 -2
  939. package/src/session/indexed-session-storage.ts +7 -10
  940. package/src/session/messages.ts +59 -95
  941. package/src/session/session-context.ts +352 -0
  942. package/src/session/session-dump-format.ts +12 -3
  943. package/src/session/session-entries.ts +194 -0
  944. package/src/session/session-history-format.ts +246 -0
  945. package/src/session/session-listing.ts +588 -0
  946. package/src/session/session-loader.ts +106 -0
  947. package/src/session/session-manager.ts +1003 -2920
  948. package/src/session/session-migrations.ts +78 -0
  949. package/src/session/session-paths.ts +193 -0
  950. package/src/session/session-persistence.ts +131 -0
  951. package/src/session/session-storage.ts +91 -30
  952. package/src/session/snapcompact-inline.ts +542 -0
  953. package/src/session/snapcompact-savings-journal.ts +113 -0
  954. package/src/session/streaming-output.ts +248 -11
  955. package/src/session/tool-choice-queue.ts +23 -11
  956. package/src/session/yield-queue.ts +20 -2
  957. package/src/slash-commands/acp-builtins.ts +25 -1
  958. package/src/slash-commands/available-commands.ts +105 -0
  959. package/src/slash-commands/builtin-registry.ts +575 -49
  960. package/src/slash-commands/helpers/active-oauth-account.ts +44 -0
  961. package/src/slash-commands/helpers/context-report.ts +28 -1
  962. package/src/slash-commands/helpers/logout.ts +88 -0
  963. package/src/slash-commands/helpers/reset-usage.ts +66 -0
  964. package/src/slash-commands/helpers/stats-dashboard.ts +85 -0
  965. package/src/slash-commands/helpers/usage-report.ts +38 -3
  966. package/src/slash-commands/types.ts +5 -9
  967. package/src/ssh/connection-manager.ts +27 -0
  968. package/src/ssh/ssh-executor.ts +60 -4
  969. package/src/stt/asr-client.ts +520 -0
  970. package/src/stt/asr-protocol.ts +65 -0
  971. package/src/stt/asr-worker.ts +790 -0
  972. package/src/stt/downloader.ts +107 -47
  973. package/src/stt/endpointer.ts +259 -0
  974. package/src/stt/index.ts +5 -1
  975. package/src/stt/models.ts +150 -0
  976. package/src/stt/recorder.ts +254 -67
  977. package/src/stt/stt-controller.ts +201 -22
  978. package/src/stt/transcriber.ts +37 -68
  979. package/src/stt/wav.ts +173 -0
  980. package/src/system-prompt.ts +52 -10
  981. package/src/task/agents.ts +3 -4
  982. package/src/task/commands.ts +3 -2
  983. package/src/task/discovery.ts +17 -24
  984. package/src/task/executor.ts +1054 -529
  985. package/src/task/index.ts +862 -757
  986. package/src/task/output-manager.ts +0 -11
  987. package/src/task/parallel.ts +3 -3
  988. package/src/task/prometheus-command.ts +2 -2
  989. package/src/task/render.ts +529 -182
  990. package/src/task/repair-args.ts +21 -9
  991. package/src/task/types.ts +144 -66
  992. package/src/task/worktree.ts +64 -56
  993. package/src/telemetry-export.ts +27 -9
  994. package/src/thinking.ts +9 -7
  995. package/src/tiny/models.ts +2 -2
  996. package/src/tiny/text.ts +5 -1
  997. package/src/tiny/title-client.ts +72 -20
  998. package/src/tiny/title-protocol.ts +1 -1
  999. package/src/tiny/worker.ts +23 -99
  1000. package/src/tool-discovery/tool-index.ts +2 -0
  1001. package/src/tools/archive-reader.ts +94 -2
  1002. package/src/tools/ask.ts +234 -177
  1003. package/src/tools/ast-edit.ts +136 -80
  1004. package/src/tools/ast-grep.ts +41 -45
  1005. package/src/tools/auto-generated-guard.ts +20 -3
  1006. package/src/tools/bash-interactive.ts +28 -8
  1007. package/src/tools/bash.ts +198 -35
  1008. package/src/tools/browser/attach.ts +26 -7
  1009. package/src/tools/browser/cmux/cmux-tab.ts +1264 -0
  1010. package/src/tools/browser/cmux/rpc.ts +156 -0
  1011. package/src/tools/browser/cmux/socket-client.ts +309 -0
  1012. package/src/tools/browser/launch.ts +11 -2
  1013. package/src/tools/browser/readable.ts +19 -2
  1014. package/src/tools/browser/registry.ts +52 -5
  1015. package/src/tools/browser/render.ts +13 -5
  1016. package/src/tools/browser/tab-protocol.ts +2 -0
  1017. package/src/tools/browser/tab-supervisor.ts +256 -34
  1018. package/src/tools/browser/tab-worker.ts +259 -91
  1019. package/src/tools/browser.ts +44 -2
  1020. package/src/tools/checkpoint.ts +1 -1
  1021. package/src/tools/conflict-detect.ts +50 -4
  1022. package/src/tools/debug.ts +27 -12
  1023. package/src/tools/eval-render.ts +32 -35
  1024. package/src/tools/eval.ts +26 -12
  1025. package/src/tools/fetch.ts +450 -99
  1026. package/src/tools/find.ts +182 -142
  1027. package/src/tools/gh-cache-invalidation.ts +255 -0
  1028. package/src/tools/gh-renderer.ts +104 -51
  1029. package/src/tools/gh.ts +232 -37
  1030. package/src/tools/github-cache.ts +97 -7
  1031. package/src/tools/grouped-file-output.ts +159 -52
  1032. package/src/tools/image-gen.ts +237 -132
  1033. package/src/tools/index.ts +147 -26
  1034. package/src/tools/inspect-image-renderer.ts +74 -45
  1035. package/src/tools/inspect-image.ts +12 -6
  1036. package/src/tools/irc.ts +626 -173
  1037. package/src/tools/job.ts +106 -29
  1038. package/src/tools/learn.ts +144 -0
  1039. package/src/tools/manage-skill.ts +104 -0
  1040. package/src/tools/memory-edit.ts +4 -4
  1041. package/src/tools/memory-recall.ts +7 -9
  1042. package/src/tools/memory-reflect.ts +5 -9
  1043. package/src/tools/memory-render.ts +23 -6
  1044. package/src/tools/memory-retain.ts +4 -4
  1045. package/src/tools/path-utils.ts +102 -48
  1046. package/src/tools/plan-mode-guard.ts +101 -40
  1047. package/src/tools/read.ts +475 -120
  1048. package/src/tools/render-mermaid.ts +1 -1
  1049. package/src/tools/render-utils.ts +132 -76
  1050. package/src/tools/renderers.ts +12 -1
  1051. package/src/tools/report-tool-issue.ts +14 -6
  1052. package/src/tools/resolve.ts +20 -3
  1053. package/src/tools/review.ts +2 -2
  1054. package/src/tools/search-tool-bm25.ts +37 -24
  1055. package/src/tools/search.ts +233 -115
  1056. package/src/tools/sqlite-reader.ts +26 -17
  1057. package/src/tools/ssh.ts +20 -14
  1058. package/src/tools/todo.ts +197 -191
  1059. package/src/tools/tool-result.ts +8 -0
  1060. package/src/tools/tool-timeouts.ts +1 -1
  1061. package/src/tools/tts.ts +205 -74
  1062. package/src/tools/write.ts +291 -155
  1063. package/src/tools/yield.ts +10 -1
  1064. package/src/tts/downloader.ts +64 -0
  1065. package/src/tts/index.ts +8 -0
  1066. package/src/tts/models.ts +137 -0
  1067. package/src/tts/player.ts +137 -0
  1068. package/src/tts/runtime.ts +21 -0
  1069. package/src/tts/streaming-player.ts +266 -0
  1070. package/src/tts/tts-client.ts +647 -0
  1071. package/src/tts/tts-protocol.ts +60 -0
  1072. package/src/tts/tts-worker.ts +505 -0
  1073. package/src/tts/vocalizer.ts +162 -0
  1074. package/src/tts/wav.ts +58 -0
  1075. package/src/tui/code-cell.ts +2 -7
  1076. package/src/tui/hyperlink.ts +40 -26
  1077. package/src/tui/output-block.ts +60 -108
  1078. package/src/tui/status-line.ts +5 -1
  1079. package/src/utils/block-context.ts +312 -0
  1080. package/src/utils/changelog.ts +27 -1
  1081. package/src/utils/clipboard.ts +91 -22
  1082. package/src/utils/commit-message-generator.ts +8 -3
  1083. package/src/utils/enhanced-paste.ts +230 -0
  1084. package/src/utils/file-mentions.ts +3 -1
  1085. package/src/utils/git.ts +315 -15
  1086. package/src/utils/image-loading.ts +65 -4
  1087. package/src/utils/session-color.ts +83 -9
  1088. package/src/utils/thinking-display.ts +37 -0
  1089. package/src/utils/title-generator.ts +73 -10
  1090. package/src/utils/tool-choice.ts +16 -0
  1091. package/src/utils/tools-manager.ts +19 -1
  1092. package/src/web/kagi.ts +28 -26
  1093. package/src/web/parallel.ts +7 -3
  1094. package/src/web/scrapers/arxiv.ts +1 -1
  1095. package/src/web/scrapers/github.ts +351 -3
  1096. package/src/web/scrapers/go-pkg.ts +1 -1
  1097. package/src/web/scrapers/iacr.ts +1 -1
  1098. package/src/web/scrapers/readthedocs.ts +1 -1
  1099. package/src/web/scrapers/twitter.ts +2 -1
  1100. package/src/web/scrapers/types.ts +87 -8
  1101. package/src/web/scrapers/wikipedia.ts +1 -1
  1102. package/src/web/scrapers/youtube.ts +9 -3
  1103. package/src/web/search/index.ts +15 -2
  1104. package/src/web/search/providers/anthropic.ts +62 -21
  1105. package/src/web/search/providers/base.ts +2 -1
  1106. package/src/web/search/providers/brave.ts +5 -2
  1107. package/src/web/search/providers/codex.ts +87 -51
  1108. package/src/web/search/providers/exa.ts +101 -10
  1109. package/src/web/search/providers/gemini.ts +49 -24
  1110. package/src/web/search/providers/jina.ts +15 -5
  1111. package/src/web/search/providers/kagi.ts +9 -2
  1112. package/src/web/search/providers/kimi.ts +45 -20
  1113. package/src/web/search/providers/parallel.ts +39 -24
  1114. package/src/web/search/providers/perplexity.ts +226 -63
  1115. package/src/web/search/providers/searxng.ts +19 -3
  1116. package/src/web/search/providers/synthetic.ts +16 -11
  1117. package/src/web/search/providers/tavily.ts +12 -9
  1118. package/src/web/search/providers/zai.ts +22 -9
  1119. package/src/web/search/render.ts +59 -64
  1120. package/src/web/search/types.ts +5 -1
  1121. package/dist/types/discovery/context-files.d.ts +0 -17
  1122. package/dist/types/exa/factory.d.ts +0 -13
  1123. package/dist/types/exa/render.d.ts +0 -19
  1124. package/dist/types/exa/researcher.d.ts +0 -9
  1125. package/dist/types/exa/search.d.ts +0 -9
  1126. package/dist/types/exa/websets.d.ts +0 -9
  1127. package/dist/types/export/html/template.generated.d.ts +0 -1
  1128. package/dist/types/modes/components/session-observer-overlay.d.ts +0 -11
  1129. package/dist/types/modes/components/status-line.d.ts +0 -77
  1130. package/dist/types/slash-commands/headless-plan.d.ts +0 -3
  1131. package/dist/types/stt/setup.d.ts +0 -18
  1132. package/scripts/generate-template.ts +0 -33
  1133. package/src/discovery/context-files.ts +0 -49
  1134. package/src/exa/factory.ts +0 -60
  1135. package/src/exa/render.ts +0 -244
  1136. package/src/exa/researcher.ts +0 -36
  1137. package/src/exa/search.ts +0 -47
  1138. package/src/exa/websets.ts +0 -248
  1139. package/src/export/html/template.generated.ts +0 -2
  1140. package/src/modes/components/session-observer-overlay.ts +0 -852
  1141. package/src/slash-commands/headless-plan.ts +0 -142
  1142. package/src/stt/setup.ts +0 -52
  1143. package/src/stt/transcribe.py +0 -70
  1144. /package/dist/types/extensibility/{legacy-pi-coding-agent-shim.d.ts → legacy-package-agent-shim.d.ts} +0 -0
  1145. /package/src/extensibility/{legacy-pi-coding-agent-shim.ts → legacy-package-agent-shim.ts} +0 -0
@@ -3,16 +3,16 @@ import type * as fsNode from "node:fs";
3
3
  import * as fs from "node:fs/promises";
4
4
  import * as path from "node:path";
5
5
  import type { AgentMessage } from "@prometheus-ai/agent-core";
6
- import { clampThinkingLevelForModel, completeSimple, Effort, type Model } from "@prometheus-ai/ai";
7
- import { getAgentDbPath, getMemoriesDir, logger, parseJsonlLenient, prompt } from "@prometheus-ai/utils";
8
- import { readFile, walkUp } from "../capability/fs";
6
+ import { type ApiKey, completeSimple, Effort, type Model } from "@prometheus-ai/ai";
7
+ import { clampThinkingLevelForModel } from "@prometheus-ai/catalog/model-thinking";
8
+ import { getAgentDbPath, getMemoriesDir, isEnoent, logger, parseJsonlLenient, prompt } from "@prometheus-ai/utils";
9
+
9
10
  import type { ModelRegistry } from "../config/model-registry";
10
- import { resolveModelRoleValue } from "../config/model-resolver";
11
+ import { getModelMatchPreferences, resolveModelRoleValue } from "../config/model-resolver";
11
12
  import type { Settings } from "../config/settings";
12
- import { SOURCE_PATHS } from "../discovery/helpers";
13
+ import type { MemoryBackendSaveInput, MemoryBackendSaveResult } from "../memory-backend/types";
13
14
  import consolidationTemplate from "../prompts/memories/consolidation.md" with { type: "text" };
14
- import identityReviewTemplate from "../prompts/memories/identity_review.md" with { type: "text" };
15
- import postTurnReviewTemplate from "../prompts/memories/post_turn_review.md" with { type: "text" };
15
+ import consolidationSystemTemplate from "../prompts/memories/consolidation_system.md" with { type: "text" };
16
16
  import readPathTemplate from "../prompts/memories/read-path.md" with { type: "text" };
17
17
  import stageOneInputTemplate from "../prompts/memories/stage_one_input.md" with { type: "text" };
18
18
  import stageOneSystemTemplate from "../prompts/memories/stage_one_system.md" with { type: "text" };
@@ -32,7 +32,6 @@ import {
32
32
  markStage1SucceededNoOutput,
33
33
  markStage1SucceededWithOutput,
34
34
  openMemoryDb,
35
- recordBackgroundStage1Output,
36
35
  type Stage1Claim,
37
36
  type Stage1OutputRow,
38
37
  tryClaimGlobalPhase2Job,
@@ -41,13 +40,6 @@ import {
41
40
 
42
41
  interface MemoryRuntimeConfig {
43
42
  enabled: boolean;
44
- selfImprovementMode: "memory-and-skills" | "off";
45
- backgroundReviewMode: "memory-and-skills" | "off";
46
- backgroundReviewEveryNTurns: number;
47
- identityReviewMode: "propose" | "off";
48
- curatorMode: "dry-run" | "off";
49
- generatedSkillStaleAfterDays: number;
50
- generatedSkillArchiveAfterDays: number;
51
43
  maxRolloutsPerStartup: number;
52
44
  maxRolloutAgeDays: number;
53
45
  minRolloutIdleHours: number;
@@ -67,13 +59,6 @@ interface MemoryRuntimeConfig {
67
59
 
68
60
  const DEFAULTS: MemoryRuntimeConfig = {
69
61
  enabled: false,
70
- selfImprovementMode: "memory-and-skills",
71
- backgroundReviewMode: "memory-and-skills",
72
- backgroundReviewEveryNTurns: 10,
73
- identityReviewMode: "propose",
74
- curatorMode: "dry-run",
75
- generatedSkillStaleAfterDays: 30,
76
- generatedSkillArchiveAfterDays: 90,
77
62
  maxRolloutsPerStartup: 64,
78
63
  maxRolloutAgeDays: 30,
79
64
  minRolloutIdleHours: 12,
@@ -91,8 +76,6 @@ const DEFAULTS: MemoryRuntimeConfig = {
91
76
  summaryInjectionTokenLimit: 5_000,
92
77
  };
93
78
 
94
- const GENERATED_MEMORY_SKILL_INDEX_LIMIT = 50;
95
-
96
79
  interface Stage1Stats {
97
80
  claimed: number;
98
81
  succeeded: number;
@@ -114,11 +97,6 @@ interface Stage1OutputSchema {
114
97
  rollout_slug: string | null;
115
98
  }
116
99
 
117
- interface PostTurnReviewMessage {
118
- role: "user" | "assistant";
119
- content: string;
120
- }
121
-
122
100
  interface ConsolidationSkillFileSchema {
123
101
  path: string;
124
102
  content: string;
@@ -133,94 +111,10 @@ interface ConsolidationSkillSchema {
133
111
  }
134
112
  interface ConsolidationOutputSchema {
135
113
  memory_md: string;
136
- user_md: string;
137
114
  memory_summary: string;
138
115
  skills: ConsolidationSkillSchema[];
139
116
  }
140
117
 
141
- type GeneratedMemorySkillState = "active" | "stale" | "archived";
142
- type GeneratedMemorySkillEvent = "use" | "view" | "patch";
143
-
144
- interface GeneratedMemorySkillUsageRecord {
145
- schemaVersion: 1;
146
- name: string;
147
- source: "memory-consolidation";
148
- state: GeneratedMemorySkillState;
149
- pinned: boolean;
150
- createdAt: string;
151
- updatedAt: string;
152
- lastSeenInConsolidationAt: string | null;
153
- archivedAt: string | null;
154
- archiveReason: string | null;
155
- useCount: number;
156
- viewCount: number;
157
- patchCount: number;
158
- lastUsedAt: string | null;
159
- lastViewedAt: string | null;
160
- lastPatchedAt: string | null;
161
- }
162
-
163
- interface GeneratedMemorySkillUsageFile {
164
- schemaVersion: 1;
165
- skills: Record<string, GeneratedMemorySkillUsageRecord>;
166
- }
167
-
168
- interface IdentityReviewResult {
169
- soulProposal: string;
170
- nativeSoulPath: string | null;
171
- error?: string;
172
- }
173
-
174
- interface SkillCurationResult {
175
- usage: GeneratedMemorySkillUsageFile;
176
- active: string[];
177
- pinnedStale: string[];
178
- archived: string[];
179
- staleCandidates: string[];
180
- archiveCandidates: string[];
181
- markedStale: string[];
182
- reactivated: string[];
183
- report: string;
184
- }
185
-
186
- export const MEMORY_ARTIFACTS = {
187
- summary: "memory_summary.md",
188
- memory: "MEMORY.md",
189
- user: "USER.md",
190
- selfImprovementReport: "self_improvement_report.md",
191
- skillUsage: "skill_usage.json",
192
- skillCuratorReport: "skill_curator_report.md",
193
- soulProposal: "SOUL.proposed.md",
194
- } as const;
195
-
196
- const USER_PROFILE_OPEN_TAG = '<user_profile role="durable_user_context">';
197
- const USER_PROFILE_CLOSE_TAG = "</user_profile>";
198
- const POST_TURN_REVIEW_THREAD_PREFIX = "post-turn-review";
199
- const postTurnReviewStates = new WeakMap<
200
- AgentSession,
201
- { lastReviewedUserTurns: number; running: boolean; unsubscribe: () => void }
202
- >();
203
-
204
- const FORBIDDEN_IDENTITY_ARTIFACT_PATTERNS: ReadonlyArray<{ label: string; pattern: RegExp }> = [
205
- { label: "soul_md", pattern: /\bsoul_md\b/i },
206
- { label: "SOUL.md", pattern: /\bSOUL\.md\b/i },
207
- { label: "SOUL.proposed.md", pattern: /\bSOUL\.proposed\.md\b/i },
208
- { label: "<soul>", pattern: /<\s*\/?\s*soul\b/i },
209
- { label: "<soul_proposal>", pattern: /<\s*\/?\s*soul[_-]?proposal\b/i },
210
- { label: "<soul_proposed>", pattern: /<\s*\/?\s*soul[_-]?proposed\b/i },
211
- { label: "<identity>", pattern: /<\s*\/?\s*identity\b/i },
212
- { label: "<personality>", pattern: /<\s*\/?\s*personality\b/i },
213
- { label: "agent_identity", pattern: /\bagent_identity\b/i },
214
- { label: "assistant_identity", pattern: /\bassistant_identity\b/i },
215
- { label: "prometheus_identity", pattern: /\bprometheus_identity\b/i },
216
- { label: "identity_md", pattern: /\bidentity_md\b/i },
217
- { label: "persona_md", pattern: /\bpersona_md\b/i },
218
- { label: "personality_md", pattern: /\bpersonality_md\b/i },
219
- { label: "agent_personality", pattern: /\bagent_personality\b/i },
220
- { label: "assistant_personality", pattern: /\bassistant_personality\b/i },
221
- { label: "prometheus_personality", pattern: /\bprometheus_personality\b/i },
222
- ];
223
-
224
118
  /**
225
119
  * Start the background memory startup pipeline.
226
120
  *
@@ -248,8 +142,6 @@ export function startMemoryStartupTask(options: {
248
142
  return;
249
143
  }
250
144
 
251
- attachPostTurnBackgroundReview({ session, settings, modelRegistry, agentDir, config: cfg });
252
-
253
145
  void runMemoryStartup({ session, settings, modelRegistry, agentDir, config: cfg }).catch(error => {
254
146
  logger.warn("Memory startup failed", { error: String(error) });
255
147
  });
@@ -265,47 +157,31 @@ export async function buildMemoryToolDeveloperInstructions(
265
157
  const cfg = loadMemoryConfig(settings);
266
158
  if (!cfg.enabled) return undefined;
267
159
  const memoryRoot = getMemoryRoot(agentDir, settings.getCwd());
268
- const summaryPath = path.join(memoryRoot, MEMORY_ARTIFACTS.summary);
269
160
 
270
- let text: string;
161
+ let summary = "";
271
162
  try {
272
- text = await Bun.file(summaryPath).text();
163
+ summary = (await Bun.file(path.join(memoryRoot, "memory_summary.md")).text()).trim();
273
164
  } catch {
274
- return undefined;
165
+ // Missing or unreadable summary: injection is best-effort; fall through
166
+ // so any captured lessons still surface on their own.
275
167
  }
168
+ const learned = await readLearnedLessons(memoryRoot);
169
+ if (!summary && !learned) return undefined;
276
170
 
277
- const summary = text.trim();
278
- if (!summary) return undefined;
279
- const truncated = truncateByApproxTokens(summary, cfg.summaryInjectionTokenLimit);
280
- if (!truncated.trim()) return undefined;
281
- const generatedMemorySkills = await buildGeneratedMemorySkillIndex(memoryRoot);
171
+ const summaryOut = summary ? truncateByApproxTokens(summary, cfg.summaryInjectionTokenLimit).trim() : "";
172
+ // Lessons share one injection budget with the summary so the combined block
173
+ // stays within `summaryInjectionTokenLimit` (~4 chars/token, matching
174
+ // truncateByApproxTokens). With no summary, lessons get the whole budget.
175
+ const learnedBudget = Math.max(0, cfg.summaryInjectionTokenLimit - Math.ceil(summaryOut.length / 4));
176
+ const learnedOut = learned && learnedBudget > 0 ? truncateByApproxTokens(learned, learnedBudget).trim() : "";
177
+ if (!summaryOut && !learnedOut) return undefined;
282
178
 
283
179
  return prompt.render(readPathTemplate, {
284
- memory_summary: truncated,
285
- generated_memory_skills: generatedMemorySkills,
180
+ memory_summary: summaryOut,
181
+ learned: learnedOut,
286
182
  });
287
183
  }
288
184
 
289
- async function buildGeneratedMemorySkillIndex(memoryRoot: string): Promise<string> {
290
- const skillsDir = path.join(memoryRoot, "skills");
291
- const dirents = await fs.readdir(skillsDir, { withFileTypes: true }).catch(() => []);
292
- const names: string[] = [];
293
- for (const dirent of dirents) {
294
- if (!dirent.isDirectory()) continue;
295
- const skillPath = path.join(skillsDir, dirent.name, "SKILL.md");
296
- if (await Bun.file(skillPath).exists()) names.push(dirent.name);
297
- }
298
- names.sort((a, b) => a.localeCompare(b));
299
- if (names.length === 0) return "None yet.";
300
- const visible = names.slice(0, GENERATED_MEMORY_SKILL_INDEX_LIMIT);
301
- const lines = visible.map(name => `- memory://root/skills/${name}/SKILL.md`);
302
- const hidden = names.length - visible.length;
303
- if (hidden > 0) {
304
- lines.push(`- ... ${hidden} more generated memory skill${hidden === 1 ? "" : "s"} not listed`);
305
- }
306
- return lines.join("\n");
307
- }
308
-
309
185
  /**
310
186
  * Clear all persisted memory state and generated artifacts.
311
187
  */
@@ -343,107 +219,6 @@ async function runMemoryStartup(options: {
343
219
  await options.session.refreshBaseSystemPrompt?.();
344
220
  }
345
221
 
346
- function attachPostTurnBackgroundReview(options: {
347
- session: AgentSession;
348
- settings: Settings;
349
- modelRegistry: ModelRegistry;
350
- agentDir: string;
351
- config: MemoryRuntimeConfig;
352
- }): void {
353
- const { session, config } = options;
354
- if (config.backgroundReviewMode === "off") return;
355
- if (config.backgroundReviewEveryNTurns <= 0) return;
356
- if (postTurnReviewStates.has(session)) return;
357
- if (typeof session.subscribe !== "function") return;
358
-
359
- const state = { lastReviewedUserTurns: 0, running: false, unsubscribe: () => {} };
360
- state.unsubscribe = session.subscribe(event => {
361
- if (event.type !== "agent_end") return;
362
- void maybeRunPostTurnBackgroundReview(options);
363
- });
364
- postTurnReviewStates.set(session, state);
365
- }
366
-
367
- async function maybeRunPostTurnBackgroundReview(options: {
368
- session: AgentSession;
369
- settings: Settings;
370
- modelRegistry: ModelRegistry;
371
- agentDir: string;
372
- config: MemoryRuntimeConfig;
373
- }): Promise<void> {
374
- const { session, modelRegistry, agentDir, config } = options;
375
- const state = postTurnReviewStates.get(session);
376
- if (!state || state.running) return;
377
-
378
- const messages = extractPostTurnReviewMessages(session);
379
- const userTurns = messages.filter(message => message.role === "user").length;
380
- if (userTurns <= 0) return;
381
- if (userTurns - state.lastReviewedUserTurns < config.backgroundReviewEveryNTurns) return;
382
-
383
- state.running = true;
384
- try {
385
- const model = await resolveMemoryModel({ modelRegistry, session, fallbackRole: "default" });
386
- if (!model) {
387
- logger.debug("Post-turn memory review skipped: no model available");
388
- return;
389
- }
390
- const apiKey = await modelRegistry.getApiKey(model, session.sessionId);
391
- if (!apiKey) {
392
- logger.debug("Post-turn memory review skipped: no API key", {
393
- provider: model.provider,
394
- model: model.id,
395
- });
396
- return;
397
- }
398
-
399
- const result = await runPostTurnReviewModel({
400
- session,
401
- messages,
402
- userTurns,
403
- model,
404
- apiKey,
405
- modelMaxTokens: computeModelTokenBudget(model, config),
406
- config,
407
- metadata: session.agent?.metadataForProvider(model.provider),
408
- });
409
- if (result.kind === "failed") {
410
- logger.warn("Post-turn memory review failed", { reason: result.reason });
411
- return;
412
- }
413
- if (result.kind === "no_output") {
414
- state.lastReviewedUserTurns = userTurns;
415
- return;
416
- }
417
-
418
- const sourceUpdatedAt = unixNow();
419
- const threadId = buildPostTurnReviewThreadId(session.sessionManager.getSessionId(), userTurns);
420
- const db = openMemoryDb(getAgentDbPath(agentDir));
421
- try {
422
- recordBackgroundStage1Output(db, {
423
- threadId,
424
- sourceUpdatedAt,
425
- rolloutPath: session.sessionManager.getSessionFile() ?? threadId,
426
- cwd: session.sessionManager.getCwd(),
427
- rawMemory: result.output.rawMemory,
428
- rolloutSummary: result.output.rolloutSummary,
429
- rolloutSlug: result.output.rolloutSlug,
430
- nowSec: sourceUpdatedAt,
431
- });
432
- } finally {
433
- closeMemoryDb(db);
434
- }
435
- state.lastReviewedUserTurns = userTurns;
436
-
437
- await runPhase2(options);
438
- await session.refreshBaseSystemPrompt?.();
439
- session.emitNotice("info", "Self-improvement review captured durable memory.", "Memory");
440
- } catch (error) {
441
- logger.warn("Post-turn memory review failed", { error: String(error) });
442
- } finally {
443
- state.running = false;
444
- }
445
- }
446
-
447
222
  async function runPhase1(options: {
448
223
  session: AgentSession;
449
224
  settings: Settings;
@@ -506,7 +281,7 @@ async function runPhase1(options: {
506
281
  const result = await runStage1Job({
507
282
  claim,
508
283
  model: phase1Model,
509
- apiKey: phase1ApiKey,
284
+ apiKey: modelRegistry.resolver(phase1Model, session.sessionId),
510
285
  modelMaxTokens: computeModelTokenBudget(phase1Model, config),
511
286
  config,
512
287
  metadata: session.agent?.metadataForProvider(phase1Model.provider),
@@ -663,24 +438,10 @@ async function runPhase2(options: {
663
438
  const consolidated = await runConsolidationModel({
664
439
  memoryRoot,
665
440
  model: phase2Model,
666
- apiKey: phase2ApiKey,
667
- metadata: session.agent?.metadataForProvider(phase2Model.provider),
668
- });
669
- const identityReview = await runIdentityReviewModel({
670
- cwd,
671
- memoryRoot,
672
- model: phase2Model,
673
- apiKey: phase2ApiKey,
441
+ apiKey: modelRegistry.resolver(phase2Model, session.sessionId),
674
442
  metadata: session.agent?.metadataForProvider(phase2Model.provider),
675
- consolidated,
676
- enabled: config.identityReviewMode === "propose",
677
- });
678
- await applyConsolidation(memoryRoot, consolidated, {
679
- identityReview,
680
- curatorMode: config.curatorMode,
681
- generatedSkillStaleAfterDays: config.generatedSkillStaleAfterDays,
682
- generatedSkillArchiveAfterDays: config.generatedSkillArchiveAfterDays,
683
443
  });
444
+ await applyConsolidation(memoryRoot, consolidated);
684
445
  if (heartbeatLostOwnership) {
685
446
  throw new Error("Phase2 lease ownership lost before completion");
686
447
  }
@@ -820,87 +581,10 @@ function extractPersistableMessages(payload: string): AgentMessage[] {
820
581
  return messages;
821
582
  }
822
583
 
823
- async function runPostTurnReviewModel(options: {
824
- session: AgentSession;
825
- messages: PostTurnReviewMessage[];
826
- userTurns: number;
827
- model: Model;
828
- apiKey: string;
829
- modelMaxTokens: number;
830
- config: MemoryRuntimeConfig;
831
- metadata?: Record<string, unknown>;
832
- }): Promise<
833
- | {
834
- kind: "output";
835
- output: { rawMemory: string; rolloutSummary: string; rolloutSlug: string | null };
836
- }
837
- | { kind: "no_output" }
838
- | { kind: "failed"; reason: string }
839
- > {
840
- const { session, messages, userTurns, model, apiKey, modelMaxTokens, config } = options;
841
- try {
842
- const budgetTokens = Math.min(
843
- config.phase1InputTokenLimit,
844
- Math.floor(modelMaxTokens * config.rolloutPayloadPercent),
845
- );
846
- const input = prompt.render(postTurnReviewTemplate, {
847
- thread_id: session.sessionManager.getSessionId() ?? "unknown",
848
- cwd: session.sessionManager.getCwd(),
849
- user_turns: String(userTurns),
850
- review_every_n_turns: String(config.backgroundReviewEveryNTurns),
851
- conversation_json: truncateByApproxTokens(JSON.stringify(messages), budgetTokens),
852
- });
853
- const response = await completeSimple(
854
- model,
855
- {
856
- messages: [{ role: "user", content: [{ type: "text", text: input }], timestamp: Date.now() }],
857
- },
858
- {
859
- apiKey,
860
- metadata: options.metadata,
861
- maxTokens: Math.max(1024, Math.min(4096, Math.floor(modelMaxTokens * 0.2))),
862
- reasoning: clampThinkingLevelForModel(model, Effort.Low),
863
- },
864
- );
865
-
866
- if (response.stopReason === "error") {
867
- return { kind: "failed", reason: response.errorMessage || "post-turn review model error" };
868
- }
869
- const text = response.content
870
- .filter((c): c is { type: "text"; text: string } => c.type === "text")
871
- .map(c => c.text)
872
- .join("\n")
873
- .trim();
874
- const parsed = parseJsonObject(text);
875
- if (!parsed) {
876
- return { kind: "failed", reason: "post-turn review JSON parse failure" };
877
- }
878
- const schemaOutput = parseStage1OutputSchema(parsed);
879
- if (!schemaOutput) {
880
- return { kind: "failed", reason: "post-turn review JSON schema validation failure" };
881
- }
882
-
883
- const rawMemory = redactSecrets(schemaOutput.raw_memory).trim();
884
- const rolloutSummary = redactSecrets(schemaOutput.rollout_summary).trim();
885
- const rolloutSlug = schemaOutput.rollout_slug === null ? null : redactSecrets(schemaOutput.rollout_slug).trim();
886
- if (!rawMemory || !rolloutSummary) return { kind: "no_output" };
887
- return {
888
- kind: "output",
889
- output: {
890
- rawMemory,
891
- rolloutSummary,
892
- rolloutSlug: rolloutSlug || null,
893
- },
894
- };
895
- } catch (error) {
896
- return { kind: "failed", reason: String(error) };
897
- }
898
- }
899
-
900
584
  async function runStage1Job(options: {
901
585
  claim: Stage1Claim;
902
586
  model: Model;
903
- apiKey: string;
587
+ apiKey: ApiKey;
904
588
  modelMaxTokens: number;
905
589
  config: MemoryRuntimeConfig;
906
590
  metadata?: Record<string, unknown>;
@@ -1006,12 +690,8 @@ async function syncPhase2Artifacts(memoryRoot: string, outputs: Stage1OutputRow[
1006
690
  }
1007
691
 
1008
692
  async function cleanupConsolidatedArtifacts(memoryRoot: string): Promise<void> {
1009
- await fs.rm(path.join(memoryRoot, MEMORY_ARTIFACTS.memory), { force: true });
1010
- await fs.rm(path.join(memoryRoot, MEMORY_ARTIFACTS.user), { force: true });
1011
- await fs.rm(path.join(memoryRoot, MEMORY_ARTIFACTS.summary), { force: true });
1012
- await fs.rm(path.join(memoryRoot, MEMORY_ARTIFACTS.selfImprovementReport), { force: true });
1013
- await fs.rm(path.join(memoryRoot, MEMORY_ARTIFACTS.skillUsage), { force: true });
1014
- await fs.rm(path.join(memoryRoot, MEMORY_ARTIFACTS.skillCuratorReport), { force: true });
693
+ await fs.rm(path.join(memoryRoot, "MEMORY.md"), { force: true });
694
+ await fs.rm(path.join(memoryRoot, "memory_summary.md"), { force: true });
1015
695
  await fs.rm(path.join(memoryRoot, "skills"), { recursive: true, force: true });
1016
696
  }
1017
697
 
@@ -1048,11 +728,10 @@ async function readRolloutSummaries(memoryRoot: string): Promise<string> {
1048
728
  async function runConsolidationModel(options: {
1049
729
  memoryRoot: string;
1050
730
  model: Model;
1051
- apiKey: string;
731
+ apiKey: ApiKey;
1052
732
  metadata?: Record<string, unknown>;
1053
733
  }): Promise<{
1054
734
  memoryMd: string;
1055
- userMd: string;
1056
735
  memorySummary: string;
1057
736
  skills: Array<{
1058
737
  name: string;
@@ -1073,6 +752,7 @@ async function runConsolidationModel(options: {
1073
752
  const response = await completeSimple(
1074
753
  model,
1075
754
  {
755
+ systemPrompt: [consolidationSystemTemplate],
1076
756
  messages: [{ role: "user", content: [{ type: "text", text: input }], timestamp: Date.now() }],
1077
757
  },
1078
758
  {
@@ -1094,29 +774,7 @@ async function runConsolidationModel(options: {
1094
774
  if (!parsed) throw new Error("phase2 JSON parse failure");
1095
775
  const schemaOutput = parseConsolidationOutputSchema(parsed);
1096
776
  if (!schemaOutput) throw new Error("phase2 JSON schema validation failure");
1097
- assertNoIdentityArtifactLeak([
1098
- { field: "memory_md", value: schemaOutput.memory_md },
1099
- { field: "user_md", value: schemaOutput.user_md },
1100
- { field: "memory_summary", value: schemaOutput.memory_summary },
1101
- ...schemaOutput.skills.flatMap((skill, index) => [
1102
- { field: `skills[${index}].name`, value: skill.name },
1103
- { field: `skills[${index}].content`, value: skill.content ?? "" },
1104
- ...(skill.scripts ?? []).map(file => ({
1105
- field: `skills[${index}].scripts.${file.path}`,
1106
- value: `${file.path}\n${file.content}`,
1107
- })),
1108
- ...(skill.templates ?? []).map(file => ({
1109
- field: `skills[${index}].templates.${file.path}`,
1110
- value: `${file.path}\n${file.content}`,
1111
- })),
1112
- ...(skill.examples ?? []).map(file => ({
1113
- field: `skills[${index}].examples.${file.path}`,
1114
- value: `${file.path}\n${file.content}`,
1115
- })),
1116
- ]),
1117
- ]);
1118
777
  const memoryMd = redactSecrets(schemaOutput.memory_md).trim();
1119
- const userMd = normalizeConsolidatedUserProfile(redactSecrets(schemaOutput.user_md));
1120
778
  const memorySummary = redactSecrets(schemaOutput.memory_summary).trim();
1121
779
  const skills = schemaOutput.skills
1122
780
  .map(item => {
@@ -1142,117 +800,16 @@ async function runConsolidationModel(options: {
1142
800
  examples: ConsolidationSkillFileSchema[];
1143
801
  } => item !== null,
1144
802
  );
1145
- assertNoIdentityArtifactLeak([
1146
- { field: "memory_md", value: memoryMd },
1147
- { field: "user_md", value: userMd },
1148
- { field: "memory_summary", value: memorySummary },
1149
- ...skills.flatMap(skill => [
1150
- { field: `skills.${skill.name}.name`, value: skill.name },
1151
- { field: `skills.${skill.name}.content`, value: skill.content },
1152
- ...skill.scripts.map(file => ({
1153
- field: `skills.${skill.name}.scripts.${file.path}`,
1154
- value: `${file.path}\n${file.content}`,
1155
- })),
1156
- ...skill.templates.map(file => ({
1157
- field: `skills.${skill.name}.templates.${file.path}`,
1158
- value: `${file.path}\n${file.content}`,
1159
- })),
1160
- ...skill.examples.map(file => ({
1161
- field: `skills.${skill.name}.examples.${file.path}`,
1162
- value: `${file.path}\n${file.content}`,
1163
- })),
1164
- ]),
1165
- ]);
1166
803
  if (!memoryMd || !memorySummary) {
1167
804
  throw new Error("phase2 returned empty consolidated memory");
1168
805
  }
1169
- return { memoryMd, userMd, memorySummary, skills };
1170
- }
1171
-
1172
- async function runIdentityReviewModel(options: {
1173
- cwd: string;
1174
- memoryRoot: string;
1175
- model: Model;
1176
- apiKey: string;
1177
- metadata?: Record<string, unknown>;
1178
- enabled: boolean;
1179
- consolidated: {
1180
- userMd: string;
1181
- memorySummary: string;
1182
- skills: Array<{ name: string }>;
1183
- };
1184
- }): Promise<IdentityReviewResult> {
1185
- const nativeSoul = await readNativeSoulContext(options.cwd);
1186
- if (!options.enabled) {
1187
- return { soulProposal: "", nativeSoulPath: nativeSoul.path };
1188
- }
1189
-
1190
- try {
1191
- const input = prompt.render(identityReviewTemplate, {
1192
- native_soul_path: nativeSoul.path ?? "No native SOUL.md found.",
1193
- native_soul: truncateByApproxTokens(nativeSoul.content || "No native SOUL.md found.", 8_000),
1194
- user_md: truncateByApproxTokens(options.consolidated.userMd || "No durable USER.md profile.", 4_000),
1195
- memory_summary: truncateByApproxTokens(options.consolidated.memorySummary, 4_000),
1196
- generated_skills:
1197
- options.consolidated.skills.length === 0
1198
- ? "None."
1199
- : options.consolidated.skills
1200
- .map(skill => `- memory://root/skills/${skill.name}/SKILL.md`)
1201
- .sort((a, b) => a.localeCompare(b))
1202
- .join("\n"),
1203
- });
1204
-
1205
- const response = await completeSimple(
1206
- options.model,
1207
- {
1208
- messages: [{ role: "user", content: [{ type: "text", text: input }], timestamp: Date.now() }],
1209
- },
1210
- {
1211
- apiKey: options.apiKey,
1212
- metadata: options.metadata,
1213
- maxTokens: 4096,
1214
- reasoning: clampThinkingLevelForModel(options.model, Effort.Low),
1215
- },
1216
- );
1217
- if (response.stopReason === "error") {
1218
- return {
1219
- soulProposal: "",
1220
- nativeSoulPath: nativeSoul.path,
1221
- error: response.errorMessage || "identity review model error",
1222
- };
1223
- }
1224
- const text = response.content
1225
- .filter((c): c is { type: "text"; text: string } => c.type === "text")
1226
- .map(c => c.text)
1227
- .join("\n")
1228
- .trim();
1229
- const parsed = parseJsonObject(text);
1230
- if (!parsed) {
1231
- return { soulProposal: "", nativeSoulPath: nativeSoul.path, error: "identity review JSON parse failure" };
1232
- }
1233
- const proposal = parseIdentityReviewOutputSchema(parsed);
1234
- if (proposal === undefined) {
1235
- return { soulProposal: "", nativeSoulPath: nativeSoul.path, error: "identity review JSON schema failure" };
1236
- }
1237
- return { soulProposal: proposal, nativeSoulPath: nativeSoul.path };
1238
- } catch (error) {
1239
- return { soulProposal: "", nativeSoulPath: nativeSoul.path, error: String(error) };
1240
- }
1241
- }
1242
-
1243
- async function readNativeSoulContext(cwd: string): Promise<{ path: string | null; content: string }> {
1244
- const projectConfigDir = await walkUp(cwd, SOURCE_PATHS.native.projectDir, { file: false, dir: true });
1245
- if (!projectConfigDir) return { path: null, content: "" };
1246
- const soulPath = path.join(projectConfigDir, "SOUL.md");
1247
- const content = await readFile(soulPath);
1248
- return { path: soulPath, content: content ?? "" };
806
+ return { memoryMd, memorySummary, skills };
1249
807
  }
1250
808
 
1251
809
  async function applyConsolidation(
1252
810
  memoryRoot: string,
1253
811
  consolidated: {
1254
812
  memoryMd: string;
1255
- userMd: string;
1256
813
  memorySummary: string;
1257
814
  skills: Array<{
1258
815
  name: string;
@@ -1262,146 +819,30 @@ async function applyConsolidation(
1262
819
  examples: ConsolidationSkillFileSchema[];
1263
820
  }>;
1264
821
  },
1265
- options: {
1266
- identityReview: IdentityReviewResult;
1267
- curatorMode: "dry-run" | "off";
1268
- generatedSkillStaleAfterDays: number;
1269
- generatedSkillArchiveAfterDays: number;
1270
- },
1271
822
  ): Promise<void> {
1272
- await Bun.write(path.join(memoryRoot, MEMORY_ARTIFACTS.memory), `${consolidated.memoryMd.trim()}\n`);
1273
- await Bun.write(path.join(memoryRoot, MEMORY_ARTIFACTS.user), `${consolidated.userMd.trim()}\n`);
1274
- await Bun.write(path.join(memoryRoot, MEMORY_ARTIFACTS.summary), `${consolidated.memorySummary.trim()}\n`);
1275
- const curation = await applyGeneratedMemorySkills(memoryRoot, consolidated.skills, {
1276
- curatorMode: options.curatorMode,
1277
- staleAfterDays: options.generatedSkillStaleAfterDays,
1278
- archiveAfterDays: options.generatedSkillArchiveAfterDays,
1279
- });
1280
-
1281
- if (options.identityReview.soulProposal.trim()) {
1282
- await Bun.write(
1283
- path.join(memoryRoot, MEMORY_ARTIFACTS.soulProposal),
1284
- `${options.identityReview.soulProposal.trim()}\n`,
1285
- );
1286
- }
1287
-
1288
- await Bun.write(
1289
- path.join(memoryRoot, MEMORY_ARTIFACTS.selfImprovementReport),
1290
- buildSelfImprovementReport(consolidated, {
1291
- identityReview: options.identityReview,
1292
- curation,
1293
- }),
1294
- );
1295
- }
1296
-
1297
- function buildSelfImprovementReport(
1298
- consolidated: {
1299
- memoryMd: string;
1300
- userMd: string;
1301
- memorySummary: string;
1302
- skills: Array<{ name: string }>;
1303
- },
1304
- options: {
1305
- identityReview: IdentityReviewResult;
1306
- curation: SkillCurationResult;
1307
- },
1308
- ): string {
1309
- const skillNames = consolidated.skills.map(skill => skill.name).sort((a, b) => a.localeCompare(b));
1310
- const generatedSkills = skillNames.length === 0 ? "- None" : skillNames.map(name => `- ${name}`).join("\n");
1311
- const userProfileState = consolidated.userMd.trim() ? "updated" : "empty";
1312
- const identityLines = options.identityReview.soulProposal.trim()
1313
- ? [
1314
- "- SOUL proposal: written to memory://root/SOUL.proposed.md",
1315
- `- Native SOUL source: ${options.identityReview.nativeSoulPath ?? "none"}`,
1316
- ]
1317
- : ["- SOUL proposal: none written", `- Native SOUL source: ${options.identityReview.nativeSoulPath ?? "none"}`];
1318
- if (options.identityReview.error) {
1319
- identityLines.push(`- Identity review warning: ${options.identityReview.error}`);
1320
- }
1321
- const curatorLines = options.curation.report.trim()
1322
- ? [`- Skill curator dry-run report: memory://root/${MEMORY_ARTIFACTS.skillCuratorReport}`]
1323
- : ["- Skill curator: off"];
1324
-
1325
- return [
1326
- "# Self-Improvement Report",
1327
- "",
1328
- "Trajectory: Hermes-style native Prometheus learning.",
1329
- "",
1330
- "Automatic write scope:",
1331
- "- MEMORY.md: project and operational memory",
1332
- "- USER.md: durable user profile",
1333
- "- skills/: generated procedural playbooks",
1334
- "",
1335
- "Stable identity boundary:",
1336
- "- SOUL.md is not generated or rewritten by memory consolidation.",
1337
- "- SOUL.proposed.md is reserved for an explicit identity-review flow.",
1338
- "- Do not present memory artifacts as Prometheus identity.",
1339
- "",
1340
- "Dry-run review:",
1341
- "- Memory/profile/skill consolidation completed through the native Prometheus memory pipeline.",
1342
- ...identityLines,
1343
- ...curatorLines,
1344
- "",
1345
- "Current artifacts:",
1346
- `- MEMORY.md chars: ${consolidated.memoryMd.trim().length}`,
1347
- `- USER.md state: ${userProfileState}`,
1348
- `- memory_summary.md chars: ${consolidated.memorySummary.trim().length}`,
1349
- `- skill_usage.json records: ${Object.keys(options.curation.usage.skills).length}`,
1350
- "",
1351
- "Generated skills:",
1352
- generatedSkills,
1353
- "",
1354
- "Skill lifecycle:",
1355
- `- Active generated skills: ${options.curation.active.length}`,
1356
- `- Pinned stale skills preserved: ${options.curation.pinnedStale.length}`,
1357
- `- Archived stale skills: ${options.curation.archived.length}`,
1358
- `- Dry-run stale candidates: ${options.curation.staleCandidates.length}`,
1359
- `- Dry-run archive candidates: ${options.curation.archiveCandidates.length}`,
1360
- "",
1361
- ].join("\n");
1362
- }
1363
-
1364
- async function applyGeneratedMemorySkills(
1365
- memoryRoot: string,
1366
- skills: Array<{
1367
- name: string;
1368
- content: string;
1369
- scripts: ConsolidationSkillFileSchema[];
1370
- templates: ConsolidationSkillFileSchema[];
1371
- examples: ConsolidationSkillFileSchema[];
1372
- }>,
1373
- options: {
1374
- curatorMode: "dry-run" | "off";
1375
- staleAfterDays: number;
1376
- archiveAfterDays: number;
1377
- },
1378
- ): Promise<SkillCurationResult> {
823
+ await Bun.write(path.join(memoryRoot, "MEMORY.md"), `${consolidated.memoryMd.trim()}\n`);
824
+ await Bun.write(path.join(memoryRoot, "memory_summary.md"), `${consolidated.memorySummary.trim()}\n`);
1379
825
  const skillsDir = path.join(memoryRoot, "skills");
1380
826
  await fs.mkdir(skillsDir, { recursive: true });
1381
- const usage = await readGeneratedMemorySkillUsage(memoryRoot);
1382
- const now = new Date().toISOString();
1383
827
  const keep = new Set<string>();
1384
- const active: string[] = [];
1385
- const pinnedStale: string[] = [];
1386
- const archived: string[] = [];
1387
- const staleCandidates: string[] = [];
1388
- const archiveCandidates: string[] = [];
1389
- const markedStale: string[] = [];
1390
- const reactivated: string[] = [];
1391
-
1392
- for (const skill of skills) {
828
+ for (const skill of consolidated.skills) {
1393
829
  const dir = path.join(skillsDir, skill.name);
1394
- const files = buildSkillFileMap(skill);
1395
- const existed = await Bun.file(path.join(dir, "SKILL.md")).exists();
1396
- const changed = await skillFilesChanged(dir, files);
1397
830
  keep.add(skill.name);
1398
- active.push(skill.name);
1399
-
1400
831
  await fs.mkdir(dir, { recursive: true });
832
+ const files = new Map<string, string>();
833
+ files.set("SKILL.md", `${skill.content.trim()}\n`);
834
+ for (const item of skill.scripts) {
835
+ files.set(path.posix.join("scripts", item.path), `${item.content.trim()}\n`);
836
+ }
837
+ for (const item of skill.templates) {
838
+ files.set(path.posix.join("templates", item.path), `${item.content.trim()}\n`);
839
+ }
840
+ for (const item of skill.examples) {
841
+ files.set(path.posix.join("examples", item.path), `${item.content.trim()}\n`);
842
+ }
843
+
1401
844
  for (const [relativePath, content] of [...files.entries()].sort(([a], [b]) => a.localeCompare(b))) {
1402
- const filePath = path.join(dir, ...relativePath.split("/"));
1403
- await fs.mkdir(path.dirname(filePath), { recursive: true });
1404
- await Bun.write(filePath, content);
845
+ await Bun.write(path.join(dir, ...relativePath.split("/")), content);
1405
846
  }
1406
847
 
1407
848
  const keepFiles = new Set(files.keys());
@@ -1411,436 +852,12 @@ async function applyGeneratedMemorySkills(
1411
852
  await fs.rm(path.join(dir, ...relativePath.split("/")), { force: true });
1412
853
  }
1413
854
  await pruneEmptyDirectories(dir);
1414
- await fs.rm(path.join(skillsDir, ".archive", skill.name), { recursive: true, force: true });
1415
-
1416
- const record = normalizeGeneratedMemorySkillRecord(usage.skills[skill.name], skill.name, now);
1417
- record.state = "active";
1418
- record.updatedAt = now;
1419
- record.lastSeenInConsolidationAt = now;
1420
- record.archivedAt = null;
1421
- record.archiveReason = null;
1422
- if (existed && changed) {
1423
- record.patchCount += 1;
1424
- record.lastPatchedAt = now;
1425
- }
1426
- usage.skills[skill.name] = record;
1427
855
  }
1428
-
1429
856
  const dirs = await fs.readdir(skillsDir, { withFileTypes: true }).catch(() => []);
1430
857
  for (const dirent of dirs) {
1431
858
  if (!dirent.isDirectory()) continue;
1432
- if (dirent.name === ".archive") continue;
1433
859
  if (keep.has(dirent.name)) continue;
1434
-
1435
- const record = normalizeGeneratedMemorySkillRecord(usage.skills[dirent.name], dirent.name, now);
1436
- record.updatedAt = now;
1437
- if (record.pinned) {
1438
- record.state = "stale";
1439
- pinnedStale.push(dirent.name);
1440
- usage.skills[dirent.name] = record;
1441
- continue;
1442
- }
1443
-
1444
- await archiveGeneratedMemorySkillDir(skillsDir, dirent.name);
1445
- record.state = "archived";
1446
- record.archivedAt = record.archivedAt ?? now;
1447
- record.archiveReason = record.archiveReason ?? "Omitted by memory consolidation; archived instead of deleted.";
1448
- archived.push(dirent.name);
1449
- usage.skills[dirent.name] = record;
1450
- }
1451
-
1452
- if (options.curatorMode === "dry-run") {
1453
- applyGeneratedSkillDryRunClassification(usage, {
1454
- now,
1455
- staleAfterDays: options.staleAfterDays,
1456
- archiveAfterDays: options.archiveAfterDays,
1457
- staleCandidates,
1458
- archiveCandidates,
1459
- markedStale,
1460
- reactivated,
1461
- });
1462
- }
1463
-
1464
- const sortedUsage = sortGeneratedMemorySkillUsage(usage);
1465
- await writeGeneratedMemorySkillUsage(memoryRoot, sortedUsage);
1466
- const report =
1467
- options.curatorMode === "dry-run"
1468
- ? buildSkillCuratorReport(sortedUsage, {
1469
- active,
1470
- pinnedStale,
1471
- archived,
1472
- staleCandidates,
1473
- archiveCandidates,
1474
- markedStale,
1475
- reactivated,
1476
- curatorMode: options.curatorMode,
1477
- staleAfterDays: options.staleAfterDays,
1478
- archiveAfterDays: options.archiveAfterDays,
1479
- })
1480
- : "";
1481
- if (report.trim()) {
1482
- await Bun.write(path.join(memoryRoot, MEMORY_ARTIFACTS.skillCuratorReport), report);
1483
- } else {
1484
- await fs.rm(path.join(memoryRoot, MEMORY_ARTIFACTS.skillCuratorReport), { force: true });
1485
- }
1486
- return {
1487
- usage: sortedUsage,
1488
- active: active.sort((a, b) => a.localeCompare(b)),
1489
- pinnedStale: pinnedStale.sort((a, b) => a.localeCompare(b)),
1490
- archived: archived.sort((a, b) => a.localeCompare(b)),
1491
- staleCandidates: staleCandidates.sort((a, b) => a.localeCompare(b)),
1492
- archiveCandidates: archiveCandidates.sort((a, b) => a.localeCompare(b)),
1493
- markedStale: markedStale.sort((a, b) => a.localeCompare(b)),
1494
- reactivated: reactivated.sort((a, b) => a.localeCompare(b)),
1495
- report,
1496
- };
1497
- }
1498
-
1499
- function buildSkillFileMap(skill: {
1500
- content: string;
1501
- scripts: ConsolidationSkillFileSchema[];
1502
- templates: ConsolidationSkillFileSchema[];
1503
- examples: ConsolidationSkillFileSchema[];
1504
- }): Map<string, string> {
1505
- const files = new Map<string, string>();
1506
- files.set("SKILL.md", `${skill.content.trim()}\n`);
1507
- for (const item of skill.scripts) {
1508
- files.set(path.posix.join("scripts", item.path), `${item.content.trim()}\n`);
1509
- }
1510
- for (const item of skill.templates) {
1511
- files.set(path.posix.join("templates", item.path), `${item.content.trim()}\n`);
1512
- }
1513
- for (const item of skill.examples) {
1514
- files.set(path.posix.join("examples", item.path), `${item.content.trim()}\n`);
1515
- }
1516
- return files;
1517
- }
1518
-
1519
- async function skillFilesChanged(dir: string, desired: Map<string, string>): Promise<boolean> {
1520
- const existing = await listRelativeFiles(dir);
1521
- if (existing.length !== desired.size) return true;
1522
- for (const relativePath of existing) {
1523
- const wanted = desired.get(relativePath);
1524
- if (wanted === undefined) return true;
1525
- const current = await Bun.file(path.join(dir, ...relativePath.split("/")))
1526
- .text()
1527
- .catch(() => undefined);
1528
- if (current !== wanted) return true;
1529
- }
1530
- return false;
1531
- }
1532
-
1533
- async function readGeneratedMemorySkillUsage(memoryRoot: string): Promise<GeneratedMemorySkillUsageFile> {
1534
- const fallback: GeneratedMemorySkillUsageFile = { schemaVersion: 1, skills: {} };
1535
- const text = await Bun.file(path.join(memoryRoot, MEMORY_ARTIFACTS.skillUsage))
1536
- .text()
1537
- .catch(() => "");
1538
- if (!text.trim()) return fallback;
1539
- try {
1540
- const parsed = JSON.parse(text) as unknown;
1541
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return fallback;
1542
- const data = parsed as Record<string, unknown>;
1543
- if (data.schemaVersion !== 1 || !data.skills || typeof data.skills !== "object" || Array.isArray(data.skills)) {
1544
- return fallback;
1545
- }
1546
- const skills: Record<string, GeneratedMemorySkillUsageRecord> = {};
1547
- const now = new Date().toISOString();
1548
- for (const [name, record] of Object.entries(data.skills as Record<string, unknown>)) {
1549
- const sanitized = sanitizeSkillName(name);
1550
- if (!sanitized) continue;
1551
- skills[sanitized] = normalizeGeneratedMemorySkillRecord(record, sanitized, now);
1552
- }
1553
- return { schemaVersion: 1, skills };
1554
- } catch {
1555
- return fallback;
1556
- }
1557
- }
1558
-
1559
- async function writeGeneratedMemorySkillUsage(memoryRoot: string, usage: GeneratedMemorySkillUsageFile): Promise<void> {
1560
- await Bun.write(
1561
- path.join(memoryRoot, MEMORY_ARTIFACTS.skillUsage),
1562
- `${JSON.stringify(sortGeneratedMemorySkillUsage(usage), null, 2)}\n`,
1563
- );
1564
- }
1565
-
1566
- function sortGeneratedMemorySkillUsage(usage: GeneratedMemorySkillUsageFile): GeneratedMemorySkillUsageFile {
1567
- const sorted: Record<string, GeneratedMemorySkillUsageRecord> = {};
1568
- for (const name of Object.keys(usage.skills).sort((a, b) => a.localeCompare(b))) {
1569
- sorted[name] = usage.skills[name]!;
1570
- }
1571
- return { schemaVersion: 1, skills: sorted };
1572
- }
1573
-
1574
- function normalizeGeneratedMemorySkillRecord(
1575
- value: unknown,
1576
- name: string,
1577
- now: string,
1578
- ): GeneratedMemorySkillUsageRecord {
1579
- const input = value && typeof value === "object" && !Array.isArray(value) ? (value as Record<string, unknown>) : {};
1580
- const state = parseGeneratedMemorySkillState(input.state) ?? "active";
1581
- return {
1582
- schemaVersion: 1,
1583
- name,
1584
- source: "memory-consolidation",
1585
- state,
1586
- pinned: input.pinned === true,
1587
- createdAt: parseString(input.createdAt) ?? now,
1588
- updatedAt: parseString(input.updatedAt) ?? now,
1589
- lastSeenInConsolidationAt: parseString(input.lastSeenInConsolidationAt),
1590
- archivedAt: parseString(input.archivedAt),
1591
- archiveReason: parseString(input.archiveReason),
1592
- useCount: parseNonNegativeInteger(input.useCount),
1593
- viewCount: parseNonNegativeInteger(input.viewCount),
1594
- patchCount: parseNonNegativeInteger(input.patchCount),
1595
- lastUsedAt: parseString(input.lastUsedAt),
1596
- lastViewedAt: parseString(input.lastViewedAt),
1597
- lastPatchedAt: parseString(input.lastPatchedAt),
1598
- };
1599
- }
1600
-
1601
- function parseGeneratedMemorySkillState(value: unknown): GeneratedMemorySkillState | undefined {
1602
- return value === "active" || value === "stale" || value === "archived" ? value : undefined;
1603
- }
1604
-
1605
- function parseString(value: unknown): string | null {
1606
- if (typeof value !== "string") return null;
1607
- const trimmed = value.trim();
1608
- return trimmed || null;
1609
- }
1610
-
1611
- function parseNonNegativeInteger(value: unknown): number {
1612
- const parsed = typeof value === "number" ? value : Number(value);
1613
- if (!Number.isFinite(parsed) || parsed < 0) return 0;
1614
- return Math.floor(parsed);
1615
- }
1616
-
1617
- function applyGeneratedSkillDryRunClassification(
1618
- usage: GeneratedMemorySkillUsageFile,
1619
- options: {
1620
- now: string;
1621
- staleAfterDays: number;
1622
- archiveAfterDays: number;
1623
- staleCandidates: string[];
1624
- archiveCandidates: string[];
1625
- markedStale: string[];
1626
- reactivated: string[];
1627
- },
1628
- ): void {
1629
- const nowMs = Date.parse(options.now);
1630
- const staleCutoff = nowMs - options.staleAfterDays * 24 * 60 * 60 * 1000;
1631
- const archiveCutoff = nowMs - options.archiveAfterDays * 24 * 60 * 60 * 1000;
1632
- for (const record of Object.values(usage.skills)) {
1633
- if (record.state === "archived" || record.pinned) continue;
1634
- const anchor = Date.parse(latestGeneratedMemorySkillActivity(record) ?? record.createdAt);
1635
- if (!Number.isFinite(anchor)) continue;
1636
- if (anchor <= archiveCutoff) {
1637
- options.archiveCandidates.push(record.name);
1638
- if (record.state === "active") {
1639
- options.markedStale.push(record.name);
1640
- }
1641
- continue;
1642
- }
1643
- if (anchor <= staleCutoff) {
1644
- options.staleCandidates.push(record.name);
1645
- if (record.state === "active") {
1646
- options.markedStale.push(record.name);
1647
- }
1648
- continue;
1649
- }
1650
- if (record.state === "stale") {
1651
- options.reactivated.push(record.name);
1652
- }
1653
- }
1654
- }
1655
-
1656
- function latestGeneratedMemorySkillActivity(record: GeneratedMemorySkillUsageRecord): string | null {
1657
- const values = [record.lastUsedAt, record.lastViewedAt, record.lastPatchedAt].filter(
1658
- (value): value is string => typeof value === "string" && value.length > 0,
1659
- );
1660
- values.sort((a, b) => b.localeCompare(a));
1661
- return values[0] ?? record.lastSeenInConsolidationAt ?? null;
1662
- }
1663
-
1664
- function buildSkillCuratorReport(
1665
- usage: GeneratedMemorySkillUsageFile,
1666
- options: {
1667
- active: string[];
1668
- pinnedStale: string[];
1669
- archived: string[];
1670
- staleCandidates: string[];
1671
- archiveCandidates: string[];
1672
- markedStale: string[];
1673
- reactivated: string[];
1674
- curatorMode: "dry-run" | "off";
1675
- staleAfterDays: number;
1676
- archiveAfterDays: number;
1677
- },
1678
- ): string {
1679
- const records = Object.values(usage.skills).sort((a, b) => a.name.localeCompare(b.name));
1680
- const recordLines =
1681
- records.length === 0
1682
- ? ["- None"]
1683
- : records.map(
1684
- record =>
1685
- `- ${record.name}: state=${record.state}, pinned=${record.pinned ? "yes" : "no"}, ` +
1686
- `use=${record.useCount}, view=${record.viewCount}, patch=${record.patchCount}`,
1687
- );
1688
-
1689
- return [
1690
- "# Generated Skill Curator Report",
1691
- "",
1692
- `Mode: ${options.curatorMode}`,
1693
- "Scope: generated memory skills only.",
1694
- "Mutation boundary: dry-run curation reports suggestions; stale skills removed by consolidation are archived, not deleted.",
1695
- `Stale threshold days: ${options.staleAfterDays}`,
1696
- `Archive threshold days: ${options.archiveAfterDays}`,
1697
- "",
1698
- "Current pass:",
1699
- `- Active generated skills: ${options.active.length ? options.active.sort((a, b) => a.localeCompare(b)).join(", ") : "none"}`,
1700
- `- Pinned stale skills preserved: ${
1701
- options.pinnedStale.length ? options.pinnedStale.sort((a, b) => a.localeCompare(b)).join(", ") : "none"
1702
- }`,
1703
- `- Archived stale skills: ${options.archived.length ? options.archived.sort((a, b) => a.localeCompare(b)).join(", ") : "none"}`,
1704
- "",
1705
- "Dry-run candidates:",
1706
- `- Would mark stale: ${options.markedStale.length ? options.markedStale.sort((a, b) => a.localeCompare(b)).join(", ") : "none"}`,
1707
- `- Would reactivate: ${options.reactivated.length ? options.reactivated.sort((a, b) => a.localeCompare(b)).join(", ") : "none"}`,
1708
- `- Stale candidates: ${options.staleCandidates.length ? options.staleCandidates.sort((a, b) => a.localeCompare(b)).join(", ") : "none"}`,
1709
- `- Archive candidates: ${options.archiveCandidates.length ? options.archiveCandidates.sort((a, b) => a.localeCompare(b)).join(", ") : "none"}`,
1710
- "",
1711
- "Lifecycle policy:",
1712
- "- pinned=true prevents automatic archive.",
1713
- "- state=stale means omitted by latest consolidation while pinned, or inactive past the stale threshold.",
1714
- "- state=archived means moved to memory://root/skills/.archive/<name>/ for recoverable restore.",
1715
- "",
1716
- "Usage records:",
1717
- ...recordLines,
1718
- "",
1719
- ].join("\n");
1720
- }
1721
-
1722
- async function archiveGeneratedMemorySkillDir(skillsDir: string, name: string): Promise<void> {
1723
- const source = path.join(skillsDir, name);
1724
- if (!(await Bun.file(path.join(source, "SKILL.md")).exists())) return;
1725
- const archiveRoot = path.join(skillsDir, ".archive");
1726
- const target = path.join(archiveRoot, name);
1727
- await fs.mkdir(archiveRoot, { recursive: true });
1728
- await fs.rm(target, { recursive: true, force: true });
1729
- await fs.rename(source, target);
1730
- }
1731
-
1732
- export async function recordGeneratedMemorySkillEvent(
1733
- memoryRoot: string,
1734
- rawName: string,
1735
- event: GeneratedMemorySkillEvent,
1736
- ): Promise<boolean> {
1737
- const name = sanitizeSkillName(rawName);
1738
- if (!name) return false;
1739
- const usage = await readGeneratedMemorySkillUsage(memoryRoot);
1740
- const now = new Date().toISOString();
1741
- const record = normalizeGeneratedMemorySkillRecord(usage.skills[name], name, now);
1742
- const activeSkillPath = path.join(memoryRoot, "skills", name, "SKILL.md");
1743
- if (!(await Bun.file(activeSkillPath).exists()) && record.state !== "archived") return false;
1744
- record.updatedAt = now;
1745
- if (event === "use") {
1746
- record.useCount += 1;
1747
- record.lastUsedAt = now;
1748
- } else if (event === "view") {
1749
- record.viewCount += 1;
1750
- record.lastViewedAt = now;
1751
- } else {
1752
- record.patchCount += 1;
1753
- record.lastPatchedAt = now;
1754
- }
1755
- usage.skills[name] = record;
1756
- await writeGeneratedMemorySkillUsage(memoryRoot, usage);
1757
- return true;
1758
- }
1759
-
1760
- export async function pinGeneratedMemorySkill(memoryRoot: string, rawName: string, pinned = true): Promise<boolean> {
1761
- const name = sanitizeSkillName(rawName);
1762
- if (!name) return false;
1763
- const usage = await readGeneratedMemorySkillUsage(memoryRoot);
1764
- const now = new Date().toISOString();
1765
- const record = normalizeGeneratedMemorySkillRecord(usage.skills[name], name, now);
1766
- const activeSkillPath = path.join(memoryRoot, "skills", name, "SKILL.md");
1767
- const archivedSkillPath = path.join(memoryRoot, "skills", ".archive", name, "SKILL.md");
1768
- if (!(await Bun.file(activeSkillPath).exists()) && !(await Bun.file(archivedSkillPath).exists())) return false;
1769
- record.pinned = pinned;
1770
- record.updatedAt = now;
1771
- usage.skills[name] = record;
1772
- await writeGeneratedMemorySkillUsage(memoryRoot, usage);
1773
- return true;
1774
- }
1775
-
1776
- export async function archiveGeneratedMemorySkill(
1777
- memoryRoot: string,
1778
- rawName: string,
1779
- reason: string,
1780
- ): Promise<boolean> {
1781
- const name = sanitizeSkillName(rawName);
1782
- if (!name) return false;
1783
- const skillsDir = path.join(memoryRoot, "skills");
1784
- const sourceSkillPath = path.join(skillsDir, name, "SKILL.md");
1785
- if (!(await Bun.file(sourceSkillPath).exists())) return false;
1786
- const usage = await readGeneratedMemorySkillUsage(memoryRoot);
1787
- const now = new Date().toISOString();
1788
- const existingRecord = normalizeGeneratedMemorySkillRecord(usage.skills[name], name, now);
1789
- if (existingRecord.pinned) return false;
1790
- await archiveGeneratedMemorySkillDir(skillsDir, name);
1791
- const record = existingRecord;
1792
- record.state = "archived";
1793
- record.updatedAt = now;
1794
- record.archivedAt = now;
1795
- record.archiveReason = reason.trim() || "Archived by native generated-skill lifecycle.";
1796
- usage.skills[name] = record;
1797
- await writeGeneratedMemorySkillUsage(memoryRoot, usage);
1798
- return true;
1799
- }
1800
-
1801
- export async function restoreGeneratedMemorySkill(memoryRoot: string, rawName: string): Promise<boolean> {
1802
- const name = sanitizeSkillName(rawName);
1803
- if (!name) return false;
1804
- const skillsDir = path.join(memoryRoot, "skills");
1805
- const source = path.join(skillsDir, ".archive", name);
1806
- const target = path.join(skillsDir, name);
1807
- if (!(await Bun.file(path.join(source, "SKILL.md")).exists())) return false;
1808
- if (await Bun.file(path.join(target, "SKILL.md")).exists()) return false;
1809
- await fs.mkdir(skillsDir, { recursive: true });
1810
- await fs.rename(source, target);
1811
- const usage = await readGeneratedMemorySkillUsage(memoryRoot);
1812
- const now = new Date().toISOString();
1813
- const record = normalizeGeneratedMemorySkillRecord(usage.skills[name], name, now);
1814
- record.state = "active";
1815
- record.updatedAt = now;
1816
- record.archivedAt = null;
1817
- record.archiveReason = null;
1818
- usage.skills[name] = record;
1819
- await writeGeneratedMemorySkillUsage(memoryRoot, usage);
1820
- return true;
1821
- }
1822
-
1823
- function normalizeConsolidatedUserProfile(input: string): string {
1824
- const trimmed = input.trim();
1825
- if (!trimmed) return "";
1826
- if (!trimmed.startsWith(USER_PROFILE_OPEN_TAG) || !trimmed.endsWith(USER_PROFILE_CLOSE_TAG)) {
1827
- throw new Error(
1828
- `phase2 user_md must be empty or a complete ${USER_PROFILE_OPEN_TAG}...${USER_PROFILE_CLOSE_TAG} block`,
1829
- );
1830
- }
1831
- return trimmed;
1832
- }
1833
-
1834
- function assertNoIdentityArtifactLeak(fields: ReadonlyArray<{ field: string; value: string }>): void {
1835
- for (const { field, value } of fields) {
1836
- for (const { label, pattern } of FORBIDDEN_IDENTITY_ARTIFACT_PATTERNS) {
1837
- if (pattern.test(value)) {
1838
- throw new Error(
1839
- `phase2 attempted to write approval-gated identity artifact ${label} in ${field}; ` +
1840
- `${MEMORY_ARTIFACTS.soulProposal} must be proposed only by an explicit identity-review flow`,
1841
- );
1842
- }
1843
- }
860
+ await fs.rm(path.join(skillsDir, dirent.name), { recursive: true, force: true });
1844
861
  }
1845
862
  }
1846
863
 
@@ -1922,9 +939,8 @@ function parseStage1OutputSchema(value: Record<string, unknown>): Stage1OutputSc
1922
939
  }
1923
940
 
1924
941
  function parseConsolidationOutputSchema(value: Record<string, unknown>): ConsolidationOutputSchema | undefined {
1925
- if (!hasExactKeys(value, ["memory_md", "user_md", "memory_summary", "skills"], true)) return undefined;
942
+ if (!hasExactKeys(value, ["memory_md", "memory_summary", "skills"])) return undefined;
1926
943
  if (typeof value.memory_md !== "string") return undefined;
1927
- if (!(value.user_md === undefined || typeof value.user_md === "string")) return undefined;
1928
944
  if (typeof value.memory_summary !== "string") return undefined;
1929
945
  if (!Array.isArray(value.skills)) return undefined;
1930
946
  const skills: ConsolidationSkillSchema[] = [];
@@ -1948,24 +964,11 @@ function parseConsolidationOutputSchema(value: Record<string, unknown>): Consoli
1948
964
  }
1949
965
  return {
1950
966
  memory_md: value.memory_md,
1951
- user_md: value.user_md ?? "",
1952
967
  memory_summary: value.memory_summary,
1953
968
  skills,
1954
969
  };
1955
970
  }
1956
971
 
1957
- function parseIdentityReviewOutputSchema(value: Record<string, unknown>): string | undefined {
1958
- if (!hasExactKeys(value, ["soul_proposal"])) return undefined;
1959
- if (typeof value.soul_proposal !== "string") return undefined;
1960
- const proposal = redactSecrets(value.soul_proposal).trim();
1961
- if (!proposal) return "";
1962
- if (!proposal.startsWith("<soul_proposal") || !proposal.endsWith("</soul_proposal>")) return undefined;
1963
- if (/<\s*\/?\s*soul\b/i.test(proposal)) return undefined;
1964
- if (/<\s*\/?\s*identity\b/i.test(proposal)) return undefined;
1965
- if (/<\s*\/?\s*personality\b/i.test(proposal)) return undefined;
1966
- return proposal;
1967
- }
1968
-
1969
972
  function hasExactKeys(value: Record<string, unknown>, expectedKeys: string[], allowMissing = false): boolean {
1970
973
  const sortedKeys = Object.keys(value).sort();
1971
974
  const sortedExpected = [...expectedKeys].sort();
@@ -1986,6 +989,12 @@ function redactSecrets(input: string): string {
1986
989
  /(?:sk|pk|rk|tok|key|secret|token|password)[-_A-Za-z0-9]{12,}/g,
1987
990
  /[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}/g,
1988
991
  /(?:AKIA|ASIA)[A-Z0-9]{16}/g,
992
+ // Common provider token prefixes (GitHub, npm, Slack, Google).
993
+ /(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}/g,
994
+ /github_pat_[A-Za-z0-9_]{20,}/g,
995
+ /npm_[A-Za-z0-9]{30,}/g,
996
+ /xox[baprs]-[A-Za-z0-9-]{10,}/g,
997
+ /AIza[A-Za-z0-9_-]{30,}/g,
1989
998
  ];
1990
999
  for (const pattern of patterns) {
1991
1000
  out = out.replace(pattern, "[REDACTED]");
@@ -2064,65 +1073,6 @@ function extractMessageText(message: AgentMessage): string {
2064
1073
  .join("\n");
2065
1074
  }
2066
1075
 
2067
- function extractPostTurnReviewMessages(session: AgentSession): PostTurnReviewMessage[] {
2068
- const manager = session.sessionManager as {
2069
- getEntries?: () => Array<{ type?: string; message?: { role?: unknown; content?: unknown } }>;
2070
- };
2071
- const entries = manager.getEntries?.();
2072
- if (!entries) return [];
2073
- const messages: PostTurnReviewMessage[] = [];
2074
- for (const entry of entries) {
2075
- if (entry.type !== "message") continue;
2076
- const message = entry.message;
2077
- if (!message) continue;
2078
- const role = message.role;
2079
- if (role !== "user" && role !== "assistant") continue;
2080
- const content =
2081
- role === "user" ? extractPostTurnUserText(message.content) : extractPostTurnAssistantText(message.content);
2082
- const trimmed = content.trim();
2083
- if (!trimmed) continue;
2084
- messages.push({ role, content: trimmed });
2085
- }
2086
- return messages;
2087
- }
2088
-
2089
- function extractPostTurnUserText(content: unknown): string {
2090
- if (typeof content === "string") return content;
2091
- if (!Array.isArray(content)) return "";
2092
- const parts: string[] = [];
2093
- for (const item of content) {
2094
- if (!item || typeof item !== "object") continue;
2095
- const block = item as { type?: unknown; text?: unknown };
2096
- if (block.type === "text" && typeof block.text === "string") {
2097
- parts.push(block.text);
2098
- }
2099
- }
2100
- return parts.join("\n");
2101
- }
2102
-
2103
- function extractPostTurnAssistantText(content: unknown): string {
2104
- if (!Array.isArray(content)) return "";
2105
- const parts: string[] = [];
2106
- for (const item of content) {
2107
- if (!item || typeof item !== "object") continue;
2108
- const block = item as { type?: unknown; text?: unknown };
2109
- if (block.type === "text" && typeof block.text === "string") {
2110
- parts.push(block.text);
2111
- }
2112
- }
2113
- return parts.join("\n");
2114
- }
2115
-
2116
- function buildPostTurnReviewThreadId(sessionId: string | undefined, userTurns: number): string {
2117
- const rawId = sessionId?.trim() || "unknown-session";
2118
- const safeSessionId =
2119
- rawId
2120
- .replace(/[^A-Za-z0-9_-]+/g, "_")
2121
- .replace(/^_+|_+$/g, "")
2122
- .slice(0, 80) || "unknown-session";
2123
- return `${POST_TURN_REVIEW_THREAD_PREFIX}-${safeSessionId}-${userTurns}`;
2124
- }
2125
-
2126
1076
  function truncateByApproxTokens(text: string, tokenLimit: number): string {
2127
1077
  if (tokenLimit <= 0) return "";
2128
1078
  const maxChars = tokenLimit * 4;
@@ -2134,7 +1084,9 @@ function truncateByApproxTokens(text: string, tokenLimit: number): string {
2134
1084
 
2135
1085
  function computeModelTokenBudget(model: Model, config: MemoryRuntimeConfig): number {
2136
1086
  const maxTokens =
2137
- Number.isFinite(model.contextWindow) && model.contextWindow > 0 ? model.contextWindow : config.fallbackTokenLimit;
1087
+ model.contextWindow !== null && Number.isFinite(model.contextWindow) && model.contextWindow > 0
1088
+ ? model.contextWindow
1089
+ : config.fallbackTokenLimit;
2138
1090
  return Math.max(2048, Math.floor(maxTokens));
2139
1091
  }
2140
1092
 
@@ -2148,7 +1100,7 @@ async function resolveMemoryModel(options: {
2148
1100
  if (requestedModel) {
2149
1101
  const resolved = resolveModelRoleValue(requestedModel, modelRegistry.getAll(), {
2150
1102
  settings: session.settings,
2151
- matchPreferences: { usageOrder: session.settings.getStorage()?.getModelUsageOrder() },
1103
+ matchPreferences: getModelMatchPreferences(session.settings),
2152
1104
  modelRegistry,
2153
1105
  });
2154
1106
  if (resolved.model) return resolved.model;
@@ -2157,28 +1109,8 @@ async function resolveMemoryModel(options: {
2157
1109
  }
2158
1110
 
2159
1111
  function loadMemoryConfig(settings: Settings): MemoryRuntimeConfig {
2160
- const selfImprovementMode = settings.get("selfImprovement.mode") ?? DEFAULTS.selfImprovementMode;
2161
- const backgroundReviewMode = settings.get("selfImprovement.backgroundReviewMode") ?? DEFAULTS.backgroundReviewMode;
2162
- const backgroundReviewEveryNTurns =
2163
- settings.get("selfImprovement.backgroundReviewEveryNTurns") ?? DEFAULTS.backgroundReviewEveryNTurns;
2164
- const identityReviewMode = settings.get("selfImprovement.identityReviewMode") ?? DEFAULTS.identityReviewMode;
2165
- const curatorMode = settings.get("selfImprovement.curatorMode") ?? DEFAULTS.curatorMode;
2166
- const generatedSkillStaleAfterDays =
2167
- settings.get("selfImprovement.generatedSkillStaleAfterDays") ?? DEFAULTS.generatedSkillStaleAfterDays;
2168
- const generatedSkillArchiveAfterDays =
2169
- settings.get("selfImprovement.generatedSkillArchiveAfterDays") ?? DEFAULTS.generatedSkillArchiveAfterDays;
2170
- const localMemoryRequested = settings.get("memory.backend") === "local" || settings.get("memories.enabled") === true;
2171
1112
  return {
2172
- enabled: selfImprovementMode !== "off" && localMemoryRequested,
2173
- selfImprovementMode,
2174
- backgroundReviewMode,
2175
- backgroundReviewEveryNTurns: Number.isFinite(backgroundReviewEveryNTurns)
2176
- ? Math.max(0, Math.floor(backgroundReviewEveryNTurns))
2177
- : DEFAULTS.backgroundReviewEveryNTurns,
2178
- identityReviewMode,
2179
- curatorMode,
2180
- generatedSkillStaleAfterDays,
2181
- generatedSkillArchiveAfterDays,
1113
+ enabled: settings.get("memory.backend") === "local" || settings.get("memories.enabled") === true,
2182
1114
  maxRolloutsPerStartup: settings.get("memories.maxRolloutsPerStartup") ?? DEFAULTS.maxRolloutsPerStartup,
2183
1115
  maxRolloutAgeDays: settings.get("memories.maxRolloutAgeDays") ?? DEFAULTS.maxRolloutAgeDays,
2184
1116
  minRolloutIdleHours: settings.get("memories.minRolloutIdleHours") ?? DEFAULTS.minRolloutIdleHours,
@@ -2202,6 +1134,120 @@ export function getMemoryRoot(agentDir: string, cwd: string): string {
2202
1134
  return path.join(getMemoriesDir(agentDir), encodeProjectPath(cwd));
2203
1135
  }
2204
1136
 
1137
+ /**
1138
+ * Filename of the captured-lessons file under a project's memory root.
1139
+ *
1140
+ * Written by the `learn` tool via {@link saveLearnedLesson} and read back by
1141
+ * {@link buildMemoryToolDeveloperInstructions}. Deliberately distinct from the
1142
+ * consolidation artifacts (`MEMORY.md`, `memory_summary.md`, `skills/`) so a
1143
+ * consolidation pass never clobbers manually captured lessons.
1144
+ */
1145
+ const LEARNED_LESSONS_FILE = "learned.md";
1146
+ /** Newest-first cap on retained lessons, bounding file growth by entry count. */
1147
+ const MAX_LEARNED_LESSONS = 100;
1148
+ /** Per-field char caps so a single huge capture can't bloat learned.md. */
1149
+ const MAX_LEARNED_CONTENT_CHARS = 2000;
1150
+ const MAX_LEARNED_CONTEXT_CHARS = 400;
1151
+
1152
+ /**
1153
+ * Strip prompt-injection vectors from a single line of lesson text: control/
1154
+ * format chars, angle brackets (`</skills>`), backticks, and `~~~` fences, then
1155
+ * collapse whitespace. Applied on BOTH write and read (the block renders
1156
+ * unescaped into the system prompt), mirroring managed-skill descriptions.
1157
+ */
1158
+ function neutralizeInjection(text: string): string {
1159
+ return text
1160
+ .replace(/[\p{Cc}\p{Cf}]/gu, " ")
1161
+ .replace(/[<>`]/g, "")
1162
+ .replace(/~{2,}/g, "~")
1163
+ .replace(/\s+/g, " ")
1164
+ .trim();
1165
+ }
1166
+
1167
+ /** Slice to `maxChars`, dropping a trailing unpaired high surrogate. */
1168
+ function boundChars(text: string, maxChars: number): string {
1169
+ if (text.length <= maxChars) return text;
1170
+ const sliced = text.slice(0, maxChars);
1171
+ return /[\uD800-\uDBFF]$/.test(sliced) ? sliced.slice(0, -1) : sliced;
1172
+ }
1173
+
1174
+ /**
1175
+ * Normalize one lesson field for storage: neutralize injection delimiters
1176
+ * first, then redact secrets, then bound the length.
1177
+ */
1178
+ function normalizeLearnedText(text: string, maxChars: number): string {
1179
+ return boundChars(redactSecrets(neutralizeInjection(text)).trim(), maxChars);
1180
+ }
1181
+
1182
+ /** Per-path write chains serializing `learned.md` read-modify-write. */
1183
+ const learnedWriteChains = new Map<string, Promise<unknown>>();
1184
+
1185
+ /**
1186
+ * Append one lesson to the project's `learned.md` (newest-first, deduped,
1187
+ * capped, secret-redacted, injection-neutralized). The file backs the `learn`
1188
+ * tool when `memory.backend` is `local`.
1189
+ */
1190
+ export async function saveLearnedLesson(
1191
+ agentDir: string,
1192
+ cwd: string,
1193
+ input: MemoryBackendSaveInput,
1194
+ ): Promise<MemoryBackendSaveResult> {
1195
+ const content = normalizeLearnedText(input.content, MAX_LEARNED_CONTENT_CHARS);
1196
+ if (!content) {
1197
+ return { backend: "local", stored: 0, message: "Empty lesson; nothing stored." };
1198
+ }
1199
+ const context = input.context ? normalizeLearnedText(input.context, MAX_LEARNED_CONTEXT_CHARS) : "";
1200
+ const line = context ? `- ${content} _(context: ${context})_` : `- ${content}`;
1201
+ const filePath = path.join(getMemoryRoot(agentDir, cwd), LEARNED_LESSONS_FILE);
1202
+
1203
+ // Serialize the read-modify-write per file: parallel `learn` calls (sibling
1204
+ // subagents, or two shared tool calls in one turn) share the project memory
1205
+ // root, so an unguarded RMW would let the last writer drop the other's lesson.
1206
+ const run = (learnedWriteChains.get(filePath) ?? Promise.resolve()).then(() => appendLearnedLine(filePath, line));
1207
+ const guarded = run.catch(() => {});
1208
+ learnedWriteChains.set(filePath, guarded);
1209
+ try {
1210
+ await run;
1211
+ } finally {
1212
+ if (learnedWriteChains.get(filePath) === guarded) learnedWriteChains.delete(filePath);
1213
+ }
1214
+ return { backend: "local", stored: 1, message: `Lesson saved to ${LEARNED_LESSONS_FILE}.` };
1215
+ }
1216
+
1217
+ async function appendLearnedLine(filePath: string, line: string): Promise<void> {
1218
+ let existing = "";
1219
+ try {
1220
+ existing = await Bun.file(filePath).text();
1221
+ } catch (err) {
1222
+ if (!isEnoent(err)) throw err;
1223
+ }
1224
+ const prior = existing
1225
+ .split("\n")
1226
+ .map(l => l.trim())
1227
+ .filter(l => l.startsWith("- ") && l !== line);
1228
+ const lessons = [line, ...prior].slice(0, MAX_LEARNED_LESSONS);
1229
+ await Bun.write(filePath, `${lessons.join("\n")}\n`);
1230
+ }
1231
+
1232
+ /**
1233
+ * Read `learned.md`, neutralizing each line on read too — a hand-edited or
1234
+ * pre-existing file bypasses write-time normalization and the block renders
1235
+ * unescaped into the system prompt. Returns "" when absent/unreadable.
1236
+ */
1237
+ async function readLearnedLessons(memoryRoot: string): Promise<string> {
1238
+ let raw = "";
1239
+ try {
1240
+ raw = (await Bun.file(path.join(memoryRoot, LEARNED_LESSONS_FILE)).text()).trim();
1241
+ } catch {
1242
+ return "";
1243
+ }
1244
+ if (!raw) return "";
1245
+ return raw
1246
+ .split("\n")
1247
+ .map(line => redactSecrets(neutralizeInjection(line)))
1248
+ .join("\n");
1249
+ }
1250
+
2205
1251
  function encodeProjectPath(cwd: string): string {
2206
1252
  return `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
2207
1253
  }