@oh-my-pi/pi-coding-agent 15.12.3 → 15.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (457) hide show
  1. package/CHANGELOG.md +347 -7
  2. package/dist/cli.js +1615 -1231
  3. package/dist/types/async/job-manager.d.ts +15 -0
  4. package/dist/types/autolearn/controller.d.ts +25 -0
  5. package/dist/types/autolearn/managed-skills.d.ts +45 -0
  6. package/dist/types/autoresearch/state.d.ts +1 -1
  7. package/dist/types/autoresearch/tools/init-experiment.d.ts +1 -1
  8. package/dist/types/autoresearch/tools/log-experiment.d.ts +1 -1
  9. package/dist/types/autoresearch/tools/run-experiment.d.ts +1 -1
  10. package/dist/types/autoresearch/tools/update-notes.d.ts +1 -1
  11. package/dist/types/autoresearch/types.d.ts +1 -1
  12. package/dist/types/cli/args.d.ts +19 -2
  13. package/dist/types/cli/models-cli.d.ts +49 -0
  14. package/dist/types/cli/session-picker.d.ts +1 -1
  15. package/dist/types/cli/setup-cli.d.ts +1 -1
  16. package/dist/types/cli/setup-model-picker.d.ts +14 -0
  17. package/dist/types/collab/protocol.d.ts +1 -1
  18. package/dist/types/commands/launch.d.ts +0 -3
  19. package/dist/types/commands/models.d.ts +33 -0
  20. package/dist/types/commands/say.d.ts +24 -0
  21. package/dist/types/commands/token.d.ts +25 -0
  22. package/dist/types/commit/agentic/tools/analyze-file.d.ts +1 -1
  23. package/dist/types/commit/agentic/tools/git-file-diff.d.ts +1 -1
  24. package/dist/types/commit/agentic/tools/git-hunk.d.ts +1 -1
  25. package/dist/types/commit/agentic/tools/git-overview.d.ts +1 -1
  26. package/dist/types/commit/agentic/tools/propose-changelog.d.ts +1 -1
  27. package/dist/types/commit/agentic/tools/propose-commit.d.ts +1 -1
  28. package/dist/types/commit/agentic/tools/recent-commits.d.ts +1 -1
  29. package/dist/types/commit/agentic/tools/schemas.d.ts +1 -1
  30. package/dist/types/commit/agentic/tools/split-commit.d.ts +1 -1
  31. package/dist/types/commit/changelog/generate.d.ts +1 -1
  32. package/dist/types/commit/shared-llm.d.ts +1 -1
  33. package/dist/types/config/keybindings.d.ts +3 -3
  34. package/dist/types/config/model-registry.d.ts +17 -0
  35. package/dist/types/config/models-config-schema.d.ts +13 -1
  36. package/dist/types/config/models-config.d.ts +8 -2
  37. package/dist/types/config/settings-schema.d.ts +281 -58
  38. package/dist/types/edit/hashline/params.d.ts +1 -1
  39. package/dist/types/edit/modes/apply-patch.d.ts +1 -1
  40. package/dist/types/edit/modes/patch.d.ts +1 -1
  41. package/dist/types/edit/modes/replace.d.ts +1 -1
  42. package/dist/types/export/html/index.d.ts +2 -1
  43. package/dist/types/extensibility/custom-commands/types.d.ts +2 -2
  44. package/dist/types/extensibility/custom-tools/types.d.ts +2 -2
  45. package/dist/types/extensibility/extensions/model-api.d.ts +17 -0
  46. package/dist/types/extensibility/extensions/runner.d.ts +3 -1
  47. package/dist/types/extensibility/extensions/types.d.ts +49 -3
  48. package/dist/types/extensibility/hooks/index.d.ts +2 -1
  49. package/dist/types/extensibility/hooks/types.d.ts +2 -2
  50. package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +9 -0
  51. package/dist/types/extensibility/plugins/loader.d.ts +11 -0
  52. package/dist/types/extensibility/shared-events.d.ts +1 -1
  53. package/dist/types/extensibility/skills.d.ts +10 -0
  54. package/dist/types/goals/guided-setup.d.ts +18 -0
  55. package/dist/types/goals/state.d.ts +1 -1
  56. package/dist/types/goals/tools/goal-tool.d.ts +1 -1
  57. package/dist/types/hindsight/transcript.d.ts +1 -1
  58. package/dist/types/index.d.ts +5 -0
  59. package/dist/types/internal-urls/local-protocol.d.ts +4 -2
  60. package/dist/types/lsp/types.d.ts +1 -1
  61. package/dist/types/main.d.ts +4 -3
  62. package/dist/types/mcp/manager.d.ts +8 -0
  63. package/dist/types/mcp/startup-events.d.ts +11 -0
  64. package/dist/types/memories/index.d.ts +7 -0
  65. package/dist/types/memory-backend/local-backend.d.ts +4 -3
  66. package/dist/types/mnemopi/config.d.ts +28 -0
  67. package/dist/types/modes/acp/acp-agent.d.ts +1 -2
  68. package/dist/types/modes/components/agent-hub.d.ts +6 -0
  69. package/dist/types/modes/components/assistant-message.d.ts +1 -2
  70. package/dist/types/modes/components/compaction-summary-message.d.ts +15 -1
  71. package/dist/types/modes/components/custom-editor.d.ts +39 -1
  72. package/dist/types/modes/components/custom-editor.test.d.ts +1 -0
  73. package/dist/types/modes/components/index.d.ts +1 -0
  74. package/dist/types/modes/components/logout-account-selector.d.ts +8 -0
  75. package/dist/types/modes/components/session-selector.d.ts +1 -1
  76. package/dist/types/modes/components/status-line/component.d.ts +9 -5
  77. package/dist/types/modes/components/status-line/types.d.ts +2 -1
  78. package/dist/types/modes/components/tool-execution.d.ts +26 -16
  79. package/dist/types/modes/components/transcript-container.d.ts +23 -2
  80. package/dist/types/modes/components/tree-selector.d.ts +1 -1
  81. package/dist/types/modes/components/usage-row.d.ts +3 -0
  82. package/dist/types/modes/controllers/command-controller.d.ts +2 -2
  83. package/dist/types/modes/controllers/event-controller.d.ts +0 -17
  84. package/dist/types/modes/controllers/input-controller.d.ts +14 -0
  85. package/dist/types/modes/controllers/selector-controller.d.ts +3 -1
  86. package/dist/types/modes/gradient-highlight.d.ts +9 -4
  87. package/dist/types/modes/image-references.d.ts +6 -0
  88. package/dist/types/modes/interactive-mode.d.ts +27 -6
  89. package/dist/types/modes/magic-keywords.d.ts +13 -1
  90. package/dist/types/modes/rpc/rpc-mode.d.ts +35 -1
  91. package/dist/types/modes/rpc/rpc-types.d.ts +9 -1
  92. package/dist/types/modes/runtime-init.d.ts +4 -0
  93. package/dist/types/modes/theme/theme.d.ts +13 -2
  94. package/dist/types/modes/types.d.ts +8 -7
  95. package/dist/types/modes/utils/ui-helpers.d.ts +1 -1
  96. package/dist/types/registry/agent-registry.d.ts +17 -0
  97. package/dist/types/secrets/obfuscator.d.ts +1 -1
  98. package/dist/types/session/agent-session.d.ts +28 -35
  99. package/dist/types/session/agent-storage.d.ts +2 -1
  100. package/dist/types/session/indexed-session-storage.d.ts +3 -3
  101. package/dist/types/session/messages.d.ts +8 -10
  102. package/dist/types/session/session-context.d.ts +39 -0
  103. package/dist/types/session/session-entries.d.ts +159 -0
  104. package/dist/types/session/session-listing.d.ts +69 -0
  105. package/dist/types/session/session-loader.d.ts +16 -0
  106. package/dist/types/session/session-manager.d.ts +85 -462
  107. package/dist/types/session/session-migrations.d.ts +12 -0
  108. package/dist/types/session/session-paths.d.ts +25 -0
  109. package/dist/types/session/session-persistence.d.ts +8 -0
  110. package/dist/types/session/session-storage.d.ts +11 -7
  111. package/dist/types/session/snapcompact-inline.d.ts +12 -1
  112. package/dist/types/session/snapcompact-savings-journal.d.ts +46 -0
  113. package/dist/types/session/tool-choice-queue.d.ts +6 -6
  114. package/dist/types/slash-commands/helpers/logout.d.ts +15 -0
  115. package/dist/types/stt/asr-client.d.ts +90 -0
  116. package/dist/types/stt/asr-protocol.d.ts +97 -0
  117. package/dist/types/stt/asr-worker.d.ts +2 -0
  118. package/dist/types/stt/downloader.d.ts +38 -0
  119. package/dist/types/stt/endpointer.d.ts +59 -0
  120. package/dist/types/stt/index.d.ts +5 -1
  121. package/dist/types/stt/models.d.ts +120 -0
  122. package/dist/types/stt/recorder.d.ts +17 -0
  123. package/dist/types/stt/stt-controller.d.ts +6 -0
  124. package/dist/types/stt/transcriber.d.ts +5 -7
  125. package/dist/types/stt/wav.d.ts +29 -0
  126. package/dist/types/system-prompt.d.ts +4 -0
  127. package/dist/types/task/executor.d.ts +2 -0
  128. package/dist/types/task/index.d.ts +9 -1
  129. package/dist/types/task/types.d.ts +37 -1
  130. package/dist/types/tools/ask.d.ts +1 -1
  131. package/dist/types/tools/ast-edit.d.ts +1 -1
  132. package/dist/types/tools/ast-grep.d.ts +1 -1
  133. package/dist/types/tools/bash.d.ts +3 -3
  134. package/dist/types/tools/browser/cmux/cmux-tab.d.ts +202 -0
  135. package/dist/types/tools/browser/cmux/rpc.d.ts +70 -0
  136. package/dist/types/tools/browser/cmux/socket-client.d.ts +19 -0
  137. package/dist/types/tools/browser/registry.d.ts +16 -3
  138. package/dist/types/tools/browser/render.d.ts +2 -0
  139. package/dist/types/tools/browser/tab-protocol.d.ts +2 -0
  140. package/dist/types/tools/browser/tab-supervisor.d.ts +16 -4
  141. package/dist/types/tools/browser.d.ts +3 -1
  142. package/dist/types/tools/checkpoint.d.ts +1 -1
  143. package/dist/types/tools/debug.d.ts +1 -1
  144. package/dist/types/tools/eval-render.d.ts +1 -1
  145. package/dist/types/tools/eval.d.ts +1 -1
  146. package/dist/types/tools/find.d.ts +1 -1
  147. package/dist/types/tools/gh.d.ts +1 -1
  148. package/dist/types/tools/image-gen.d.ts +1 -1
  149. package/dist/types/tools/index.d.ts +14 -2
  150. package/dist/types/tools/inspect-image.d.ts +1 -1
  151. package/dist/types/tools/irc.d.ts +2 -1
  152. package/dist/types/tools/job.d.ts +1 -1
  153. package/dist/types/tools/learn.d.ts +51 -0
  154. package/dist/types/tools/manage-skill.d.ts +40 -0
  155. package/dist/types/tools/memory-edit.d.ts +1 -1
  156. package/dist/types/tools/memory-recall.d.ts +1 -1
  157. package/dist/types/tools/memory-reflect.d.ts +1 -1
  158. package/dist/types/tools/memory-retain.d.ts +1 -1
  159. package/dist/types/tools/plan-mode-guard.d.ts +10 -0
  160. package/dist/types/tools/read.d.ts +1 -1
  161. package/dist/types/tools/render-mermaid.d.ts +1 -1
  162. package/dist/types/tools/renderers.d.ts +7 -11
  163. package/dist/types/tools/resolve.d.ts +1 -1
  164. package/dist/types/tools/review.d.ts +1 -1
  165. package/dist/types/tools/search-tool-bm25.d.ts +1 -1
  166. package/dist/types/tools/search.d.ts +1 -1
  167. package/dist/types/tools/ssh.d.ts +2 -2
  168. package/dist/types/tools/todo.d.ts +2 -2
  169. package/dist/types/tools/tts.d.ts +26 -1
  170. package/dist/types/tools/write.d.ts +2 -2
  171. package/dist/types/tts/downloader.d.ts +20 -0
  172. package/dist/types/tts/index.d.ts +8 -0
  173. package/dist/types/tts/models.d.ts +82 -0
  174. package/dist/types/tts/player.d.ts +32 -0
  175. package/dist/types/tts/runtime.d.ts +6 -0
  176. package/dist/types/tts/streaming-player.d.ts +41 -0
  177. package/dist/types/tts/tts-client.d.ts +93 -0
  178. package/dist/types/tts/tts-protocol.d.ts +95 -0
  179. package/dist/types/tts/tts-worker.d.ts +2 -0
  180. package/dist/types/tts/vocalizer.d.ts +41 -0
  181. package/dist/types/tts/wav.d.ts +8 -0
  182. package/dist/types/utils/clipboard.d.ts +4 -3
  183. package/dist/types/utils/image-loading.d.ts +18 -1
  184. package/dist/types/utils/thinking-display.d.ts +17 -0
  185. package/dist/types/utils/tool-choice.d.ts +8 -0
  186. package/dist/types/utils/tools-manager.d.ts +2 -1
  187. package/dist/types/utils/tools-manager.test.d.ts +1 -0
  188. package/dist/types/web/scrapers/github.d.ts +1 -1
  189. package/dist/types/web/search/index.d.ts +1 -1
  190. package/package.json +17 -16
  191. package/src/async/job-manager.ts +49 -0
  192. package/src/autolearn/controller.ts +139 -0
  193. package/src/autolearn/managed-skills.ts +257 -0
  194. package/src/autoresearch/state.ts +1 -1
  195. package/src/autoresearch/storage.ts +2 -1
  196. package/src/autoresearch/tools/init-experiment.ts +1 -1
  197. package/src/autoresearch/tools/log-experiment.ts +1 -1
  198. package/src/autoresearch/tools/run-experiment.ts +1 -1
  199. package/src/autoresearch/tools/update-notes.ts +1 -1
  200. package/src/autoresearch/types.ts +1 -1
  201. package/src/cli/args.ts +56 -10
  202. package/src/cli/auth-gateway-cli.ts +1 -1
  203. package/src/cli/bench-cli.ts +1 -1
  204. package/src/cli/dry-balance-cli.ts +1 -1
  205. package/src/cli/models-cli.ts +427 -0
  206. package/src/cli/session-picker.ts +2 -1
  207. package/src/cli/setup-cli.ts +148 -47
  208. package/src/cli/setup-model-picker.ts +43 -0
  209. package/src/cli-commands.ts +3 -0
  210. package/src/cli.ts +45 -13
  211. package/src/collab/host.ts +10 -13
  212. package/src/collab/protocol.ts +1 -1
  213. package/src/commands/launch.ts +0 -3
  214. package/src/commands/models.ts +61 -0
  215. package/src/commands/say.ts +102 -0
  216. package/src/commands/setup.ts +1 -1
  217. package/src/commands/token.ts +89 -0
  218. package/src/commit/agentic/tools/analyze-file.ts +4 -1
  219. package/src/commit/agentic/tools/git-file-diff.ts +1 -1
  220. package/src/commit/agentic/tools/git-hunk.ts +1 -1
  221. package/src/commit/agentic/tools/git-overview.ts +1 -1
  222. package/src/commit/agentic/tools/propose-changelog.ts +1 -1
  223. package/src/commit/agentic/tools/propose-commit.ts +1 -1
  224. package/src/commit/agentic/tools/recent-commits.ts +1 -1
  225. package/src/commit/agentic/tools/schemas.ts +1 -1
  226. package/src/commit/agentic/tools/split-commit.ts +1 -1
  227. package/src/commit/analysis/summary.ts +1 -1
  228. package/src/commit/changelog/generate.ts +1 -1
  229. package/src/commit/shared-llm.ts +1 -1
  230. package/src/config/keybindings.ts +2 -2
  231. package/src/config/model-discovery.ts +11 -5
  232. package/src/config/model-registry.ts +79 -21
  233. package/src/config/model-resolver.ts +2 -2
  234. package/src/config/models-config-schema.ts +5 -2
  235. package/src/config/models-config.ts +2 -1
  236. package/src/config/settings-schema.ts +266 -32
  237. package/src/config/settings.ts +10 -0
  238. package/src/discovery/builtin.ts +23 -1
  239. package/src/discovery/claude-plugins.ts +44 -5
  240. package/src/discovery/helpers.ts +41 -1
  241. package/src/edit/hashline/params.ts +1 -1
  242. package/src/edit/modes/apply-patch.ts +1 -1
  243. package/src/edit/modes/patch.ts +1 -1
  244. package/src/edit/modes/replace.ts +1 -1
  245. package/src/eval/__tests__/budget-bridge.test.ts +1 -1
  246. package/src/eval/agent-bridge.ts +1 -1
  247. package/src/eval/completion-bridge.ts +1 -1
  248. package/src/eval/js/shared/prelude.txt +69 -17
  249. package/src/export/html/index.ts +3 -6
  250. package/src/export/html/template.js +24 -2
  251. package/src/export/html/tool-views.generated.js +2 -2
  252. package/src/extensibility/custom-commands/loader.ts +1 -1
  253. package/src/extensibility/custom-commands/types.ts +2 -2
  254. package/src/extensibility/custom-tools/loader.ts +1 -1
  255. package/src/extensibility/custom-tools/types.ts +2 -2
  256. package/src/extensibility/extensions/loader.ts +2 -2
  257. package/src/extensibility/extensions/model-api.ts +41 -0
  258. package/src/extensibility/extensions/runner.ts +4 -0
  259. package/src/extensibility/extensions/types.ts +54 -3
  260. package/src/extensibility/extensions/wrapper.ts +41 -5
  261. package/src/extensibility/hooks/index.ts +2 -1
  262. package/src/extensibility/hooks/loader.ts +1 -1
  263. package/src/extensibility/hooks/types.ts +2 -2
  264. package/src/extensibility/plugins/legacy-pi-compat.ts +43 -13
  265. package/src/extensibility/plugins/loader.ts +30 -19
  266. package/src/extensibility/plugins/manager.ts +221 -90
  267. package/src/extensibility/shared-events.ts +1 -1
  268. package/src/extensibility/skills.ts +101 -5
  269. package/src/goals/guided-setup.ts +133 -0
  270. package/src/goals/state.ts +1 -1
  271. package/src/goals/tools/goal-tool.ts +1 -1
  272. package/src/hindsight/transcript.ts +1 -1
  273. package/src/index.ts +5 -0
  274. package/src/internal-urls/docs-index.generated.ts +13 -10
  275. package/src/internal-urls/history-protocol.ts +1 -1
  276. package/src/internal-urls/local-protocol.ts +29 -7
  277. package/src/lsp/types.ts +1 -1
  278. package/src/main.ts +27 -32
  279. package/src/mcp/config-writer.ts +7 -3
  280. package/src/mcp/manager.ts +11 -0
  281. package/src/mcp/startup-events.ts +21 -0
  282. package/src/mcp/transports/stdio.ts +2 -1
  283. package/src/memories/index.ts +149 -12
  284. package/src/memories/storage.ts +2 -1
  285. package/src/memory-backend/local-backend.ts +11 -5
  286. package/src/mnemopi/backend.ts +1 -0
  287. package/src/mnemopi/config.ts +112 -12
  288. package/src/modes/acp/acp-agent.ts +8 -53
  289. package/src/modes/acp/acp-event-mapper.ts +5 -1
  290. package/src/modes/components/agent-hub.ts +51 -5
  291. package/src/modes/components/assistant-message.ts +12 -44
  292. package/src/modes/components/compaction-summary-message.ts +125 -26
  293. package/src/modes/components/custom-editor.test.ts +96 -0
  294. package/src/modes/components/custom-editor.ts +164 -8
  295. package/src/modes/components/index.ts +1 -0
  296. package/src/modes/components/logout-account-selector.ts +130 -0
  297. package/src/modes/components/mcp-add-wizard.ts +1 -1
  298. package/src/modes/components/model-selector.ts +2 -2
  299. package/src/modes/components/session-selector.ts +1 -1
  300. package/src/modes/components/settings-defs.ts +7 -0
  301. package/src/modes/components/status-line/component.ts +54 -157
  302. package/src/modes/components/status-line/segments.ts +1 -1
  303. package/src/modes/components/status-line/types.ts +2 -1
  304. package/src/modes/components/tool-execution.ts +82 -43
  305. package/src/modes/components/transcript-container.ts +70 -1
  306. package/src/modes/components/tree-selector.ts +1 -1
  307. package/src/modes/components/usage-row.ts +18 -0
  308. package/src/modes/components/user-message.ts +4 -2
  309. package/src/modes/controllers/command-controller.ts +14 -16
  310. package/src/modes/controllers/event-controller.ts +101 -73
  311. package/src/modes/controllers/extension-ui-controller.ts +6 -0
  312. package/src/modes/controllers/input-controller.ts +311 -57
  313. package/src/modes/controllers/mcp-command-controller.ts +44 -3
  314. package/src/modes/controllers/selector-controller.ts +68 -12
  315. package/src/modes/controllers/streaming-reveal.ts +4 -3
  316. package/src/modes/gradient-highlight.ts +21 -9
  317. package/src/modes/image-references.ts +20 -0
  318. package/src/modes/interactive-mode.ts +288 -48
  319. package/src/modes/magic-keywords.ts +27 -5
  320. package/src/modes/rpc/rpc-mode.ts +146 -14
  321. package/src/modes/rpc/rpc-subagents.ts +2 -2
  322. package/src/modes/rpc/rpc-types.ts +8 -2
  323. package/src/modes/runtime-init.ts +28 -3
  324. package/src/modes/theme/theme.ts +99 -51
  325. package/src/modes/types.ts +6 -7
  326. package/src/modes/utils/hotkeys-markdown.ts +1 -1
  327. package/src/modes/utils/ui-helpers.ts +36 -7
  328. package/src/priority.json +5 -1
  329. package/src/prompts/agents/task.md +1 -0
  330. package/src/prompts/goals/guided-goal-interview.md +8 -0
  331. package/src/prompts/goals/guided-goal-system.md +12 -0
  332. package/src/prompts/memories/read-path.md +6 -0
  333. package/src/prompts/system/autolearn-guidance-learn.md +1 -0
  334. package/src/prompts/system/autolearn-guidance.md +7 -0
  335. package/src/prompts/system/autolearn-nudge.md +3 -0
  336. package/src/prompts/system/eager-task.md +7 -0
  337. package/src/prompts/system/eager-todo.md +11 -6
  338. package/src/prompts/system/empty-stop-retry.md +4 -6
  339. package/src/prompts/system/subagent-system-prompt.md +4 -0
  340. package/src/prompts/system/system-prompt.md +10 -5
  341. package/src/prompts/system/title-marker-instruction.md +1 -0
  342. package/src/prompts/system/title-system-marker.md +16 -0
  343. package/src/prompts/tools/job.md +1 -0
  344. package/src/prompts/tools/learn.md +7 -0
  345. package/src/prompts/tools/manage-skill.md +9 -0
  346. package/src/prompts/tools/task.md +3 -0
  347. package/src/registry/agent-registry.ts +30 -0
  348. package/src/sdk.ts +103 -43
  349. package/src/secrets/obfuscator.ts +1 -1
  350. package/src/session/agent-session.ts +331 -318
  351. package/src/session/agent-storage.ts +18 -9
  352. package/src/session/history-storage.ts +3 -2
  353. package/src/session/indexed-session-storage.ts +7 -10
  354. package/src/session/messages.ts +9 -11
  355. package/src/session/session-context.ts +352 -0
  356. package/src/session/session-dump-format.ts +4 -2
  357. package/src/session/session-entries.ts +194 -0
  358. package/src/session/session-listing.ts +588 -0
  359. package/src/session/session-loader.ts +106 -0
  360. package/src/session/session-manager.ts +968 -3064
  361. package/src/session/session-migrations.ts +78 -0
  362. package/src/session/session-paths.ts +193 -0
  363. package/src/session/session-persistence.ts +131 -0
  364. package/src/session/session-storage.ts +91 -30
  365. package/src/session/snapcompact-inline.ts +21 -1
  366. package/src/session/snapcompact-savings-journal.ts +113 -0
  367. package/src/session/tool-choice-queue.ts +23 -11
  368. package/src/slash-commands/builtin-registry.ts +40 -4
  369. package/src/slash-commands/helpers/logout.ts +88 -0
  370. package/src/stt/asr-client.ts +520 -0
  371. package/src/stt/asr-protocol.ts +65 -0
  372. package/src/stt/asr-worker.ts +790 -0
  373. package/src/stt/downloader.ts +107 -47
  374. package/src/stt/endpointer.ts +259 -0
  375. package/src/stt/index.ts +5 -1
  376. package/src/stt/models.ts +150 -0
  377. package/src/stt/recorder.ts +247 -60
  378. package/src/stt/stt-controller.ts +201 -22
  379. package/src/stt/transcriber.ts +37 -68
  380. package/src/stt/wav.ts +173 -0
  381. package/src/system-prompt.ts +8 -0
  382. package/src/task/agents.ts +1 -2
  383. package/src/task/executor.ts +49 -15
  384. package/src/task/index.ts +60 -6
  385. package/src/task/render.ts +83 -8
  386. package/src/task/types.ts +54 -1
  387. package/src/tools/ask.ts +9 -1
  388. package/src/tools/ast-edit.ts +1 -1
  389. package/src/tools/ast-grep.ts +1 -1
  390. package/src/tools/bash.ts +5 -4
  391. package/src/tools/browser/cmux/cmux-tab.ts +1264 -0
  392. package/src/tools/browser/cmux/rpc.ts +156 -0
  393. package/src/tools/browser/cmux/socket-client.ts +309 -0
  394. package/src/tools/browser/registry.ts +37 -3
  395. package/src/tools/browser/render.ts +6 -1
  396. package/src/tools/browser/tab-protocol.ts +2 -0
  397. package/src/tools/browser/tab-supervisor.ts +189 -18
  398. package/src/tools/browser/tab-worker.ts +1 -1
  399. package/src/tools/browser.ts +16 -1
  400. package/src/tools/checkpoint.ts +1 -1
  401. package/src/tools/debug.ts +1 -1
  402. package/src/tools/eval-render.ts +4 -3
  403. package/src/tools/eval.ts +11 -6
  404. package/src/tools/fetch.ts +13 -2
  405. package/src/tools/find.ts +1 -1
  406. package/src/tools/gh.ts +1 -1
  407. package/src/tools/github-cache.ts +2 -1
  408. package/src/tools/image-gen.ts +1 -1
  409. package/src/tools/index.ts +43 -5
  410. package/src/tools/inspect-image.ts +3 -1
  411. package/src/tools/irc.ts +11 -3
  412. package/src/tools/job.ts +15 -3
  413. package/src/tools/learn.ts +144 -0
  414. package/src/tools/manage-skill.ts +104 -0
  415. package/src/tools/memory-edit.ts +1 -1
  416. package/src/tools/memory-recall.ts +1 -1
  417. package/src/tools/memory-reflect.ts +1 -1
  418. package/src/tools/memory-retain.ts +1 -1
  419. package/src/tools/plan-mode-guard.ts +53 -19
  420. package/src/tools/read.ts +8 -2
  421. package/src/tools/render-mermaid.ts +1 -1
  422. package/src/tools/renderers.ts +7 -11
  423. package/src/tools/report-tool-issue.ts +3 -2
  424. package/src/tools/resolve.ts +1 -1
  425. package/src/tools/review.ts +1 -1
  426. package/src/tools/search-tool-bm25.ts +1 -1
  427. package/src/tools/search.ts +1 -1
  428. package/src/tools/ssh.ts +5 -4
  429. package/src/tools/todo.ts +2 -2
  430. package/src/tools/tts.ts +204 -93
  431. package/src/tools/write.ts +19 -3
  432. package/src/tts/downloader.ts +64 -0
  433. package/src/tts/index.ts +8 -0
  434. package/src/tts/models.ts +137 -0
  435. package/src/tts/player.ts +137 -0
  436. package/src/tts/runtime.ts +21 -0
  437. package/src/tts/streaming-player.ts +266 -0
  438. package/src/tts/tts-client.ts +647 -0
  439. package/src/tts/tts-protocol.ts +60 -0
  440. package/src/tts/tts-worker.ts +497 -0
  441. package/src/tts/vocalizer.ts +162 -0
  442. package/src/tts/wav.ts +58 -0
  443. package/src/utils/clipboard.ts +35 -18
  444. package/src/utils/image-loading.ts +35 -4
  445. package/src/utils/thinking-display.ts +37 -0
  446. package/src/utils/title-generator.ts +48 -5
  447. package/src/utils/tool-choice.ts +16 -0
  448. package/src/utils/tools-manager.test.ts +25 -0
  449. package/src/utils/tools-manager.ts +19 -1
  450. package/src/web/scrapers/github.ts +96 -0
  451. package/src/web/search/index.ts +14 -1
  452. package/src/web/search/providers/searxng.ts +13 -1
  453. package/dist/types/cli/list-models.d.ts +0 -30
  454. package/dist/types/stt/setup.d.ts +0 -18
  455. package/src/cli/list-models.ts +0 -194
  456. package/src/stt/setup.ts +0 -52
  457. package/src/stt/transcribe.py +0 -70
@@ -1,6 +1,6 @@
1
1
  import type { SnapshotStore } from "@oh-my-pi/hashline";
2
2
  import type { AgentTool } from "@oh-my-pi/pi-agent-core";
3
- import { type Component, Container, type TUI } from "@oh-my-pi/pi-tui";
3
+ import { type Component, Container, type NativeScrollbackLiveRegion, type TUI } from "@oh-my-pi/pi-tui";
4
4
  /**
5
5
  * Transcript-side probe telling a block whether it is still inside the live
6
6
  * (repaintable) region. Implemented by `TranscriptContainer`; injected rather
@@ -33,10 +33,20 @@ export interface ToolExecutionHandle {
33
33
  setArgsComplete(toolCallId?: string): void;
34
34
  setExpanded(expanded: boolean): void;
35
35
  }
36
+ /** Drive pending-tool redraws at 30fps for live tool headers and displaceable
37
+ * poll blocks. The TUI throttles at the same cadence, and static frames diff to
38
+ * a no-op redraw at ~zero cost. */
39
+ export declare const SPINNER_RENDER_INTERVAL_MS: number;
40
+ /** Advance the spinner glyph at its classic ~12.5fps step, decoupled from the
41
+ * render cadence (mirrors `Loader`). */
42
+ export declare const SPINNER_GLYPH_ADVANCE_MS = 80;
43
+ /** Phase-locked spinner glyph index shared by every live tool block so parallel
44
+ * spinners advance in lockstep instead of each tracking its own start time. */
45
+ export declare function sharedSpinnerFrame(frameCount: number, now?: number): number;
36
46
  /**
37
47
  * Component that renders a tool call with its result (updateable)
38
48
  */
39
- export declare class ToolExecutionComponent extends Container {
49
+ export declare class ToolExecutionComponent extends Container implements NativeScrollbackLiveRegion {
40
50
  #private;
41
51
  constructor(toolName: string, args: any, options: ToolExecutionOptions | undefined, tool: AgentTool | undefined, ui: TUI, cwd?: string, _toolCallId?: string);
42
52
  updateArgs(args: any, _toolCallId?: string): void;
@@ -63,6 +73,14 @@ export declare class ToolExecutionComponent extends Container {
63
73
  details?: any;
64
74
  isError?: boolean;
65
75
  }, isPartial?: boolean, _toolCallId?: string): void;
76
+ /**
77
+ * Standalone harnesses may mount a tool component directly under `TUI`
78
+ * instead of inside `TranscriptContainer`. In that shape the component must
79
+ * report its own live-region seam for provisional previews, or the core
80
+ * renderer treats it like shell output and commits tail-window edit/eval/bash
81
+ * previews to immutable native scrollback before the result replaces them.
82
+ */
83
+ getNativeScrollbackLiveRegionStart(): number | undefined;
66
84
  /**
67
85
  * Whether this block has reached a terminal state for transcript freezing.
68
86
  * Reports `false` while it can still visually change so the
@@ -74,20 +92,12 @@ export declare class ToolExecutionComponent extends Container {
74
92
  isTranscriptBlockFinalized(): boolean;
75
93
  /**
76
94
  * Whether this still-live block's settled rows may enter native scrollback
77
- * (see `FinalizableBlock.isTranscriptBlockCommitStable`). Classification is
78
- * per renderer (`ToolRenderer.provisionalPendingPreview`): tail-window
79
- * streaming views (edit's streamed-diff tail, bash/ssh command caps, eval
80
- * cells) are re-anchored top-first by the result render, so promoting
81
- * their visually static head — e.g. an edit preview idling on its last
82
- * frame while the apply + LSP pass runs — would strand a stale copy of
83
- * the call box above the final block the moment the result lands. Every
84
- * other pending preview streams top-anchored append-shaped rows the
85
- * result render preserves (a task call's context/assignment markdown, a
86
- * write's content), so it stays commit-eligible — a call taller than the
87
- * viewport scrolls into native history mid-stream instead of reading as
88
- * cut off until the result. Expanded blocks always stream top-anchored
89
- * (the over-tall write/eval scrollback contract). Displaceable waiting
90
- * polls are removed wholesale by the next poll and must never commit.
95
+ * (see `FinalizableBlock.isTranscriptBlockCommitStable`). Renderers classify
96
+ * pending views by durability instead of by tool name: a provisional view is
97
+ * allowed to be useful on screen, but finalization may replace or re-anchor
98
+ * it wholesale, so committing any of its rows would strand stale preview
99
+ * bytes in immutable scrollback. Non-provisional views stream rows whose
100
+ * committed prefix survives the remaining transitions.
91
101
  */
92
102
  isTranscriptBlockCommitStable(): boolean;
93
103
  /**
@@ -1,4 +1,4 @@
1
- import { type Component, Container, type NativeScrollbackCommittedRows, type NativeScrollbackLiveRegion, type RenderStablePrefix } from "@oh-my-pi/pi-tui";
1
+ import { type Component, Container, type NativeScrollbackCommittedRows, type NativeScrollbackLiveRegion, type RenderStablePrefix, type ViewportTailProvider } from "@oh-my-pi/pi-tui";
2
2
  /**
3
3
  * Transcript container that renders every block's current content each frame
4
4
  * and reports the live-region seam (`NativeScrollbackLiveRegion`) that gates
@@ -22,7 +22,7 @@ import { type Component, Container, type NativeScrollbackCommittedRows, type Nat
22
22
  * through {@link RenderStablePrefix} so the engine can skip marker scanning,
23
23
  * line preparation, and the committed-prefix audit for those rows.
24
24
  */
25
- export declare class TranscriptContainer extends Container implements NativeScrollbackLiveRegion, NativeScrollbackCommittedRows, RenderStablePrefix {
25
+ export declare class TranscriptContainer extends Container implements NativeScrollbackLiveRegion, NativeScrollbackCommittedRows, RenderStablePrefix, ViewportTailProvider {
26
26
  #private;
27
27
  invalidate(): void;
28
28
  clear(): void;
@@ -30,6 +30,7 @@ export declare class TranscriptContainer extends Container implements NativeScro
30
30
  getRenderStablePrefixRows(): number;
31
31
  getNativeScrollbackLiveRegionStart(): number | undefined;
32
32
  getNativeScrollbackCommitSafeEnd(): number | undefined;
33
+ getNativeScrollbackSnapshotSafeEnd(): number | undefined;
33
34
  /**
34
35
  * Whether `component` sits below a still-mutating block — i.e. inside the
35
36
  * live region, where its rows cannot have been committed to native
@@ -52,6 +53,26 @@ export declare class TranscriptContainer extends Container implements NativeScro
52
53
  * become commit-eligible native-scrollback history.
53
54
  */
54
55
  isBlockInLiveRegion(component: Component): boolean;
56
+ /**
57
+ * Render only the bottom `maxRows` rows of the transcript at `width`, walking
58
+ * blocks from the last toward the first and stopping the instant enough rows
59
+ * are collected — blocks above the fold are never rendered. The engine's
60
+ * resize viewport fast path uses this so a drag (a SIGWINCH burst, each event
61
+ * a fresh width that misses every per-width cache) re-lays-out only the
62
+ * handful of visible blocks instead of the whole history every event.
63
+ *
64
+ * State-isolated by contract: touches none of the persistent full-compose
65
+ * fields (#lines, #segments, the per-block diff snapshots, the commit/stable
66
+ * bookkeeping), so the authoritative full render on settle reconciles exactly
67
+ * as if this never ran. Calling each block's render() still warms its own
68
+ * per-width cache, which that settle render then reuses for free.
69
+ *
70
+ * Consecutive visible blocks are joined by exactly one blank separator, the
71
+ * same rule render() applies, so the result equals the bottom of a full
72
+ * render except for an at-most-one-row separator on the topmost included
73
+ * block — a transient discrepancy the settle paint overwrites.
74
+ */
75
+ renderViewportTail(width: number, maxRows: number): readonly string[];
55
76
  render(width: number): readonly string[];
56
77
  }
57
78
  /**
@@ -1,6 +1,6 @@
1
1
  import { type Component, Container } from "@oh-my-pi/pi-tui";
2
2
  import type { TreeFilterMode } from "../../config/settings-schema";
3
- import type { SessionTreeNode } from "../../session/session-manager";
3
+ import type { SessionTreeNode } from "../../session/session-entries";
4
4
  /** Filter mode for tree display */
5
5
  type FilterMode = TreeFilterMode;
6
6
  declare class TreeList implements Component {
@@ -0,0 +1,3 @@
1
+ import type { Usage } from "@oh-my-pi/pi-ai";
2
+ import { Container } from "@oh-my-pi/pi-tui";
3
+ export declare function createUsageRowBlock(usage: Usage): Container;
@@ -29,14 +29,14 @@ export declare class CommandController {
29
29
  handleRenameCommand(title: string): Promise<void>;
30
30
  handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
31
31
  handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
32
- handleCompactCommand(customInstructions?: string): Promise<CompactionOutcome>;
32
+ handleCompactCommand(customInstructions?: string, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void>): Promise<CompactionOutcome>;
33
33
  /**
34
34
  * TUI handler for `/shake`. `elide` drops heavy structural content and
35
35
  * `images` strips image blocks. Rebuilds the chat and reports counts.
36
36
  */
37
37
  handleShakeCommand(mode: ShakeMode): Promise<void>;
38
38
  handleSkillCommand(skillPath: string, args: string): Promise<void>;
39
- executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<CompactionOutcome>;
39
+ executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void>): Promise<CompactionOutcome>;
40
40
  handleHandoffCommand(customInstructions?: string): Promise<void>;
41
41
  }
42
42
  export declare function renderProviderSection(details: ProviderDetails, uiTheme: Pick<typeof theme, "fg">): string;
@@ -1,27 +1,10 @@
1
1
  import type { InteractiveModeContext } from "../../modes/types";
2
2
  import type { AgentSessionEvent } from "../../session/agent-session";
3
- /**
4
- * Loader label shown the instant a user interrupt (Esc) is requested, kept until
5
- * the agent turn fully unwinds. Esc fires the abort synchronously, but the loop
6
- * only stops the spinner at `agent_end`, which it cannot reach until every
7
- * in-flight tool settles its abort in `executeToolCalls` (`Promise.allSettled`).
8
- * Swapping the steady "Working…" for this acknowledges the keypress instead of
9
- * reading as an ignored Esc for the seconds a slow tool takes to tear down.
10
- */
11
- export declare const INTERRUPTING_WORKING_MESSAGE = "Interrupting\u2026";
12
3
  export declare class EventController {
13
4
  #private;
14
5
  private ctx;
15
6
  constructor(ctx: InteractiveModeContext);
16
7
  dispose(): void;
17
- /**
18
- * Acknowledge a user interrupt (Esc) immediately: switch the loader to
19
- * `INTERRUPTING_WORKING_MESSAGE` and freeze intent-driven working-message
20
- * updates for the rest of the turn so a late `tool_execution_start` intent
21
- * cannot repaint a "Working…/<intent>" line over the acknowledgment. Reset at
22
- * the next `agent_start`. No-op outside an active turn or if already set.
23
- */
24
- notifyInterrupting(): void;
25
8
  subscribeToAgent(): void;
26
9
  /**
27
10
  * Clear every transcript-anchored/turn-scoped piece of state. Used by the
@@ -27,6 +27,20 @@ export declare class InputController {
27
27
  handleImagePathPaste(path: string): Promise<void>;
28
28
  handleImagePaste(): Promise<boolean>;
29
29
  handleClipboardTextRawPaste(): Promise<void>;
30
+ /**
31
+ * Editor `onLargePaste` hook: gate a marker-sized paste behind the large-paste menu. Returns
32
+ * `true` to intercept (the editor skips its default `[Paste]` marker) once the paste reaches the
33
+ * configured `paste.largeMenuThreshold` line count; otherwise `false` for default collapse-to-marker
34
+ * behavior. The async menu is fired and forgotten — the editor only needs the synchronous verdict.
35
+ */
36
+ handleLargePaste(text: string, lineCount: number): boolean;
37
+ /**
38
+ * Present the large-paste menu and apply the chosen action: wrap in a code block or in XML tags
39
+ * (both collapse to a `[Paste]` marker that expands on submit), or save the text to a file and
40
+ * reference its path so the agent can `read` it on demand. Cancelling (Esc) falls back to the
41
+ * default inline paste marker, so the pasted content is never lost.
42
+ */
43
+ presentLargePasteMenu(text: string, lineCount: number): Promise<void>;
30
44
  createAutocompleteProvider(commands: SlashCommand[], basePath: string): AutocompleteProvider;
31
45
  /** Copy the current editor line to the system clipboard. */
32
46
  handleCopyCurrentLine(): void;
@@ -43,5 +43,7 @@ export declare class SelectorController {
43
43
  showOAuthSelector(mode: "login" | "logout", providerId?: string): Promise<void>;
44
44
  showResetUsageSelector(): Promise<void>;
45
45
  showDebugSelector(): Promise<void>;
46
- showAgentHub(observers: SessionObserverRegistry): void;
46
+ showAgentHub(observers: SessionObserverRegistry, options?: {
47
+ requireContent?: boolean;
48
+ }): void;
47
49
  }
@@ -1,7 +1,12 @@
1
- /** A gradient keyword highlighter. `resetTo` is the SGR foreground sequence
2
- * re-emitted after each painted keyword so surrounding text keeps its color;
3
- * it defaults to a plain foreground reset (editor / default-colored text). */
4
- export type KeywordHighlighter = (text: string, resetTo?: string) => string;
1
+ /** A gradient keyword highlighter.
2
+ *
3
+ * - `resetTo` is the SGR foreground sequence re-emitted after each painted
4
+ * keyword so surrounding text keeps its color; it defaults to a plain
5
+ * foreground reset (editor / default-colored text).
6
+ * - `phase` ∈ [0, 1) rotates the gradient stops cyclically; pass `Date.now()`-
7
+ * derived values to animate a shimmer. Defaults to `0` (the static
8
+ * sent-bubble palette). */
9
+ export type KeywordHighlighter = (text: string, resetTo?: string, phase?: number) => string;
5
10
  /** Declarative spec for {@link createGradientHighlighter}. */
6
11
  export interface GradientHighlightSpec {
7
12
  /** Cheap, stateless presence probe used to skip the boundary regex on most lines. Must be non-global. */
@@ -4,6 +4,12 @@ import { type BlobPutResult } from "../session/blob-store";
4
4
  * Group 1 is the kind (`Image`/`Paste`), group 2 the 1-based index. The optional metadata
5
5
  * tail (`, …`) is captured loosely (no `]`/newline) so future label tweaks keep matching. */
6
6
  export declare const PLACEHOLDER_REGEX: RegExp;
7
+ /** Renumber every `[Image #N]` marker in `text` by `offset` (added to the
8
+ * existing index), preserving the optional `, WxH` tail. Paste markers are
9
+ * left untouched. Used when restoring queued image-messages back into a draft
10
+ * that already holds pending images so the merged text's positional markers
11
+ * still line up with `pendingImages`. */
12
+ export declare function shiftImageMarkers(text: string, offset: number): string;
7
13
  type ImageBlobWriter = (data: Buffer, options?: {
8
14
  extension?: string;
9
15
  }) => Promise<BlobPutResult>;
@@ -13,7 +13,8 @@ import type { MCPManager } from "../mcp";
13
13
  import { type PlanApprovalDetails } from "../plan-mode/approved-plan";
14
14
  import type { AgentSession } from "../session/agent-session";
15
15
  import { HistoryStorage } from "../session/history-storage";
16
- import type { SessionContext, SessionManager } from "../session/session-manager";
16
+ import type { SessionContext } from "../session/session-context";
17
+ import type { SessionManager } from "../session/session-manager";
17
18
  import type { ShakeMode } from "../session/shake-types";
18
19
  import type { LspStartupServerInfo } from "../tools";
19
20
  import type { EventBus } from "../utils/event-bus";
@@ -33,6 +34,18 @@ import { OAuthManualInputManager } from "./oauth-manual-input";
33
34
  import type { ObservableSession } from "./session-observer-registry";
34
35
  import type { Theme } from "./theme/theme";
35
36
  import type { CompactionQueuedMessage, InteractiveModeContext, InteractiveModeInitOptions, InteractiveSelectorDialogOptions, SubmittedUserInput, TodoItem, TodoPhase } from "./types";
37
+ /**
38
+ * Editor max-height cap for a terminal of `terminalRows` rows.
39
+ *
40
+ * Roomy terminals get the comfortable [6, 18] band. Small terminals shrink the
41
+ * cap so the editor leaves at least EDITOR_MIN_CHROME_ROWS rows for the
42
+ * transcript + status line. The editor is bordered, so it never renders fewer
43
+ * than EDITOR_MIN_RENDERED_ROWS rows; once the terminal is too small for both
44
+ * (terminalRows < EDITOR_MIN_RENDERED_ROWS + EDITOR_MIN_CHROME_ROWS) the cap is
45
+ * pinned to that floor — returning a smaller number would not shrink the editor
46
+ * any further, it would only misreport the rows it actually occupies.
47
+ */
48
+ export declare function computeEditorMaxHeight(terminalRows: number): number;
36
49
  /** Options for creating an InteractiveMode instance (for future API use) */
37
50
  export interface InteractiveModeOptions {
38
51
  /** Providers that were migrated during startup */
@@ -74,6 +87,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
74
87
  btwContainer: Container;
75
88
  omfgContainer: Container;
76
89
  errorBannerContainer: Container;
90
+ modelCycleContainer: Container;
77
91
  editor: CustomEditor;
78
92
  editorContainer: Container;
79
93
  hookWidgetContainerAbove: Container;
@@ -107,8 +121,6 @@ export declare class InteractiveMode implements InteractiveModeContext {
107
121
  loadingAnimation: Loader | undefined;
108
122
  autoCompactionLoader: Loader | undefined;
109
123
  retryLoader: Loader | undefined;
110
- autoCompactionEscapeHandler?: () => void;
111
- retryEscapeHandler?: () => void;
112
124
  unsubscribe?: () => void;
113
125
  onInputCallback?: (input: SubmittedUserInput) => void;
114
126
  optimisticUserMessageSignature: string | undefined;
@@ -177,6 +189,13 @@ export declare class InteractiveMode implements InteractiveModeContext {
177
189
  updateEditorBorderColor(): void;
178
190
  updateEditorTopBorder(): void;
179
191
  rebuildChatFromMessages(): void;
192
+ /**
193
+ * Render the ctrl+p model-role cycle chip track into its own anchored
194
+ * container (just above the editor), mirroring the todo HUD: the container is
195
+ * cleared and rebuilt in place on every cycle, so rapid presses or concurrent
196
+ * chat activity can never stack duplicate tracks into the scrollback.
197
+ */
198
+ showModelCycleTrack(track: string): void;
180
199
  /** Apply any deferred model switch after the current stream ends. */
181
200
  flushPendingModelSwitch(): Promise<void>;
182
201
  showPlanReview(planContent: string, title: string, options: string[], dialogOptions?: {
@@ -191,6 +210,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
191
210
  }): Promise<string | undefined>;
192
211
  handlePlanModeCommand(initialPrompt?: string): Promise<void>;
193
212
  handleGoalModeCommand(rest?: string): Promise<void>;
213
+ handleGuidedGoalCommand(rest?: string): Promise<void>;
194
214
  /** Manually (re-)open the plan-review overlay — bound to `/plan-review`. Lets
195
215
  * the operator pull the review back up after dismissing it, or review a plan
196
216
  * the agent wrote without calling `resolve`. There is no fixed plan filename:
@@ -218,7 +238,6 @@ export declare class InteractiveMode implements InteractiveModeContext {
218
238
  ensureLoadingAnimation(): void;
219
239
  setWorkingMessage(message?: string): void;
220
240
  applyPendingWorkingMessage(): void;
221
- notifyInterrupting(): void;
222
241
  showNewVersionNotification(newVersion: string): void;
223
242
  clearEditor(): void;
224
243
  updatePendingMessagesDisplay(): void;
@@ -264,13 +283,15 @@ export declare class InteractiveMode implements InteractiveModeContext {
264
283
  handleMemoryCommand(text: string): Promise<void>;
265
284
  handleSTTToggle(): Promise<void>;
266
285
  showDebugSelector(): Promise<void>;
267
- showAgentHub(): void;
286
+ showAgentHub(options?: {
287
+ requireContent?: boolean;
288
+ }): void;
268
289
  resetObserverRegistry(): void;
269
290
  handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
270
291
  handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
271
292
  handleMCPCommand(text: string): Promise<void>;
272
293
  handleSSHCommand(text: string): Promise<void>;
273
- handleCompactCommand(customInstructions?: string): Promise<CompactionOutcome>;
294
+ handleCompactCommand(customInstructions?: string, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void>): Promise<CompactionOutcome>;
274
295
  handleHandoffCommand(customInstructions?: string): Promise<void>;
275
296
  handleShakeCommand(mode: ShakeMode): Promise<void>;
276
297
  executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<CompactionOutcome>;
@@ -10,5 +10,17 @@
10
10
  * pass the surrounding text color when decorating already-colored content (e.g.
11
11
  * a themed message bubble) so the gradient does not bleed into the rest of the
12
12
  * line. Defaults to a plain foreground reset for default-colored editor text.
13
+ *
14
+ * `phase` ∈ [0, 1) cyclically rotates each gradient — the editor passes a
15
+ * `Date.now()`-derived value to animate a Claude-Code-style shimmer while a
16
+ * keyword is on screen and the prompt is focused; sent message bubbles omit it
17
+ * to keep the static gradient.
18
+ */
19
+ export declare function highlightMagicKeywords(text: string, resetTo?: string, phase?: number): string;
20
+ /**
21
+ * Cheap test for "does this text contain any magic keyword as standalone prose?".
22
+ * Short-circuits on a substring probe before paying for the markdown-aware
23
+ * prose check, so the common "no keyword in buffer" path is just three
24
+ * `String#indexOf`s. Used by the live editor to gate the shimmer timer.
13
25
  */
14
- export declare function highlightMagicKeywords(text: string, resetTo?: string): string;
26
+ export declare function hasMagicKeyword(text: string): boolean;
@@ -35,7 +35,41 @@ export type RpcSessionChangeResult = {
35
35
  };
36
36
  export type RpcSessionChangeSession = Pick<AgentSession, "newSession" | "switchSession" | "branch">;
37
37
  export type RpcSkillCommandSession = Pick<AgentSession, "promptCustomMessage" | "skills" | "skillsSettings">;
38
- export declare function tryRunRpcSkillCommand(session: RpcSkillCommandSession, text: string): Promise<boolean>;
38
+ export type RpcSkillCommandResult = {
39
+ agentInvoked: true;
40
+ };
41
+ export declare function tryRunRpcSkillCommand(session: RpcSkillCommandSession, text: string): Promise<RpcSkillCommandResult | false>;
42
+ export declare function reportLocalOnlyPromptResult(input: {
43
+ id: string | undefined;
44
+ prompt: Promise<boolean>;
45
+ output: (obj: object) => void;
46
+ onError: (error: Error) => void;
47
+ hasExtensionAgentMessageTask?: () => boolean;
48
+ waitForExtensionAgentMessageTasks?: () => Promise<void>;
49
+ }): void;
50
+ /**
51
+ * Tracks extension-originated messages while an RPC prompt is executing.
52
+ * A slash command can resolve the outer prompt as local-only while also
53
+ * scheduling agent work through pi.sendUserMessage() or pi.sendMessage()
54
+ * with triggerTurn; that prompt must not report agentInvoked:false to the host.
55
+ */
56
+ export declare class RpcExtensionUserMessageTracker {
57
+ #private;
58
+ markAgentMessageTask(): void;
59
+ trackAgentMessageTask(task: Promise<unknown>): void;
60
+ watchPrompt<T>(startPrompt: () => Promise<T>): {
61
+ prompt: Promise<T>;
62
+ hasAgentMessageTask: () => boolean;
63
+ waitForAgentMessageTasks: () => Promise<void>;
64
+ };
65
+ }
66
+ export declare function watchAndReportLocalOnlyPromptResult(input: {
67
+ id: string | undefined;
68
+ startPrompt: () => Promise<boolean>;
69
+ output: (obj: object) => void;
70
+ onError: (error: Error) => void;
71
+ extensionUserMessageTracker: RpcExtensionUserMessageTracker;
72
+ }): void;
39
73
  export type RpcSubagentResetRegistry = Pick<RpcSubagentRegistry, "clear">;
40
74
  export declare function handleRpcSessionChange(session: RpcSessionChangeSession, command: RpcSessionChangeCommand, subagentRegistry?: RpcSubagentResetRegistry): Promise<RpcSessionChangeResult>;
41
75
  export declare function requestRpcEditor(pendingRequests: Map<string, PendingExtensionRequest>, output: RpcOutput, title: string, prefill?: string, dialogOptions?: ExtensionUIDialogOptions, editorOptions?: {
@@ -10,7 +10,7 @@ import type { Effort, ImageContent, Model } from "@oh-my-pi/pi-ai";
10
10
  import type { BashResult } from "../../exec/bash-executor";
11
11
  import type { ContextUsage } from "../../extensibility/extensions/types";
12
12
  import type { AgentSessionEvent, SessionStats } from "../../session/agent-session";
13
- import type { FileEntry } from "../../session/session-manager";
13
+ import type { FileEntry } from "../../session/session-entries";
14
14
  import type { AvailableSlashCommandSource } from "../../slash-commands/available-commands";
15
15
  import type { AgentProgress, SubagentEventPayload, SubagentLifecyclePayload, SubagentProgressPayload } from "../../task";
16
16
  import type { TodoPhase } from "../../tools/todo";
@@ -208,6 +208,11 @@ export interface RpcAvailableCommandsUpdateFrame {
208
208
  type: "available_commands_update";
209
209
  commands: RpcAvailableSlashCommand[];
210
210
  }
211
+ export interface RpcPromptResultFrame {
212
+ type: "prompt_result";
213
+ id?: string;
214
+ agentInvoked: boolean;
215
+ }
211
216
  export interface RpcHandoffResult {
212
217
  savedPath?: string;
213
218
  }
@@ -239,6 +244,9 @@ export type RpcResponse = {
239
244
  type: "response";
240
245
  command: "prompt";
241
246
  success: true;
247
+ data?: {
248
+ agentInvoked: boolean;
249
+ };
242
250
  } | {
243
251
  id?: string;
244
252
  type: "response";
@@ -11,6 +11,10 @@ export interface InitializeExtensionsOptions {
11
11
  onShutdown?: () => void;
12
12
  /** Optional UI context (rpc supplies one; print runs headless). */
13
13
  uiContext?: ExtensionUIContext;
14
+ /** Optional lifecycle hook for extension-originated messages that can start an agent turn. */
15
+ markAgentInvokingMessage?: () => void;
16
+ /** Optional lifecycle hook for extension-originated sends whose success/failure determines turn ownership. */
17
+ trackAgentInvokingMessage?: (task: Promise<unknown>) => void;
14
18
  }
15
19
  /**
16
20
  * Initialize the session's extension runner with the standard action set
@@ -246,6 +246,8 @@ export declare function getThemeByName(name: string): Promise<Theme | undefined>
246
246
  export declare var theme: Theme;
247
247
  /** Get the name of the currently active theme. */
248
248
  export declare function getCurrentThemeName(): string | undefined;
249
+ /** Returns unstyled `text` before `initTheme()` assigns the global theme; use only for early-render paths. */
250
+ export declare function fgOrPlain(color: ThemeColor, text: string, styledText?: string): string;
249
251
  export declare function initTheme(enableWatcher?: boolean, symbolPreset?: SymbolPreset, colorBlindMode?: boolean, darkTheme?: string, lightTheme?: string): Promise<void>;
250
252
  export declare function setTheme(name: string, enableWatcher?: boolean): Promise<{
251
253
  success: boolean;
@@ -289,6 +291,14 @@ export declare function setColorBlindMode(enabled: boolean): Promise<void>;
289
291
  */
290
292
  export declare function getColorBlindMode(): boolean;
291
293
  export declare function onThemeChange(callback: () => void): void;
294
+ /**
295
+ * Monotonic counter bumped on any theme-affecting change that should invalidate
296
+ * cached renders: theme swaps and reloads (including the invalid-theme dark
297
+ * fallback), theme previews, symbol-preset changes, and color-blind-mode
298
+ * changes — everything that routes through {@link notifyThemeChange}. Consumers
299
+ * key cached renders on it so the next render re-shapes their output.
300
+ */
301
+ export declare function getThemeEpoch(): number;
292
302
  /**
293
303
  * Get available symbol presets.
294
304
  */
@@ -304,8 +314,9 @@ export declare function stopThemeWatcher(): void;
304
314
  */
305
315
  export declare function getResolvedThemeColors(themeName?: string): Promise<Record<string, string>>;
306
316
  /**
307
- * Check if a theme is a "light" theme by analyzing its background color luminance.
308
- * Loads theme JSON synchronously (built-in or custom file) and resolves userMessageBg.
317
+ * Check if a theme is a "light" theme by analyzing its status-line background
318
+ * luminance. Loads theme JSON synchronously (built-in or custom file on disk)
319
+ * for callers in synchronous flows (settings migration, setup wizard).
309
320
  */
310
321
  export declare function isLightTheme(themeName?: string): boolean;
311
322
  /**
@@ -12,7 +12,8 @@ import type { MCPManager } from "../mcp";
12
12
  import type { PlanApprovalDetails } from "../plan-mode/approved-plan";
13
13
  import type { AgentSession } from "../session/agent-session";
14
14
  import type { HistoryStorage } from "../session/history-storage";
15
- import type { SessionContext, SessionManager } from "../session/session-manager";
15
+ import type { SessionContext } from "../session/session-context";
16
+ import type { SessionManager } from "../session/session-manager";
16
17
  import type { ShakeMode } from "../session/shake-types";
17
18
  import type { LspStartupServerInfo } from "../tools";
18
19
  import type { EventBus } from "../utils/event-bus";
@@ -74,6 +75,7 @@ export interface InteractiveModeContext {
74
75
  btwContainer: Container;
75
76
  omfgContainer: Container;
76
77
  errorBannerContainer: Container;
78
+ modelCycleContainer: Container;
77
79
  editor: CustomEditor;
78
80
  editorContainer: Container;
79
81
  hookWidgetContainerAbove: Container;
@@ -130,8 +132,6 @@ export interface InteractiveModeContext {
130
132
  loadingAnimation: Loader | undefined;
131
133
  autoCompactionLoader: Loader | undefined;
132
134
  retryLoader: Loader | undefined;
133
- autoCompactionEscapeHandler?: () => void;
134
- retryEscapeHandler?: () => void;
135
135
  unsubscribe?: () => void;
136
136
  onInputCallback?: (input: SubmittedUserInput) => void;
137
137
  optimisticUserMessageSignature: string | undefined;
@@ -173,6 +173,7 @@ export interface InteractiveModeContext {
173
173
  showStatus(message: string, options?: {
174
174
  dim?: boolean;
175
175
  }): void;
176
+ showModelCycleTrack(track: string): void;
176
177
  showError(message: string): void;
177
178
  showPinnedError(message: string): void;
178
179
  clearPinnedError(): void;
@@ -188,9 +189,6 @@ export interface InteractiveModeContext {
188
189
  flushPendingModelSwitch(): Promise<void>;
189
190
  setWorkingMessage(message?: string): void;
190
191
  applyPendingWorkingMessage(): void;
191
- /** Acknowledge a user interrupt (Esc) by switching the loader to an
192
- * "Interrupting…" label until the agent turn unwinds. */
193
- notifyInterrupting(): void;
194
192
  ensureLoadingAnimation(): void;
195
193
  startPendingSubmission(input: {
196
194
  text: string;
@@ -289,7 +287,9 @@ export interface InteractiveModeContext {
289
287
  showProviderSetup(): Promise<void>;
290
288
  showHookConfirm(title: string, message: string): Promise<boolean>;
291
289
  showDebugSelector(): Promise<void>;
292
- showAgentHub(): void;
290
+ showAgentHub(options?: {
291
+ requireContent?: boolean;
292
+ }): void;
293
293
  resetObserverRegistry(): void;
294
294
  handleCtrlC(): void;
295
295
  handleCtrlD(): void;
@@ -312,6 +312,7 @@ export interface InteractiveModeContext {
312
312
  registerExtensionShortcuts(): void;
313
313
  handlePlanModeCommand(initialPrompt?: string): Promise<void>;
314
314
  handleGoalModeCommand(rest?: string): Promise<void>;
315
+ handleGuidedGoalCommand(rest?: string): Promise<void>;
315
316
  handleLoopCommand(args?: string): Promise<void>;
316
317
  disableLoopMode(): void;
317
318
  pauseLoop(): void;
@@ -2,7 +2,7 @@ import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
2
2
  import type { AssistantMessage, ImageContent, Message } from "@oh-my-pi/pi-ai";
3
3
  import { type Component } from "@oh-my-pi/pi-tui";
4
4
  import type { InteractiveModeContext } from "../../modes/types";
5
- import type { SessionContext } from "../../session/session-manager";
5
+ import type { SessionContext } from "../../session/session-context";
6
6
  interface RenderInitialMessagesOptions {
7
7
  preserveExistingChat?: boolean;
8
8
  clearTerminalHistory?: boolean;
@@ -30,6 +30,8 @@ export interface AgentRef {
30
30
  sessionFile: string | null;
31
31
  createdAt: number;
32
32
  lastActivity: number;
33
+ /** Short gist of what the agent is currently doing (latest intent or tool), for the work-aware roster. Display-only. */
34
+ activity?: string;
33
35
  }
34
36
  export type RegistryEvent = {
35
37
  type: "registered";
@@ -58,6 +60,21 @@ export declare class AgentRegistry {
58
60
  static resetGlobalForTests(): void;
59
61
  register(input: RegisterInput): AgentRef;
60
62
  setStatus(id: string, status: AgentStatus): void;
63
+ /**
64
+ * Record a short activity gist for the work-aware roster. Display-only and
65
+ * read on demand (`irc list`, peer roster), so it emits no event — keeping
66
+ * the per-tool-call update rate off the registry listener path (same as
67
+ * `attachSession`, which also bumps `lastActivity` without emitting). Only a
68
+ * `running` agent has current work: a heartbeat for any other status is
69
+ * dropped, so a late progress flush can't resurrect activity on a ref that
70
+ * `setStatus` just cleared. Every running heartbeat refreshes `lastActivity`
71
+ * — even when the gist text is unchanged — so the roster's "active … ago" and
72
+ * recency sort track real work, not just the last status change.
73
+ * The gist is normalized to one bounded line (`oneLineLabel`) so model-derived
74
+ * intent text can neither break the roster nor smuggle terminal escapes —
75
+ * every caller is safe without sanitizing at its own call site.
76
+ */
77
+ setActivity(id: string, activity: string): void;
61
78
  attachSession(id: string, session: AgentSession, sessionFile?: string | null): void;
62
79
  detachSession(id: string): void;
63
80
  unregister(id: string): void;
@@ -1,5 +1,5 @@
1
1
  import type { Context, Message, Tool } from "@oh-my-pi/pi-ai";
2
- import type { SessionContext } from "../session/session-manager";
2
+ import type { SessionContext } from "../session/session-context";
3
3
  export interface SecretEntry {
4
4
  type: "plain" | "regex";
5
5
  content: string;