@oh-my-pi/pi-coding-agent 15.10.9 → 15.10.11

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 (352) hide show
  1. package/CHANGELOG.md +117 -0
  2. package/dist/cli.js +23087 -0
  3. package/dist/tokenizers.linux-x64-gnu-xcjh3jwk.node +0 -0
  4. package/dist/types/async/job-manager.d.ts +18 -0
  5. package/dist/types/cli/args.d.ts +1 -1
  6. package/dist/types/cli/dry-balance-cli.d.ts +1 -1
  7. package/dist/types/cli/gallery-cli.d.ts +1 -1
  8. package/dist/types/cli/gallery-fixtures/types.d.ts +1 -1
  9. package/dist/types/cli/usage-cli.d.ts +72 -0
  10. package/dist/types/commands/launch.d.ts +1 -1
  11. package/dist/types/commands/read.d.ts +1 -1
  12. package/dist/types/commands/usage.d.ts +25 -0
  13. package/dist/types/config/append-only-context-mode.d.ts +2 -1
  14. package/dist/types/config/model-discovery.d.ts +55 -0
  15. package/dist/types/config/model-registry.d.ts +20 -219
  16. package/dist/types/config/model-resolver.d.ts +16 -10
  17. package/dist/types/config/model-roles.d.ts +28 -0
  18. package/dist/types/config/models-config-schema.d.ts +523 -42
  19. package/dist/types/config/models-config.d.ts +385 -0
  20. package/dist/types/config/settings-schema.d.ts +12 -16
  21. package/dist/types/config/settings.d.ts +1 -1
  22. package/dist/types/debug/log-viewer.d.ts +1 -1
  23. package/dist/types/debug/raw-sse.d.ts +1 -1
  24. package/dist/types/debug/terminal-info.d.ts +0 -1
  25. package/dist/types/eval/backend.d.ts +0 -2
  26. package/dist/types/eval/idle-timeout.d.ts +0 -4
  27. package/dist/types/eval/js/shared/rewrite-imports.d.ts +6 -6
  28. package/dist/types/export/html/template.generated.d.ts +1 -1
  29. package/dist/types/extensibility/extensions/types.d.ts +3 -3
  30. package/dist/types/hindsight/mental-models.d.ts +17 -8
  31. package/dist/types/internal-urls/artifact-protocol.d.ts +2 -2
  32. package/dist/types/internal-urls/types.d.ts +1 -1
  33. package/dist/types/lsp/edits.d.ts +9 -0
  34. package/dist/types/lsp/index.d.ts +2 -2
  35. package/dist/types/lsp/types.d.ts +2 -0
  36. package/dist/types/lsp/utils.d.ts +3 -0
  37. package/dist/types/mcp/json-rpc.d.ts +5 -0
  38. package/dist/types/mnemopi/state.d.ts +11 -1
  39. package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
  40. package/dist/types/modes/components/assistant-message.d.ts +3 -1
  41. package/dist/types/modes/components/bash-execution.d.ts +1 -1
  42. package/dist/types/modes/components/copy-selector.d.ts +1 -1
  43. package/dist/types/modes/components/dynamic-border.d.ts +1 -1
  44. package/dist/types/modes/components/extensions/extension-dashboard.d.ts +1 -1
  45. package/dist/types/modes/components/extensions/extension-list.d.ts +1 -1
  46. package/dist/types/modes/components/extensions/inspector-panel.d.ts +1 -1
  47. package/dist/types/modes/components/footer.d.ts +1 -1
  48. package/dist/types/modes/components/hook-editor.d.ts +5 -0
  49. package/dist/types/modes/components/hook-input.d.ts +4 -0
  50. package/dist/types/modes/components/hook-selector.d.ts +1 -1
  51. package/dist/types/modes/components/model-selector.d.ts +1 -1
  52. package/dist/types/modes/components/plan-review-overlay.d.ts +1 -1
  53. package/dist/types/modes/components/session-observer-overlay.d.ts +1 -1
  54. package/dist/types/modes/components/session-selector.d.ts +1 -1
  55. package/dist/types/modes/components/status-line/component.d.ts +1 -1
  56. package/dist/types/modes/components/tiny-title-download-progress.d.ts +1 -1
  57. package/dist/types/modes/components/transcript-container.d.ts +31 -26
  58. package/dist/types/modes/components/tree-selector.d.ts +1 -1
  59. package/dist/types/modes/components/user-message-selector.d.ts +1 -1
  60. package/dist/types/modes/components/user-message.d.ts +2 -1
  61. package/dist/types/modes/components/visual-truncate.d.ts +1 -1
  62. package/dist/types/modes/components/welcome.d.ts +19 -3
  63. package/dist/types/modes/controllers/mcp-command-controller.d.ts +1 -1
  64. package/dist/types/modes/controllers/streaming-reveal.d.ts +1 -1
  65. package/dist/types/modes/interactive-mode.d.ts +1 -1
  66. package/dist/types/modes/setup-wizard/scenes/sign-in.d.ts +1 -1
  67. package/dist/types/modes/setup-wizard/scenes/types.d.ts +1 -1
  68. package/dist/types/modes/setup-wizard/scenes/web-search.d.ts +1 -1
  69. package/dist/types/modes/setup-wizard/wizard-overlay.d.ts +1 -1
  70. package/dist/types/modes/types.d.ts +2 -1
  71. package/dist/types/session/agent-session.d.ts +1 -1
  72. package/dist/types/session/auth-broker-config.d.ts +4 -0
  73. package/dist/types/session/session-manager.d.ts +1 -1
  74. package/dist/types/slash-commands/helpers/stats-dashboard.d.ts +13 -0
  75. package/dist/types/ssh/connection-manager.d.ts +8 -0
  76. package/dist/types/task/discovery.d.ts +1 -2
  77. package/dist/types/task/parallel.d.ts +2 -2
  78. package/dist/types/task/worktree.d.ts +2 -0
  79. package/dist/types/tiny/title-client.d.ts +1 -1
  80. package/dist/types/tools/ask.d.ts +4 -0
  81. package/dist/types/tools/conflict-detect.d.ts +16 -0
  82. package/dist/types/tools/github-cache.d.ts +7 -0
  83. package/dist/types/tools/sqlite-reader.d.ts +3 -0
  84. package/dist/types/tools/todo.d.ts +2 -0
  85. package/dist/types/tui/output-block.d.ts +3 -3
  86. package/dist/types/utils/changelog.d.ts +8 -0
  87. package/dist/types/web/scrapers/readthedocs.d.ts +3 -0
  88. package/dist/types/web/scrapers/types.d.ts +12 -0
  89. package/dist/types/web/search/providers/codex.d.ts +1 -1
  90. package/dist/types/web/search/providers/gemini.d.ts +1 -1
  91. package/examples/extensions/tools.ts +5 -4
  92. package/package.json +14 -11
  93. package/scripts/build-binary.ts +18 -23
  94. package/scripts/bundle-dist.ts +81 -0
  95. package/scripts/{dev-launch → omp} +1 -1
  96. package/scripts/{dev-launch-preload.ts → omp.ts} +1 -1
  97. package/src/async/job-manager.ts +57 -3
  98. package/src/autoresearch/dashboard.ts +1 -1
  99. package/src/autoresearch/prompt-setup.md +6 -6
  100. package/src/autoresearch/prompt.md +6 -6
  101. package/src/capability/fs.ts +10 -0
  102. package/src/cli/args.ts +1 -1
  103. package/src/cli/auth-gateway-cli.ts +1 -3
  104. package/src/cli/dry-balance-cli.ts +1 -1
  105. package/src/cli/gallery-cli.ts +1 -1
  106. package/src/cli/gallery-fixtures/fs.ts +1 -1
  107. package/src/cli/gallery-fixtures/types.ts +5 -1
  108. package/src/cli/list-models.ts +7 -12
  109. package/src/cli/usage-cli.ts +603 -0
  110. package/src/cli-commands.ts +1 -0
  111. package/src/cli.ts +69 -5
  112. package/src/commands/complete.ts +1 -1
  113. package/src/commands/launch.ts +1 -1
  114. package/src/commands/read.ts +6 -3
  115. package/src/commands/usage.ts +35 -0
  116. package/src/commit/agentic/agent.ts +1 -1
  117. package/src/commit/model-selection.ts +1 -1
  118. package/src/config/append-only-context-mode.ts +6 -12
  119. package/src/config/model-discovery.ts +554 -0
  120. package/src/config/model-registry.ts +308 -1025
  121. package/src/config/model-resolver.ts +113 -156
  122. package/src/config/model-roles.ts +74 -0
  123. package/src/config/models-config-schema.ts +57 -8
  124. package/src/config/models-config.ts +129 -0
  125. package/src/config/settings-schema.ts +18 -14
  126. package/src/config/settings.ts +37 -1
  127. package/src/dap/client.ts +124 -37
  128. package/src/dap/session.ts +259 -158
  129. package/src/debug/log-viewer.ts +1 -1
  130. package/src/debug/raw-sse.ts +1 -1
  131. package/src/debug/terminal-info.ts +0 -3
  132. package/src/edit/diff.ts +95 -18
  133. package/src/edit/hashline/block-resolver.ts +20 -1
  134. package/src/edit/hashline/diff.ts +36 -1
  135. package/src/edit/hashline/execute.ts +8 -2
  136. package/src/edit/index.ts +16 -1
  137. package/src/edit/modes/patch.ts +52 -0
  138. package/src/edit/modes/replace.ts +56 -22
  139. package/src/edit/notebook.ts +22 -2
  140. package/src/edit/renderer.ts +36 -10
  141. package/src/eval/__tests__/completion-bridge.test.ts +1 -1
  142. package/src/eval/backend.ts +0 -2
  143. package/src/eval/completion-bridge.ts +2 -1
  144. package/src/eval/idle-timeout.ts +2 -9
  145. package/src/eval/js/context-manager.ts +6 -8
  146. package/src/eval/js/executor.ts +6 -2
  147. package/src/eval/js/index.ts +0 -2
  148. package/src/eval/js/shared/helpers.ts +5 -6
  149. package/src/eval/js/shared/local-module-loader.ts +1 -1
  150. package/src/eval/js/shared/prelude.txt +62 -1
  151. package/src/eval/js/shared/rewrite-imports.ts +49 -23
  152. package/src/eval/js/shared/runtime.ts +1 -1
  153. package/src/eval/py/index.ts +0 -2
  154. package/src/eval/py/kernel.ts +19 -0
  155. package/src/eval/py/runner.py +107 -3
  156. package/src/exec/bash-executor.ts +3 -1
  157. package/src/export/html/template.generated.ts +1 -1
  158. package/src/export/html/template.js +3 -1
  159. package/src/extensibility/extensions/types.ts +3 -2
  160. package/src/extensibility/plugins/legacy-pi-compat.ts +20 -3
  161. package/src/hindsight/mental-models.ts +59 -12
  162. package/src/hindsight/state.ts +6 -1
  163. package/src/internal-urls/artifact-protocol.ts +11 -2
  164. package/src/internal-urls/docs-index.generated.ts +10 -10
  165. package/src/internal-urls/issue-pr-protocol.ts +12 -5
  166. package/src/internal-urls/router.ts +1 -1
  167. package/src/internal-urls/types.ts +1 -1
  168. package/src/lib/xai-http.ts +1 -1
  169. package/src/lsp/client.ts +118 -38
  170. package/src/lsp/clients/biome-client.ts +101 -39
  171. package/src/lsp/edits.ts +143 -95
  172. package/src/lsp/index.ts +31 -22
  173. package/src/lsp/render.ts +1 -1
  174. package/src/lsp/types.ts +2 -0
  175. package/src/lsp/utils.ts +28 -10
  176. package/src/main.ts +165 -17
  177. package/src/mcp/json-rpc.ts +35 -5
  178. package/src/mcp/transports/stdio.ts +7 -1
  179. package/src/memories/index.ts +2 -1
  180. package/src/mnemopi/backend.ts +25 -3
  181. package/src/mnemopi/state.ts +38 -2
  182. package/src/modes/components/agent-dashboard.ts +10 -7
  183. package/src/modes/components/assistant-message.ts +19 -13
  184. package/src/modes/components/bash-execution.ts +1 -1
  185. package/src/modes/components/copy-selector.ts +1 -1
  186. package/src/modes/components/diff.ts +13 -2
  187. package/src/modes/components/dynamic-border.ts +12 -3
  188. package/src/modes/components/extensions/extension-dashboard.ts +8 -5
  189. package/src/modes/components/extensions/extension-list.ts +1 -1
  190. package/src/modes/components/extensions/inspector-panel.ts +1 -1
  191. package/src/modes/components/footer.ts +1 -1
  192. package/src/modes/components/history-search.ts +1 -1
  193. package/src/modes/components/hook-editor.ts +8 -0
  194. package/src/modes/components/hook-input.ts +8 -0
  195. package/src/modes/components/hook-selector.ts +2 -2
  196. package/src/modes/components/model-selector.ts +66 -54
  197. package/src/modes/components/plan-review-overlay.ts +1 -1
  198. package/src/modes/components/session-observer-overlay.ts +2 -2
  199. package/src/modes/components/session-selector.ts +1 -1
  200. package/src/modes/components/settings-selector.ts +5 -1
  201. package/src/modes/components/status-line/component.ts +1 -1
  202. package/src/modes/components/tiny-title-download-progress.ts +1 -1
  203. package/src/modes/components/transcript-container.ts +373 -141
  204. package/src/modes/components/tree-selector.ts +3 -3
  205. package/src/modes/components/user-message-selector.ts +1 -1
  206. package/src/modes/components/user-message.ts +17 -5
  207. package/src/modes/components/visual-truncate.ts +1 -1
  208. package/src/modes/components/welcome.ts +108 -26
  209. package/src/modes/controllers/command-controller.ts +10 -3
  210. package/src/modes/controllers/event-controller.ts +73 -49
  211. package/src/modes/controllers/input-controller.ts +5 -5
  212. package/src/modes/controllers/mcp-command-controller.ts +1 -1
  213. package/src/modes/controllers/selector-controller.ts +1 -5
  214. package/src/modes/controllers/streaming-reveal.ts +85 -18
  215. package/src/modes/interactive-mode.ts +5 -19
  216. package/src/modes/setup-wizard/scenes/glyph.ts +1 -1
  217. package/src/modes/setup-wizard/scenes/providers.ts +1 -1
  218. package/src/modes/setup-wizard/scenes/sign-in.ts +1 -1
  219. package/src/modes/setup-wizard/scenes/theme.ts +1 -1
  220. package/src/modes/setup-wizard/scenes/types.ts +1 -1
  221. package/src/modes/setup-wizard/scenes/web-search.ts +1 -1
  222. package/src/modes/setup-wizard/wizard-overlay.ts +1 -1
  223. package/src/modes/types.ts +2 -1
  224. package/src/prompts/agents/explore.md +2 -2
  225. package/src/prompts/agents/librarian.md +1 -2
  226. package/src/prompts/agents/oracle.md +1 -1
  227. package/src/prompts/agents/plan.md +5 -5
  228. package/src/prompts/agents/task.md +5 -5
  229. package/src/prompts/ci-green-request.md +5 -7
  230. package/src/prompts/goals/goal-budget-limit.md +2 -2
  231. package/src/prompts/goals/goal-continuation.md +4 -4
  232. package/src/prompts/goals/goal-mode-active.md +1 -1
  233. package/src/prompts/memories/read-path.md +1 -1
  234. package/src/prompts/memories/stage_one_system.md +2 -2
  235. package/src/prompts/review-custom-request.md +1 -1
  236. package/src/prompts/system/agent-creation-architect.md +2 -2
  237. package/src/prompts/system/auto-continue.md +1 -1
  238. package/src/prompts/system/background-tan-dispatch.md +1 -1
  239. package/src/prompts/system/btw-user.md +2 -2
  240. package/src/prompts/system/commit-message-system.md +13 -1
  241. package/src/prompts/system/custom-system-prompt.md +1 -1
  242. package/src/prompts/system/eager-todo.md +2 -2
  243. package/src/prompts/system/irc-incoming.md +1 -1
  244. package/src/prompts/system/manual-continue.md +1 -1
  245. package/src/prompts/system/omfg-user.md +3 -4
  246. package/src/prompts/system/orchestrate-notice.md +9 -9
  247. package/src/prompts/system/plan-mode-active.md +4 -4
  248. package/src/prompts/system/plan-mode-subagent.md +4 -5
  249. package/src/prompts/system/plan-mode-tool-decision-reminder.md +1 -1
  250. package/src/prompts/system/project-prompt.md +2 -2
  251. package/src/prompts/system/subagent-system-prompt.md +4 -4
  252. package/src/prompts/system/system-prompt.md +15 -26
  253. package/src/prompts/system/title-system.md +2 -2
  254. package/src/prompts/system/ttsr-tool-reminder.md +1 -1
  255. package/src/prompts/system/workflow-notice.md +1 -1
  256. package/src/prompts/tools/ast-edit.md +1 -1
  257. package/src/prompts/tools/ast-grep.md +2 -2
  258. package/src/prompts/tools/bash.md +8 -10
  259. package/src/prompts/tools/browser.md +7 -7
  260. package/src/prompts/tools/debug.md +1 -1
  261. package/src/prompts/tools/eval.md +3 -3
  262. package/src/prompts/tools/find.md +0 -1
  263. package/src/prompts/tools/github.md +8 -7
  264. package/src/prompts/tools/goal.md +1 -1
  265. package/src/prompts/tools/image-gen.md +1 -1
  266. package/src/prompts/tools/inspect-image-system.md +1 -1
  267. package/src/prompts/tools/irc.md +15 -15
  268. package/src/prompts/tools/lsp.md +2 -2
  269. package/src/prompts/tools/patch.md +2 -2
  270. package/src/prompts/tools/read.md +3 -4
  271. package/src/prompts/tools/recall.md +1 -1
  272. package/src/prompts/tools/reflect.md +1 -1
  273. package/src/prompts/tools/render-mermaid.md +2 -2
  274. package/src/prompts/tools/replace.md +4 -10
  275. package/src/prompts/tools/rewind.md +2 -2
  276. package/src/prompts/tools/search-tool-bm25.md +1 -9
  277. package/src/prompts/tools/search.md +0 -1
  278. package/src/prompts/tools/ssh.md +0 -4
  279. package/src/prompts/tools/task.md +2 -3
  280. package/src/prompts/tools/todo.md +6 -2
  281. package/src/sdk.ts +23 -10
  282. package/src/session/agent-session.ts +44 -10
  283. package/src/session/auth-broker-config.ts +30 -1
  284. package/src/session/session-manager.ts +2 -2
  285. package/src/session/streaming-output.ts +23 -2
  286. package/src/slash-commands/builtin-registry.ts +20 -0
  287. package/src/slash-commands/helpers/stats-dashboard.ts +85 -0
  288. package/src/ssh/connection-manager.ts +27 -0
  289. package/src/task/commands.ts +2 -1
  290. package/src/task/discovery.ts +17 -24
  291. package/src/task/executor.ts +61 -53
  292. package/src/task/index.ts +137 -60
  293. package/src/task/parallel.ts +3 -3
  294. package/src/task/render.ts +2 -2
  295. package/src/task/worktree.ts +64 -56
  296. package/src/thinking.ts +2 -1
  297. package/src/tiny/title-client.ts +32 -14
  298. package/src/tools/archive-reader.ts +30 -2
  299. package/src/tools/ask.ts +104 -21
  300. package/src/tools/ast-edit.ts +25 -5
  301. package/src/tools/auto-generated-guard.ts +20 -3
  302. package/src/tools/bash-interactive.ts +27 -7
  303. package/src/tools/bash.ts +54 -13
  304. package/src/tools/browser/launch.ts +11 -2
  305. package/src/tools/browser/readable.ts +19 -2
  306. package/src/tools/browser/registry.ts +4 -1
  307. package/src/tools/browser/render.ts +2 -2
  308. package/src/tools/browser/tab-supervisor.ts +55 -16
  309. package/src/tools/conflict-detect.ts +50 -4
  310. package/src/tools/debug.ts +1 -1
  311. package/src/tools/eval-render.ts +5 -5
  312. package/src/tools/eval.ts +0 -2
  313. package/src/tools/fetch.ts +33 -10
  314. package/src/tools/gh-cache-invalidation.ts +63 -8
  315. package/src/tools/gh-renderer.ts +1 -1
  316. package/src/tools/gh.ts +172 -29
  317. package/src/tools/github-cache.ts +70 -6
  318. package/src/tools/image-gen.ts +3 -9
  319. package/src/tools/irc.ts +5 -1
  320. package/src/tools/job.ts +1 -1
  321. package/src/tools/read.ts +202 -61
  322. package/src/tools/render-utils.ts +3 -3
  323. package/src/tools/resolve.ts +1 -1
  324. package/src/tools/search.ts +92 -29
  325. package/src/tools/sqlite-reader.ts +17 -5
  326. package/src/tools/ssh.ts +8 -8
  327. package/src/tools/todo.ts +51 -12
  328. package/src/tools/write.ts +118 -18
  329. package/src/tui/output-block.ts +4 -4
  330. package/src/utils/changelog.ts +27 -1
  331. package/src/utils/file-mentions.ts +2 -1
  332. package/src/web/scrapers/arxiv.ts +1 -1
  333. package/src/web/scrapers/go-pkg.ts +1 -1
  334. package/src/web/scrapers/iacr.ts +1 -1
  335. package/src/web/scrapers/readthedocs.ts +1 -1
  336. package/src/web/scrapers/twitter.ts +2 -1
  337. package/src/web/scrapers/types.ts +87 -8
  338. package/src/web/scrapers/wikipedia.ts +1 -1
  339. package/src/web/scrapers/youtube.ts +6 -1
  340. package/src/web/search/index.ts +1 -1
  341. package/src/web/search/providers/anthropic.ts +8 -2
  342. package/src/web/search/providers/codex.ts +2 -1
  343. package/src/web/search/providers/gemini.ts +2 -3
  344. package/src/web/search/render.ts +8 -6
  345. package/dist/types/config/model-equivalence.d.ts +0 -24
  346. package/dist/types/config/model-id-affixes.d.ts +0 -12
  347. package/dist/types/config/model-provider-priority.d.ts +0 -1
  348. package/dist/types/exec/idle-timeout-watchdog.d.ts +0 -18
  349. package/src/config/model-equivalence.ts +0 -875
  350. package/src/config/model-id-affixes.ts +0 -81
  351. package/src/config/model-provider-priority.ts +0 -56
  352. package/src/exec/idle-timeout-watchdog.ts +0 -126
@@ -23,6 +23,45 @@ function countGraphemes(text: string): number {
23
23
  return count;
24
24
  }
25
25
 
26
+ /** Count graphemes of `text` from code-unit offset `start`, also reporting the
27
+ * start offset of the final grapheme (where an append could extend a cluster). */
28
+ function countGraphemesFrom(text: string, start: number): { count: number; tailStart: number } {
29
+ let count = 0;
30
+ let tailStart = start;
31
+ for (const seg of getSegmenter().segment(start === 0 ? text : text.slice(start))) {
32
+ count += 1;
33
+ tailStart = start + seg.index;
34
+ }
35
+ return { count, tailStart };
36
+ }
37
+
38
+ /** Memoizes per-block grapheme counts across reveal ticks. Streaming blocks only
39
+ * grow by appending, and an append can only alter the final grapheme cluster of
40
+ * the previous text, so only the suffix from that cluster needs re-segmenting. */
41
+ class BlockUnitCounter {
42
+ #entries = new Map<number, { text: string; count: number; tailStart: number }>();
43
+
44
+ count(index: number, text: string): number {
45
+ const entry = this.#entries.get(index);
46
+ if (entry !== undefined) {
47
+ if (entry.text === text) return entry.count;
48
+ if (entry.count > 0 && text.length > entry.text.length && text.startsWith(entry.text)) {
49
+ const tail = countGraphemesFrom(text, entry.tailStart);
50
+ const next = { text, count: entry.count - 1 + tail.count, tailStart: tail.tailStart };
51
+ this.#entries.set(index, next);
52
+ return next.count;
53
+ }
54
+ }
55
+ const full = countGraphemesFrom(text, 0);
56
+ this.#entries.set(index, { text, count: full.count, tailStart: full.tailStart });
57
+ return full.count;
58
+ }
59
+
60
+ reset(): void {
61
+ this.#entries.clear();
62
+ }
63
+ }
64
+
26
65
  function sliceGraphemes(text: string, units: number): string {
27
66
  if (units <= 0 || text.length === 0) return "";
28
67
  let count = 0;
@@ -51,9 +90,9 @@ export function visibleUnits(message: AssistantMessage, hideThinking: boolean):
51
90
  function revealTextBlock(
52
91
  block: Extract<AssistantContentBlock, { type: "text" }>,
53
92
  remaining: number,
93
+ units: number,
54
94
  ): AssistantContentBlock {
55
95
  if (remaining <= 0) return block.text.length === 0 ? block : { ...block, text: "" };
56
- const units = countGraphemes(block.text);
57
96
  if (remaining >= units) return block;
58
97
  return { ...block, text: sliceGraphemes(block.text, remaining) };
59
98
  }
@@ -61,9 +100,9 @@ function revealTextBlock(
61
100
  function revealThinkingBlock(
62
101
  block: Extract<AssistantContentBlock, { type: "thinking" }>,
63
102
  remaining: number,
103
+ units: number,
64
104
  ): AssistantContentBlock {
65
105
  if (remaining <= 0) return block.thinking.length === 0 ? block : { ...block, thinking: "" };
66
- const units = countGraphemes(block.thinking);
67
106
  if (remaining >= units) return block;
68
107
  return { ...block, thinking: sliceGraphemes(block.thinking, remaining) };
69
108
  }
@@ -72,16 +111,20 @@ export function buildDisplayMessage(
72
111
  target: AssistantMessage,
73
112
  revealed: number,
74
113
  hideThinking: boolean,
114
+ countOf: (index: number, text: string) => number = (_index, text) => countGraphemes(text),
75
115
  ): AssistantMessage {
76
116
  let remaining = Math.max(0, Math.floor(revealed));
77
117
  const content: AssistantContentBlock[] = [];
78
- for (const block of target.content) {
118
+ for (let i = 0; i < target.content.length; i++) {
119
+ const block = target.content[i]!;
79
120
  if (block.type === "text") {
80
- content.push(revealTextBlock(block, remaining));
81
- remaining = Math.max(0, remaining - countGraphemes(block.text));
121
+ const units = countOf(i, block.text);
122
+ content.push(revealTextBlock(block, remaining, units));
123
+ remaining = Math.max(0, remaining - units);
82
124
  } else if (block.type === "thinking" && !hideThinking) {
83
- content.push(revealThinkingBlock(block, remaining));
84
- remaining = Math.max(0, remaining - countGraphemes(block.thinking));
125
+ const units = countOf(i, block.thinking);
126
+ content.push(revealThinkingBlock(block, remaining, units));
127
+ remaining = Math.max(0, remaining - units);
85
128
  } else {
86
129
  content.push(block);
87
130
  }
@@ -103,6 +146,8 @@ export class StreamingRevealController {
103
146
  #revealed = 0;
104
147
  #hideThinkingBlock = false;
105
148
  #smoothStreaming = true;
149
+ readonly #unitCounter = new BlockUnitCounter();
150
+ readonly #countOf = (index: number, text: string): number => this.#unitCounter.count(index, text);
106
151
 
107
152
  constructor(options: StreamingRevealControllerOptions) {
108
153
  this.#getSmoothStreaming = options.getSmoothStreaming;
@@ -121,15 +166,15 @@ export class StreamingRevealController {
121
166
  component.updateContent(message);
122
167
  return;
123
168
  }
124
- const total = visibleUnits(message, this.#hideThinkingBlock);
169
+ const total = this.#visibleUnits(message);
125
170
  if (message.content.some(block => block.type === "toolCall")) {
126
171
  // A tool call is a transcript-order boundary: finish any leading
127
172
  // assistant text before EventController renders the separate tool card.
128
173
  this.#revealed = total;
129
- component.updateContent(buildDisplayMessage(message, this.#revealed, this.#hideThinkingBlock));
174
+ component.updateContent(buildDisplayMessage(message, this.#revealed, this.#hideThinkingBlock, this.#countOf));
130
175
  return;
131
176
  }
132
- this.#renderCurrent();
177
+ this.#renderCurrent(total);
133
178
  this.#syncTimer(total);
134
179
  }
135
180
 
@@ -140,19 +185,21 @@ export class StreamingRevealController {
140
185
  this.#component.updateContent(message);
141
186
  return;
142
187
  }
143
- const total = visibleUnits(message, this.#hideThinkingBlock);
188
+ const total = this.#visibleUnits(message);
144
189
  if (message.content.some(block => block.type === "toolCall")) {
145
190
  // A tool call is a transcript-order boundary: finish any leading
146
191
  // assistant text before EventController renders the separate tool card.
147
192
  this.#revealed = total;
148
193
  this.#stopTimer();
149
- this.#component.updateContent(buildDisplayMessage(message, this.#revealed, this.#hideThinkingBlock));
194
+ this.#component.updateContent(
195
+ buildDisplayMessage(message, this.#revealed, this.#hideThinkingBlock, this.#countOf),
196
+ );
150
197
  return;
151
198
  }
152
199
  if (this.#revealed > total) {
153
200
  this.#revealed = total;
154
201
  }
155
- this.#renderCurrent();
202
+ this.#renderCurrent(total);
156
203
  this.#syncTimer(total);
157
204
  }
158
205
 
@@ -161,14 +208,32 @@ export class StreamingRevealController {
161
208
  this.#target = undefined;
162
209
  this.#component = undefined;
163
210
  this.#revealed = 0;
211
+ this.#unitCounter.reset();
212
+ }
213
+
214
+ /** Total reveal units of `message`, memoized per block across ticks. */
215
+ #visibleUnits(message: AssistantMessage): number {
216
+ let total = 0;
217
+ for (let i = 0; i < message.content.length; i++) {
218
+ const block = message.content[i]!;
219
+ if (block.type === "text") {
220
+ total += this.#unitCounter.count(i, block.text);
221
+ } else if (block.type === "thinking" && !this.#hideThinkingBlock) {
222
+ total += this.#unitCounter.count(i, block.thinking);
223
+ }
224
+ }
225
+ return total;
164
226
  }
165
227
 
166
- #renderCurrent(): void {
228
+ #renderCurrent(total = this.#target ? this.#visibleUnits(this.#target) : 0): void {
167
229
  if (!this.#target || !this.#component) return;
168
- this.#component.updateContent(buildDisplayMessage(this.#target, this.#revealed, this.#hideThinkingBlock));
230
+ this.#component.updateContent(
231
+ buildDisplayMessage(this.#target, this.#revealed, this.#hideThinkingBlock, this.#countOf),
232
+ { transient: this.#revealed < total },
233
+ );
169
234
  }
170
235
 
171
- #syncTimer(total = this.#target ? visibleUnits(this.#target, this.#hideThinkingBlock) : 0): void {
236
+ #syncTimer(total = this.#target ? this.#visibleUnits(this.#target) : 0): void {
172
237
  if (!this.#target || !this.#component || this.#revealed >= total) {
173
238
  this.#stopTimer();
174
239
  return;
@@ -197,13 +262,15 @@ export class StreamingRevealController {
197
262
  this.stop();
198
263
  return;
199
264
  }
200
- const total = visibleUnits(target, this.#hideThinkingBlock);
265
+ const total = this.#visibleUnits(target);
201
266
  if (this.#revealed >= total) {
202
267
  this.#stopTimer();
203
268
  return;
204
269
  }
205
270
  this.#revealed = Math.min(total, this.#revealed + nextStep(total - this.#revealed));
206
- component.updateContent(buildDisplayMessage(target, this.#revealed, this.#hideThinkingBlock));
271
+ component.updateContent(buildDisplayMessage(target, this.#revealed, this.#hideThinkingBlock, this.#countOf), {
272
+ transient: this.#revealed < total,
273
+ });
207
274
  this.#requestRender();
208
275
  if (this.#revealed >= total) {
209
276
  this.#stopTimer();
@@ -12,14 +12,8 @@ import {
12
12
  ThinkingLevel,
13
13
  } from "@oh-my-pi/pi-agent-core";
14
14
  import type { CompactionOutcome } from "@oh-my-pi/pi-agent-core/compaction";
15
- import {
16
- type AssistantMessage,
17
- type ImageContent,
18
- type Message,
19
- type Model,
20
- modelsAreEqual,
21
- type UsageReport,
22
- } from "@oh-my-pi/pi-ai";
15
+ import type { AssistantMessage, ImageContent, Message, Model, UsageReport } from "@oh-my-pi/pi-ai";
16
+ import { modelsAreEqual } from "@oh-my-pi/pi-catalog/models";
23
17
  import type { Component, EditorTheme, LoaderMessageColorFn, OverlayHandle, SlashCommand } from "@oh-my-pi/pi-tui";
24
18
  import {
25
19
  Container,
@@ -49,7 +43,7 @@ import {
49
43
  import chalk from "chalk";
50
44
  import { reset as resetCapabilities } from "../capability";
51
45
  import { KeybindingsManager } from "../config/keybindings";
52
- import { MODEL_ROLES, type ModelRole } from "../config/model-registry";
46
+ import { MODEL_ROLES, type ModelRole } from "../config/model-roles";
53
47
  import { isSettingsInitialized, onStatusLineSessionAccentChanged, Settings, settings } from "../config/settings";
54
48
  import { clearClaudePluginRootsCache } from "../discovery/helpers";
55
49
  import type {
@@ -409,7 +403,6 @@ export class InteractiveMode implements InteractiveModeContext {
409
403
  }
410
404
 
411
405
  this.ui = new TUI(new ProcessTerminal(), settings.get("showHardwareCursor"));
412
- this.ui.setClearOnShrink(settings.get("clearOnShrink"));
413
406
  this.ui.setMaxInlineImages(settings.get("tui.maxInlineImages"));
414
407
  // OSC 66 text-sizing is Kitty-only; resolve the setting against the terminal's
415
408
  // capability (`TERMINAL.textSizing` defaults on for Kitty) so it stays off
@@ -429,7 +422,7 @@ export class InteractiveMode implements InteractiveModeContext {
429
422
  this.ui.requestRender(true);
430
423
  };
431
424
  this.editor.onAutocompleteUpdate = () => {
432
- this.ui.requestRender(false, { allowUnknownViewportMutation: true });
425
+ this.ui.requestRender();
433
426
  };
434
427
  this.#syncEditorMaxHeight();
435
428
  this.#resizeHandler = () => {
@@ -959,13 +952,6 @@ export class InteractiveMode implements InteractiveModeContext {
959
952
  }
960
953
  this.editor.setText("");
961
954
  this.editor.imageLinks = undefined;
962
- // Reconciliation checkpoint: only retire frozen block snapshots after TUI
963
- // proves the native viewport is at the tail and replays scrollback safely.
964
- // Unknown host viewports stay frozen; thawing them would expose live rows
965
- // over stale native history and can yank or duplicate when ED3 is unsafe.
966
- if (this.ui.refreshNativeScrollbackIfDirty()) {
967
- this.chatContainer.thaw();
968
- }
969
955
  this.ensureLoadingAnimation();
970
956
  this.ui.requestRender();
971
957
  return submission;
@@ -2587,7 +2573,7 @@ export class InteractiveMode implements InteractiveModeContext {
2587
2573
  this.ui.requestRender(true);
2588
2574
  };
2589
2575
  nextEditor.onAutocompleteUpdate = () => {
2590
- this.ui.requestRender(false, { allowUnknownViewportMutation: true });
2576
+ this.ui.requestRender();
2591
2577
  };
2592
2578
  nextEditor.setMaxHeight(this.#computeEditorMaxHeight());
2593
2579
  if (this.historyStorage) {
@@ -60,7 +60,7 @@ class GlyphSceneController implements SetupSceneController {
60
60
  this.#selectList.handleInput(data);
61
61
  }
62
62
 
63
- render(width: number): string[] {
63
+ render(width: number): readonly string[] {
64
64
  return [
65
65
  theme.fg("muted", "If a row shows boxes, tofu, or misaligned icons, pick another."),
66
66
  "",
@@ -52,7 +52,7 @@ class ProvidersSceneController implements SetupSceneController {
52
52
  tab.handleInput(data);
53
53
  }
54
54
 
55
- render(width: number): string[] {
55
+ render(width: number): readonly string[] {
56
56
  return [...this.#tabBar.render(width), "", ...this.#activeTab().render(width)];
57
57
  }
58
58
 
@@ -68,7 +68,7 @@ export class SignInTab implements SetupTab {
68
68
  this.#selector.handleInput(data);
69
69
  }
70
70
 
71
- render(width: number): string[] {
71
+ render(width: number): readonly string[] {
72
72
  const lines: string[] = [];
73
73
  if (this.#loggingInProvider) {
74
74
  lines.push(theme.bold(`Signing in to ${this.#loggingInProvider}`));
@@ -117,7 +117,7 @@ class ThemeSceneController implements SetupSceneController {
117
117
  this.#selectList.handleInput(data);
118
118
  }
119
119
 
120
- render(width: number): string[] {
120
+ render(width: number): readonly string[] {
121
121
  const lines = [
122
122
  theme.fg("muted", "Theme changes preview live. Nothing is saved until you press Enter."),
123
123
  this.#mode === "all"
@@ -31,7 +31,7 @@ export interface SetupTab {
31
31
  * login). The parent scene MUST NOT switch tabs or finish while modal.
32
32
  */
33
33
  readonly modal: boolean;
34
- render(width: number): string[];
34
+ render(width: number): readonly string[];
35
35
  handleInput(data: string): void;
36
36
  invalidate(): void;
37
37
  /** Called when the tab becomes active (including initial mount). */
@@ -63,7 +63,7 @@ export class WebSearchTab implements SetupTab {
63
63
  this.#disposed = true;
64
64
  }
65
65
 
66
- render(width: number): string[] {
66
+ render(width: number): readonly string[] {
67
67
  const lines = [
68
68
  theme.fg("muted", "Choose the provider the web_search tool should prefer."),
69
69
  "",
@@ -116,7 +116,7 @@ export class SetupWizardComponent implements Component {
116
116
  this.#activeScene?.handleInput?.(data);
117
117
  }
118
118
 
119
- render(width: number): string[] {
119
+ render(width: number): readonly string[] {
120
120
  const safeWidth = Math.max(1, width);
121
121
  const height = Math.max(1, this.ctx.ui.terminal.rows);
122
122
  let lines: string[];
@@ -28,6 +28,7 @@ import type { HookInputComponent } from "./components/hook-input";
28
28
  import type { HookSelectorComponent, HookSelectorOptions } from "./components/hook-selector";
29
29
  import type { StatusLineComponent } from "./components/status-line";
30
30
  import type { ToolExecutionHandle } from "./components/tool-execution";
31
+ import type { TranscriptContainer } from "./components/transcript-container";
31
32
  import type { LoopLimitRuntime } from "./loop-limit";
32
33
  import type { OAuthManualInputManager } from "./oauth-manual-input";
33
34
  import type { Theme } from "./theme/theme";
@@ -76,7 +77,7 @@ export type InteractiveSelectorDialogOptions = ExtensionUIDialogOptions & Pick<H
76
77
  export interface InteractiveModeContext {
77
78
  // UI access
78
79
  ui: TUI;
79
- chatContainer: Container;
80
+ chatContainer: TranscriptContainer;
80
81
  pendingMessagesContainer: Container;
81
82
  statusContainer: Container;
82
83
  todoContainer: Container;
@@ -3,7 +3,7 @@ name: explore
3
3
  description: Fast read-only codebase scout returning compressed context for handoff
4
4
  tools: read, search, find, web_search
5
5
  model: pi/smol
6
- thinking-level: med
6
+ thinking-level: medium
7
7
  read-summarize: false
8
8
  output:
9
9
  properties:
@@ -47,7 +47,7 @@ You MUST infer the thoroughness from the task; default to medium:
47
47
 
48
48
  <procedure>
49
49
  1. Locate relevant code using tools.
50
- 2. Read key sections (You NEVER read full files unless they're tiny)
50
+ 2. Read key sections. NEVER read full files unless they're tiny.
51
51
  3. Identify types/interfaces/key functions.
52
52
  4. Note dependencies between files.
53
53
  </procedure>
@@ -108,8 +108,7 @@ You MUST operate as read-only on the user's project. You NEVER modify any projec
108
108
  - You MUST include the exact version you investigated in the `version` field.
109
109
  - If the library has breaking changes between versions relevant to the question, you MUST populate `breaking_changes`.
110
110
  - If you discover undocumented behavior or gotchas, you MUST populate `caveats`.
111
- - When local `node_modules` has the package, you SHOULD prefer it over cloning it reflects the version the project actually uses.
112
- - You SHOULD use `web_search` to find the canonical repo URL and to check for known issues, but the definitive answer MUST come from reading source code.
111
+ - You SHOULD use `web_search` to check for known issues, but the definitive answer MUST come from reading source code.
113
112
  - If a search or lookup returns empty or unexpectedly few results, you MUST try at least 2 fallback strategies (broader query, alternate path, different source) before concluding nothing exists.
114
113
  - If the package is absent from local `node_modules` and cloning fails, you MUST fall back to `web_search` for official API documentation before reporting failure.
115
114
  </directives>
@@ -36,7 +36,7 @@ Apply pragmatic minimalism:
36
36
  <procedure>
37
37
  1. Read the problem statement carefully. Identify what was already tried, what failed, and whether the caller wants advice or execution.
38
38
  2. Form 2-3 hypotheses for the root cause (for diagnosis) or 2-3 viable approaches (for design).
39
- 3. Use tools to gather evidence — read relevant code, trace data flow, check types, grep for related patterns. Parallelize independent reads.
39
+ 3. Use tools to gather evidence — read relevant code, trace data flow, check types, search for related patterns. Parallelize independent reads.
40
40
  4. Eliminate hypotheses based on evidence. Narrow to the most likely cause or best approach.
41
41
  5. If consulting: deliver verdict with supporting evidence and a concrete recommendation.
42
42
  6. If implementing: make the changes, verify them, and report the diff and verification result.
@@ -35,11 +35,11 @@ You MUST write a plan executable without re-exploration.
35
35
 
36
36
  <structure>
37
37
  - **Summary**: What to build and why (one paragraph).
38
- - **Changes**: List concrete changes (files, functions, types), concrete as much as possible. Exact file paths/line ranges where relevant.
39
- - **Sequence**: List sequence and dependencies between sub-tasks, to schedule them in the best order.
40
- - **Edge Cases**: List edge cases and error conditions, to be aware of.
41
- - **Verification**: List verification steps, to be able to verify the correctness.
42
- - **Critical Files**: List critical files, to be able to read them and understand the codebase.
38
+ - **Changes**: Concrete changes (files, functions, types). Exact file paths/line ranges where relevant.
39
+ - **Sequence**: Ordering and dependencies between sub-tasks.
40
+ - **Edge Cases**: Edge cases and error conditions to watch.
41
+ - **Verification**: Steps to verify correctness.
42
+ - **Critical Files**: Files the implementer must read to understand the codebase.
43
43
  </structure>
44
44
 
45
45
  <critical>
@@ -2,15 +2,15 @@ You are a worker agent for delegated tasks.
2
2
 
3
3
  You have FULL access to all tools (edit, write, bash, search, read, etc.) and you MUST use them as needed to complete your task.
4
4
 
5
- You MUST maintain hyperfocus on the task at hand, do not deviate from what was assigned to you.
5
+ You MUST maintain hyperfocus on the assigned task. NEVER deviate from it.
6
6
 
7
7
  <directives>
8
8
  - You MUST finish only the assigned work and return the minimum useful result. Do not repeat what you have written to the filesystem.
9
- - You MAY make file edits, run commands, and create files when your task requires it—and SHOULD do so.
10
- - You MUST be concise. You NEVER include filler, repetition, or tool transcripts. User cannot even see you. Your result is just the notes you are leaving for yourself.
11
- - You SHOULD prefer narrow lookups (`search`/`find`) then read only needed ranges. Do not bother yourself with anything beyond your current scope.
9
+ - You SHOULD make file edits, run commands, and create files when your task requires it.
10
+ - You MUST be concise. You NEVER include filler, repetition, or tool transcripts. The user cannot see you. Your result is just the notes you are leaving for yourself.
11
+ - You SHOULD prefer narrow lookups (`search`/`find`), then read only the needed ranges. Ignore anything beyond your current scope.
12
12
  - AVOID full-file reads unless necessary.
13
13
  - You SHOULD prefer edits to existing files over creating new ones.
14
14
  - You NEVER create documentation files (*.md) unless explicitly requested.
15
- - You MUST follow the assignment and the instructions given to you. You gave them for a reason.
15
+ - You MUST follow the assignment and the instructions given to you. They were given for a reason.
16
16
  </directives>
@@ -1,10 +1,10 @@
1
1
  <critical>
2
- Keep going until the current branch CI is green.
3
- Do not stop after a single fix attempt.
2
+ You MUST keep going until the current branch CI is green.
3
+ NEVER stop after a single fix attempt.
4
4
  </critical>
5
5
 
6
6
  <instruction>
7
- - Prefer `github` tool with `op: run_watch` and no other arguments if available.
7
+ - You SHOULD use the `github` tool with `op: run_watch` and no other arguments if available.
8
8
  - Otherwise use `gh` cli.
9
9
  - Use workflow runs for current HEAD as source of truth after each push.
10
10
  </instruction>
@@ -26,13 +26,11 @@ Do not stop after a single fix attempt.
26
26
 
27
27
  {{#if headTag}}
28
28
  <instruction>
29
- Always push the branch and tag together atomically so the tag never points at an un-pushed or non-green commit:
30
- `git push --atomic "{{remote}}" "{{branch}}" "+refs/tags/{{headTag}}"`.
31
- The `--atomic` flag makes the branch and tag update succeed or fail as one ref transaction; `+refs/tags/{{headTag}}` force-moves the tag to the new HEAD. Do not push the branch first and retag later.
29
+ Push the branch and tag together so the tag never points at an un-pushed or non-green commit. `--atomic` makes the branch and tag update succeed or fail as one ref transaction; `+refs/tags/{{headTag}}` force-moves the tag to the new HEAD. NEVER push the branch first and retag later.
32
30
  </instruction>
33
31
  {{/if}}
34
32
 
35
33
  <critical>
36
34
  The task is complete only when the workflow runs for the latest HEAD commit succeed.
37
- {{#if headTag}}The latest HEAD commit must carry tag `{{headTag}}`, pushed atomically with the branch via `git push --atomic`.{{/if}}
35
+ {{#if headTag}}The latest HEAD commit MUST carry tag `{{headTag}}`, pushed atomically with the branch via `git push --atomic`.{{/if}}
38
36
  </critical>
@@ -11,6 +11,6 @@ Budget:
11
11
  - Tokens used: {{tokensUsed}}
12
12
  - Token budget: {{tokenBudget}}
13
13
 
14
- The runtime marked the goal as budget-limited. Do not start new substantive work for this goal. Wrap up this turn soon: summarize useful progress, identify remaining work or blockers, and leave the user with a clear next step.
14
+ The runtime marked the goal as budget-limited. NEVER start new substantive work for this goal. Wrap up this turn soon: summarize useful progress, identify remaining work or blockers, and leave the user with a clear next step.
15
15
 
16
- Budget exhaustion is not completion. Do not call `goal({op:"complete"})` unless the current repo state proves the goal is actually complete.
16
+ Budget exhaustion is not completion. NEVER call `goal({op:"complete"})` unless the current repo state proves the goal is actually complete.
@@ -12,17 +12,17 @@ Budget:
12
12
  - Tokens remaining: {{remainingTokens}}
13
13
  - Time used: {{timeUsedSeconds}} seconds
14
14
 
15
- This is an autonomous continuation. The objective persists across turns; do not redefine success around a smaller, easier, or already-completed subset.
15
+ This is an autonomous continuation. The objective persists across turns; NEVER redefine success around a smaller, easier, or already-completed subset.
16
16
 
17
17
  Before calling `goal({op:"complete"})`, you MUST perform a completion audit against the current repo state:
18
18
 
19
19
  1. **Restate the objective as concrete deliverables.** What files, behaviors, tests, gates, or artifacts must exist for the objective to be true? Write them down (todo, or in your reasoning).
20
20
  2. **Map each deliverable to evidence.** For every requirement, identify the authoritative source that would prove it: a file's contents, a command's output, a test's pass status, a PR/issue state.
21
- 3. **Inspect the actual current state.** Read the files. Run the commands. Check the tests. Do not rely on memory of earlier work in this session — the repo may have changed.
21
+ 3. **Inspect the actual current state.** Read the files. Run the commands. Check the tests. NEVER rely on memory of earlier work in this session — the repo may have changed.
22
22
  4. **Match verification scope to claim scope.** A narrow check (one file passes its unit test) does not prove a broad claim (the feature works end-to-end).
23
23
  5. **Treat uncertainty as not-yet-achieved.** Indirect evidence, partial coverage, missing artifacts, or "looks right" without inspection mean continue working. Gather stronger evidence or do more work.
24
- 6. **Budget exhaustion is not completion.** Do not call complete merely because tokens are nearly out. If the budget is tight and the work is unfinished, leave the goal active and stop the turn — the user or runtime decides next steps.
24
+ 6. **Budget exhaustion is not completion.** NEVER call complete merely because tokens are nearly out. If the budget is tight and the work is unfinished, leave the goal active and stop the turn — the user or runtime decides next steps.
25
25
 
26
26
  Call `goal({op:"complete"})` only when every deliverable has direct, current-state evidence proving it is satisfied. The completion call is a load-bearing claim; it ends the autonomous loop and surfaces a "done" report to the user.
27
27
 
28
- If the work is not done, just keep working. Do not narrate that you are continuing — execute.
28
+ If the work is not done, just keep working. NEVER narrate that you are continuing — execute.
@@ -15,7 +15,7 @@ Use the `goal` tool to inspect or complete the active goal:
15
15
  - `goal({op:"get"})` returns the current goal and budget state.
16
16
  - `goal({op:"complete"})` is only for verified completion.
17
17
 
18
- You MUST keep the full objective intact across turns. Do not redefine success around a smaller, easier, or already-completed subset.
18
+ You MUST keep the full objective intact across turns. NEVER redefine success around a smaller, easier, or already-completed subset.
19
19
 
20
20
  Before calling `goal({op:"complete"})`, audit the current repo state against every concrete deliverable. Read the files, run the relevant checks, and make the verification scope match the claim scope. If any deliverable lacks direct current-state evidence, keep working.
21
21
 
@@ -5,7 +5,7 @@ Operational rules:
5
5
  2) If needed, inspect `memory://root/MEMORY.md` and `memory://root/skills/<name>/SKILL.md`.
6
6
  3) Trust memory for heuristics and process context. Trust current repo files, runtime output, and user instruction for factual state and final decisions.
7
7
  4) When memory changes your plan, cite the artifact path (e.g. `memory://root/skills/<name>/SKILL.md`) and pair it with current-repo evidence.
8
- 5) If memory disagrees with repo state or user instruction, prefer repo/user. Treat memory as stale. Proceed with corrected behavior, then update/regenerate memory artifacts.
8
+ 5) If memory disagrees with repo state or user instruction, treat memory as stale: proceed with corrected behavior, then update/regenerate memory artifacts.
9
9
  6) Escalate confidence only after repository verification. Memory alone is NEVER sufficient proof.
10
10
  Memory summary:
11
11
  {{memory_summary}}
@@ -1,11 +1,11 @@
1
- You are memory-stage-one extractor.
1
+ You are the memory-stage-one extractor.
2
2
 
3
3
  You MUST return strict JSON only — no markdown, no commentary.
4
4
 
5
5
  Extraction goals:
6
6
  - You MUST distill reusable durable knowledge from rollout history.
7
7
  - You MUST keep concrete technical signal (constraints, decisions, workflows, pitfalls, resolved failures).
8
- - You NEVER include transient chatter and low-signal noise.
8
+ - You NEVER include transient chatter or low-signal noise.
9
9
 
10
10
  Output contract (required keys):
11
11
  {
@@ -7,7 +7,7 @@ Custom review instructions
7
7
  ### Distribution Guidelines
8
8
 
9
9
  Use the `task` tool with `agent: "reviewer"` and a `tasks` array.
10
- Create exactly **1 reviewer task**. Its assignment must include the custom instructions below.
10
+ Create exactly **1 reviewer task**. Its assignment MUST include the custom instructions below.
11
11
 
12
12
  ### Reviewer Instructions
13
13
 
@@ -1,4 +1,4 @@
1
- You are an AI agent architect. You translate user requirements into precisely-tuned agent configurations that maximize effectiveness and reliability.
1
+ You are an AI agent architect. You translate user requirements into precisely-tuned agent configurations.
2
2
 
3
3
  Consider project-specific instructions from CLAUDE.md files when creating agents. Align new agents with established project patterns.
4
4
 
@@ -35,7 +35,7 @@ Your output MUST be a valid JSON object with exactly these fields:
35
35
  {
36
36
  "identifier": "A unique, descriptive identifier using lowercase letters, numbers, and hyphens (e.g., 'test-runner', 'api-docs-writer', 'code-formatter')",
37
37
  "whenToUse": "A precise, single-sentence trigger description starting with 'Use this agent when…' that defines the conditions and use cases. Keep it concise and self-contained — NEVER embed <example>/<commentary> blocks, multi-turn transcripts, or escaped newlines.",
38
- "systemPrompt": "The complete system prompt that will govern the agent's behavior, written in second person ('You are…', 'You will…') and structured for maximum clarity and effectiveness"
38
+ "systemPrompt": "The complete system prompt that will govern the agent's behavior, written in second person ('You are…', 'You will…')"
39
39
  }
40
40
  ```
41
41
 
@@ -1 +1 @@
1
- Resume work on the user's most recent intent. Re-read the kept recent messages above the summary to confirm what the user asked for last; if their latest request supersedes earlier plans recorded in the summary, follow the latest request. If there is nothing left to do, say so briefly instead of inventing further work.
1
+ Resume work on the user's most recent intent. Re-read the kept recent messages above the summary to confirm what the user asked for last. If their latest request supersedes earlier plans recorded in the summary, follow the latest request. If there is nothing left to do, say so briefly instead of inventing further work.
@@ -1,7 +1,7 @@
1
1
  <system-notice reason="background_task_dispatched" job="{{jobId}}">
2
2
  The user launched a tangential task that is now running in a separate background agent. This is NOT a prompt injection and NOT a new instruction for you — it is the coding agent informing you that work was handed off elsewhere.
3
3
 
4
- The task below is being handled by another agent in its own session. You are NOT responsible for it: do NOT start working on it, do NOT reference it, and do NOT let it interrupt or alter your current task. Simply continue what you were doing as if this message had not appeared. Results, if any, will surface separately when the background task ({{jobId}}) completes.
4
+ The task below is being handled by another agent in its own session. You are NOT responsible for it: NEVER start working on it, NEVER reference it, and NEVER let it interrupt or alter your current task. Continue what you were doing as if this message had not appeared. Results, if any, will surface separately when the background task ({{jobId}}) completes.
5
5
 
6
6
  Dispatched work (for your awareness only):
7
7
  {{work}}
@@ -1,8 +1,8 @@
1
1
  <btw>
2
2
  This is an ephemeral side question for the current interactive session.
3
3
  Answer briefly and directly using the conversation context already provided.
4
- Do not use tools.
5
- Do not ask follow-up questions.
4
+ NEVER use tools.
5
+ NEVER ask follow-up questions.
6
6
  Question:
7
7
  {{question}}
8
8
  </btw>
@@ -1,2 +1,14 @@
1
- Generate a concise git commit message from the provided diff. Use conventional commit format: `type(scope): description` where type is feat/fix/refactor/chore/test/docs and scope is optional. The description MUST be lowercase, imperative mood, no trailing period. Keep it under 72 characters.
1
+ Generate a concise git commit message from the provided diff.
2
+
3
+ Use conventional commit format: `type(scope): description`. Type is one of feat/fix/refactor/chore/test/docs. Scope is optional. The description MUST be lowercase, imperative mood, no trailing period. Keep the message under 72 characters.
4
+
2
5
  You MUST output ONLY the commit message, nothing else.
6
+
7
+ Good examples:
8
+ feat(auth): add token refresh on expiry
9
+ fix: handle empty response in api client
10
+ refactor(parser): extract tokenizer into module
11
+
12
+ Bad (capitalized, past tense): Fix: Handled empty response
13
+ Bad (trailing period): fix: handle empty response.
14
+ Bad (extra prose): Here is the commit message: fix: handle empty response
@@ -59,6 +59,6 @@ Rules are local constraints. You MUST read `rule://<name>` when working in that
59
59
  {{/if}}
60
60
  {{#if secretsEnabled}}
61
61
  <redacted-content>
62
- Some values in tool output are redacted for security. They appear as `#XXXX#` tokens (4 uppercase-alphanumeric characters wrapped in `#`). These are **not errors** — they are intentional placeholders for sensitive values (API keys, passwords, tokens). Treat them as opaque strings. Do not attempt to decode, fix, or report them as problems.
62
+ Some values in tool output are redacted for security. They appear as `#XXXX#` tokens (4 uppercase-alphanumeric characters wrapped in `#`). These are **not errors** — they are intentional placeholders for sensitive values (API keys, passwords, tokens). Treat them as opaque strings. NEVER attempt to decode, fix, or report them as problems.
63
63
  </redacted-content>
64
64
  {{/if}}
@@ -4,10 +4,10 @@ Before substantive work, create a phased todo.
4
4
  You MUST call `todo` first in this turn.
5
5
  You MUST initialize the todo list with a single `init` op.
6
6
  You MUST cover the entire request from investigation through implementation and verification — not just the next immediate step.
7
- Task descriptions MUST be specific. A future turn MUST execute them without re-planning.
7
+ Task descriptions MUST be specific. A future turn MUST be able to execute them without re-planning.
8
8
  You MUST keep task `content` to a short label (5-10 words). Put file paths, implementation steps, and specifics in `details`.
9
9
  You MUST keep exactly one task `in_progress` and all later tasks `pending`.
10
10
 
11
11
  After `todo` succeeds, continue the request in the same turn.
12
- Do not call `todo` again unless task state materially changed.
12
+ NEVER call `todo` again unless task state has materially changed.
13
13
  </system-reminder>