@linxiraos/pi-tui 1.1.27 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/CHANGELOG.md +50 -461
  2. package/README.md +7 -5
  3. package/dist/types/app-keybindings.d.ts +1 -1
  4. package/dist/types/apps/cleanse-board.d.ts +1 -1
  5. package/dist/types/apps/debug/log-viewer.d.ts +4 -0
  6. package/dist/types/apps/debug/raw-sse-buffer.d.ts +2 -0
  7. package/dist/types/apps/git/git-tui.d.ts +2 -2
  8. package/dist/types/apps/git/help.d.ts +3 -1
  9. package/dist/types/apps/if-bench-board.d.ts +2 -2
  10. package/dist/types/apps/setup-model-picker.d.ts +1 -1
  11. package/dist/types/autocomplete.d.ts +5 -2
  12. package/dist/types/charts/chart-plan.d.ts +674 -0
  13. package/dist/types/charts/chart-svg.d.ts +59 -0
  14. package/dist/types/charts/table-data.d.ts +175 -0
  15. package/dist/types/chat/assistant-message.d.ts +5 -0
  16. package/dist/types/chat/chat-transcript-builder.d.ts +2 -0
  17. package/dist/types/chat/compaction-summary-message.d.ts +1 -0
  18. package/dist/types/chat/execution-shared.d.ts +6 -5
  19. package/dist/types/chat/fence-figure.d.ts +42 -0
  20. package/dist/types/chat/figure-markdown.d.ts +42 -0
  21. package/dist/types/chat/messages.d.ts +1 -1
  22. package/dist/types/chat/svg-figure.d.ts +33 -0
  23. package/dist/types/chat/svg-source.d.ts +49 -0
  24. package/dist/types/chat/table-chart.d.ts +89 -0
  25. package/dist/types/chat/tool-execution.d.ts +2 -0
  26. package/dist/types/chat/user-message.d.ts +15 -2
  27. package/dist/types/chrome/shared.d.ts +9 -0
  28. package/dist/types/chrome/transcript-container.d.ts +6 -0
  29. package/dist/types/components/box.d.ts +1 -0
  30. package/dist/types/components/disclosure.d.ts +1 -0
  31. package/dist/types/components/editor.d.ts +15 -4
  32. package/dist/types/components/form.d.ts +1 -0
  33. package/dist/types/components/image.d.ts +12 -44
  34. package/dist/types/components/key-value-list.d.ts +1 -0
  35. package/dist/types/components/layout/row.d.ts +1 -0
  36. package/dist/types/components/layout/stack.d.ts +1 -0
  37. package/dist/types/components/markdown.d.ts +36 -3
  38. package/dist/types/components/scroll-view.d.ts +1 -0
  39. package/dist/types/components/section.d.ts +1 -0
  40. package/dist/types/components/table.d.ts +1 -0
  41. package/dist/types/components/text.d.ts +1 -0
  42. package/dist/types/components/tree-view.d.ts +7 -0
  43. package/dist/types/components/truncated-text.d.ts +1 -0
  44. package/dist/types/fuzzy.d.ts +29 -1
  45. package/dist/types/key-hint-format.d.ts +1 -1
  46. package/dist/types/keybinding-matchers.d.ts +3 -0
  47. package/dist/types/keybindings.d.ts +1 -1
  48. package/dist/types/kitty-graphics.d.ts +2 -2
  49. package/dist/types/loop-watchdog.d.ts +8 -7
  50. package/dist/types/multiplexers/cmux.d.ts +16 -0
  51. package/dist/types/multiplexers/herdr.d.ts +26 -0
  52. package/dist/types/multiplexers/notify.d.ts +13 -0
  53. package/dist/types/multiplexers/orca.d.ts +12 -0
  54. package/dist/types/multiplexers/screen.d.ts +9 -0
  55. package/dist/types/multiplexers/tmux.d.ts +29 -0
  56. package/dist/types/multiplexers/types.d.ts +100 -0
  57. package/dist/types/multiplexers/wmux.d.ts +12 -0
  58. package/dist/types/multiplexers/zellij.d.ts +12 -0
  59. package/dist/types/native/backend.d.ts +3 -2
  60. package/dist/types/native/blobs.d.ts +7 -3
  61. package/dist/types/native/encode.d.ts +3 -4
  62. package/dist/types/native/overlay.d.ts +5 -0
  63. package/dist/types/overlays/agent-hub-projection.d.ts +6 -5
  64. package/dist/types/overlays/agent-hub-types.d.ts +9 -0
  65. package/dist/types/overlays/agent-hub.d.ts +2 -0
  66. package/dist/types/overlays/agent-transcript-viewer.d.ts +11 -2
  67. package/dist/types/overlays/agents-hub.d.ts +9 -0
  68. package/dist/types/overlays/annotation-overlay.d.ts +19 -2
  69. package/dist/types/overlays/annotation-types.d.ts +2 -0
  70. package/dist/types/overlays/ask-dialog.d.ts +5 -2
  71. package/dist/types/overlays/history-search.d.ts +10 -0
  72. package/dist/types/overlays/hook-selector.d.ts +9 -4
  73. package/dist/types/overlays/jobs-panel.d.ts +1 -7
  74. package/dist/types/overlays/model-browser.d.ts +54 -7
  75. package/dist/types/overlays/model-hub.d.ts +23 -0
  76. package/dist/types/overlays/oauth-selector.d.ts +0 -1
  77. package/dist/types/overlays/plan-review-overlay.d.ts +3 -2
  78. package/dist/types/overlays/session-observer-registry.d.ts +2 -0
  79. package/dist/types/overlays/session-selector.d.ts +6 -2
  80. package/dist/types/overlays/settings-defs.d.ts +1 -0
  81. package/dist/types/overlays/usage-dashboard.d.ts +8 -4
  82. package/dist/types/overlays/usage-display.d.ts +3 -1
  83. package/dist/types/prompt/composer.d.ts +2 -7
  84. package/dist/types/prompt/custom-editor.d.ts +11 -8
  85. package/dist/types/prompt/image-source.d.ts +2 -1
  86. package/dist/types/prompt/interactive-context-helpers.d.ts +4 -1
  87. package/dist/types/prompt/model-mention-autocomplete.d.ts +1 -1
  88. package/dist/types/prompt/welcome.d.ts +19 -42
  89. package/dist/types/render/composite.d.ts +2 -0
  90. package/dist/types/render/output-pane.d.ts +1 -0
  91. package/dist/types/render/render-utils.d.ts +1 -0
  92. package/dist/types/render/tool-card.d.ts +6 -0
  93. package/dist/types/render/width-aware-text.d.ts +2 -0
  94. package/dist/types/setup/scenes/splash.d.ts +1 -1
  95. package/dist/types/setup/scenes/types.d.ts +1 -0
  96. package/dist/types/status-line/component.d.ts +3 -0
  97. package/dist/types/status-line/host.d.ts +4 -1
  98. package/dist/types/status-line/segments.d.ts +2 -0
  99. package/dist/types/status-line/types.d.ts +14 -3
  100. package/dist/types/terminal-capabilities.d.ts +27 -35
  101. package/dist/types/terminal-multiplexer.d.ts +127 -14
  102. package/dist/types/terminal.d.ts +22 -6
  103. package/dist/types/theme/active-symbols.d.ts +1 -1
  104. package/dist/types/theme/schema.d.ts +11 -2
  105. package/dist/types/theme/symbols.d.ts +1 -1
  106. package/dist/types/theme/theme-class.d.ts +7 -0
  107. package/dist/types/theme/theme.d.ts +1 -1
  108. package/dist/types/theme/tui-adapters.d.ts +3 -0
  109. package/dist/types/tmux.d.ts +11 -4
  110. package/dist/types/tools/daemon.d.ts +1 -1
  111. package/dist/types/tools/eval.d.ts +22 -3
  112. package/dist/types/tools/glob.d.ts +4 -0
  113. package/dist/types/tools/native-view.d.ts +47 -0
  114. package/dist/types/tools/output-meta.d.ts +11 -1
  115. package/dist/types/tools/renderer.d.ts +37 -2
  116. package/dist/types/tools/streaming-output.d.ts +20 -1
  117. package/dist/types/tools/task.d.ts +0 -4
  118. package/dist/types/tools/write.d.ts +9 -2
  119. package/dist/types/tools/yield.d.ts +22 -0
  120. package/dist/types/tui.d.ts +31 -0
  121. package/dist/types/utils.d.ts +6 -0
  122. package/dist/types/vim.d.ts +19 -5
  123. package/package.json +13 -9
  124. package/src/app-keybindings.d.ts +1 -1
  125. package/src/app-keybindings.ts +1 -1
  126. package/src/apps/autoresearch-dashboard.ts +7 -3
  127. package/src/apps/cleanse-board.ts +2 -2
  128. package/src/apps/cleanse-picker.ts +1 -1
  129. package/src/apps/debug/log-viewer.ts +188 -72
  130. package/src/apps/debug/raw-sse-buffer.ts +8 -0
  131. package/src/apps/debug/raw-sse.ts +39 -5
  132. package/src/apps/git/diff-pane.ts +26 -5
  133. package/src/apps/git/git-tui.ts +2 -2
  134. package/src/apps/git/help.ts +29 -20
  135. package/src/apps/if-bench-board.ts +2 -2
  136. package/src/apps/ps-top.ts +2 -2
  137. package/src/apps/setup-model-picker.ts +1 -1
  138. package/src/autocomplete.d.ts +5 -2
  139. package/src/autocomplete.ts +67 -43
  140. package/src/charts/chart-plan.d.ts +674 -0
  141. package/src/charts/chart-plan.ts +5081 -0
  142. package/src/charts/chart-svg.d.ts +59 -0
  143. package/src/charts/chart-svg.ts +4657 -0
  144. package/src/charts/table-data.d.ts +175 -0
  145. package/src/charts/table-data.ts +1478 -0
  146. package/src/chat/advisor-message.ts +11 -0
  147. package/src/chat/assistant-message.d.ts +5 -0
  148. package/src/chat/assistant-message.ts +219 -50
  149. package/src/chat/chat-transcript-builder.d.ts +2 -0
  150. package/src/chat/chat-transcript-builder.ts +5 -3
  151. package/src/chat/compaction-summary-message.d.ts +1 -0
  152. package/src/chat/compaction-summary-message.ts +8 -0
  153. package/src/chat/execution-shared.d.ts +6 -5
  154. package/src/chat/execution-shared.ts +42 -25
  155. package/src/chat/fence-figure.d.ts +42 -0
  156. package/src/chat/fence-figure.ts +80 -0
  157. package/src/chat/figure-markdown.d.ts +42 -0
  158. package/src/chat/figure-markdown.ts +174 -0
  159. package/src/chat/messages.d.ts +1 -1
  160. package/src/chat/messages.ts +1 -1
  161. package/src/chat/read-tool-group.ts +6 -4
  162. package/src/chat/skill-message.ts +6 -0
  163. package/src/chat/svg-figure.d.ts +33 -0
  164. package/src/chat/svg-figure.ts +399 -0
  165. package/src/chat/svg-source.d.ts +49 -0
  166. package/src/chat/svg-source.ts +188 -0
  167. package/src/chat/table-chart.d.ts +89 -0
  168. package/src/chat/table-chart.ts +294 -0
  169. package/src/chat/tool-execution.d.ts +2 -0
  170. package/src/chat/tool-execution.ts +80 -6
  171. package/src/chat/user-message.d.ts +15 -2
  172. package/src/chat/user-message.ts +55 -3
  173. package/src/chrome/shared.ts +53 -0
  174. package/src/chrome/transcript-container.d.ts +6 -0
  175. package/src/chrome/transcript-container.ts +93 -13
  176. package/src/components/box.d.ts +1 -0
  177. package/src/components/box.ts +5 -0
  178. package/src/components/disclosure.d.ts +1 -0
  179. package/src/components/disclosure.ts +8 -0
  180. package/src/components/editor.d.ts +15 -4
  181. package/src/components/editor.ts +294 -46
  182. package/src/components/form.d.ts +1 -0
  183. package/src/components/form.ts +8 -0
  184. package/src/components/image.d.ts +12 -44
  185. package/src/components/image.ts +47 -151
  186. package/src/components/key-value-list.d.ts +1 -0
  187. package/src/components/key-value-list.ts +4 -0
  188. package/src/components/layout/row.d.ts +1 -0
  189. package/src/components/layout/row.ts +7 -0
  190. package/src/components/layout/stack.d.ts +1 -0
  191. package/src/components/layout/stack.ts +7 -0
  192. package/src/components/markdown.d.ts +36 -3
  193. package/src/components/markdown.ts +433 -318
  194. package/src/components/scroll-view.d.ts +1 -0
  195. package/src/components/scroll-view.ts +5 -0
  196. package/src/components/section.d.ts +1 -0
  197. package/src/components/section.ts +5 -0
  198. package/src/components/settings-list.ts +2 -0
  199. package/src/components/table.d.ts +1 -0
  200. package/src/components/table.ts +4 -0
  201. package/src/components/text.d.ts +1 -0
  202. package/src/components/text.ts +7 -0
  203. package/src/components/tree-view.d.ts +7 -0
  204. package/src/components/tree-view.ts +38 -8
  205. package/src/components/truncated-text.d.ts +1 -0
  206. package/src/components/truncated-text.ts +5 -0
  207. package/src/desktop-notify.ts +1 -1
  208. package/src/fuzzy.d.ts +29 -1
  209. package/src/fuzzy.ts +115 -30
  210. package/src/key-hint-format.d.ts +1 -1
  211. package/src/key-hint-format.ts +1 -1
  212. package/src/keybinding-matchers.d.ts +3 -0
  213. package/src/keybinding-matchers.ts +6 -2
  214. package/src/keybindings.d.ts +1 -1
  215. package/src/keybindings.ts +1 -1
  216. package/src/kitty-graphics.d.ts +2 -2
  217. package/src/kitty-graphics.ts +4 -4
  218. package/src/loop-watchdog.d.ts +8 -7
  219. package/src/loop-watchdog.ts +18 -13
  220. package/src/multiplexers/cmux.d.ts +16 -0
  221. package/src/multiplexers/cmux.ts +29 -0
  222. package/src/multiplexers/herdr.d.ts +26 -0
  223. package/src/multiplexers/herdr.ts +64 -0
  224. package/src/multiplexers/notify.d.ts +13 -0
  225. package/src/multiplexers/notify.ts +24 -0
  226. package/src/multiplexers/orca.d.ts +12 -0
  227. package/src/multiplexers/orca.ts +16 -0
  228. package/src/multiplexers/screen.d.ts +9 -0
  229. package/src/multiplexers/screen.ts +15 -0
  230. package/src/multiplexers/tmux.d.ts +29 -0
  231. package/src/multiplexers/tmux.ts +40 -0
  232. package/src/multiplexers/types.d.ts +100 -0
  233. package/src/multiplexers/types.ts +110 -0
  234. package/src/multiplexers/wmux.d.ts +12 -0
  235. package/src/multiplexers/wmux.ts +16 -0
  236. package/src/multiplexers/zellij.d.ts +12 -0
  237. package/src/multiplexers/zellij.ts +24 -0
  238. package/src/native/backend.d.ts +3 -2
  239. package/src/native/backend.ts +174 -18
  240. package/src/native/blobs.d.ts +7 -3
  241. package/src/native/blobs.ts +47 -12
  242. package/src/native/encode.d.ts +3 -4
  243. package/src/native/encode.ts +58 -31
  244. package/src/native/overlay.d.ts +5 -0
  245. package/src/native/overlay.ts +13 -0
  246. package/src/native/reconcile.ts +4 -0
  247. package/src/overlays/agent-hub-projection.d.ts +6 -5
  248. package/src/overlays/agent-hub-projection.ts +124 -13
  249. package/src/overlays/agent-hub-types.d.ts +9 -0
  250. package/src/overlays/agent-hub-types.ts +6 -0
  251. package/src/overlays/agent-hub.ts +46 -31
  252. package/src/overlays/agent-transcript-viewer.ts +91 -23
  253. package/src/overlays/agents-hub.ts +28 -8
  254. package/src/overlays/annotation-overlay.ts +293 -90
  255. package/src/overlays/annotation-types.ts +2 -0
  256. package/src/overlays/ask-dialog.ts +7 -10
  257. package/src/overlays/btw-history-panel.ts +12 -1
  258. package/src/overlays/copy-selector.ts +30 -8
  259. package/src/overlays/extensions/state-manager.ts +52 -12
  260. package/src/overlays/history-search.ts +100 -7
  261. package/src/overlays/hook-selector.ts +12 -5
  262. package/src/overlays/jobs-panel.ts +28 -46
  263. package/src/overlays/model-browser.ts +341 -110
  264. package/src/overlays/model-hub.ts +300 -49
  265. package/src/overlays/move-overlay.ts +28 -14
  266. package/src/overlays/oauth-selector.ts +54 -70
  267. package/src/overlays/plan-review-overlay.ts +194 -70
  268. package/src/overlays/plugin-settings.ts +11 -5
  269. package/src/overlays/report-panel.ts +2 -2
  270. package/src/overlays/rewind-selector.ts +86 -17
  271. package/src/overlays/session-observer-registry.d.ts +2 -0
  272. package/src/overlays/session-observer-registry.ts +10 -2
  273. package/src/overlays/session-selector.ts +64 -26
  274. package/src/overlays/settings-defs.ts +4 -3
  275. package/src/overlays/settings-selector.ts +33 -8
  276. package/src/overlays/snapcompact-shape-preview.ts +2 -3
  277. package/src/overlays/stats-notice.ts +1 -1
  278. package/src/overlays/tree-selector.ts +41 -20
  279. package/src/overlays/usage-dashboard.ts +100 -50
  280. package/src/overlays/usage-display.ts +10 -4
  281. package/src/prompt/attachment-chips.ts +15 -11
  282. package/src/prompt/composer-attachments.ts +6 -4
  283. package/src/prompt/composer-cache.ts +4 -6
  284. package/src/prompt/composer.ts +6 -37
  285. package/src/prompt/custom-editor.ts +54 -26
  286. package/src/prompt/image-source.ts +2 -1
  287. package/src/prompt/interactive-context-helpers.ts +30 -18
  288. package/src/prompt/macos-spelling.ts +7 -0
  289. package/src/prompt/magic-keywords.ts +11 -2
  290. package/src/prompt/model-mention-autocomplete.ts +14 -14
  291. package/src/prompt/tips.txt +6 -5
  292. package/src/prompt/welcome.ts +235 -411
  293. package/src/prompt/word-completion.ts +38 -5
  294. package/src/render/composite.d.ts +2 -0
  295. package/src/render/composite.ts +64 -0
  296. package/src/render/output-pane.d.ts +1 -0
  297. package/src/render/output-pane.ts +6 -0
  298. package/src/render/render-utils.d.ts +1 -0
  299. package/src/render/render-utils.ts +11 -0
  300. package/src/render/tool-card.d.ts +6 -0
  301. package/src/render/tool-card.ts +15 -0
  302. package/src/render/width-aware-text.d.ts +2 -0
  303. package/src/render/width-aware-text.ts +5 -0
  304. package/src/setup/scenes/model.ts +2 -1
  305. package/src/setup/scenes/splash.ts +116 -53
  306. package/src/setup/scenes/types.ts +1 -0
  307. package/src/status-line/component.ts +292 -78
  308. package/src/status-line/host.ts +4 -1
  309. package/src/status-line/segments.ts +40 -22
  310. package/src/status-line/types.ts +15 -3
  311. package/src/terminal-capabilities.d.ts +27 -35
  312. package/src/terminal-capabilities.ts +75 -189
  313. package/src/terminal-multiplexer.d.ts +127 -14
  314. package/src/terminal-multiplexer.ts +112 -33
  315. package/src/terminal.d.ts +22 -6
  316. package/src/terminal.ts +139 -37
  317. package/src/theme/active-symbols.d.ts +1 -1
  318. package/src/theme/active-symbols.ts +1 -1
  319. package/src/theme/schema-validation.ts +1 -0
  320. package/src/theme/schema.d.ts +11 -2
  321. package/src/theme/schema.ts +14 -1
  322. package/src/theme/session-color.ts +1 -7
  323. package/src/theme/symbols.d.ts +1 -1
  324. package/src/theme/symbols.ts +6 -1
  325. package/src/theme/theme-class.d.ts +7 -0
  326. package/src/theme/theme-class.ts +26 -1
  327. package/src/theme/theme-schema.json +5 -1
  328. package/src/theme/theme.d.ts +1 -1
  329. package/src/theme/theme.ts +8 -4
  330. package/src/theme/tui-adapters.d.ts +3 -0
  331. package/src/theme/tui-adapters.ts +68 -0
  332. package/src/tmux.d.ts +11 -4
  333. package/src/tmux.ts +47 -11
  334. package/src/tools/ast-edit.ts +59 -35
  335. package/src/tools/ast-grep.ts +35 -16
  336. package/src/tools/bash.ts +92 -42
  337. package/src/tools/daemon.d.ts +1 -1
  338. package/src/tools/daemon.ts +1 -1
  339. package/src/tools/default-renderer.ts +35 -19
  340. package/src/tools/edit.ts +142 -120
  341. package/src/tools/eval-format/index.ts +28 -2
  342. package/src/tools/eval-format/javascript.ts +7 -5
  343. package/src/tools/eval.d.ts +22 -3
  344. package/src/tools/eval.ts +364 -208
  345. package/src/tools/fetch.ts +5 -6
  346. package/src/tools/glob.d.ts +4 -0
  347. package/src/tools/glob.ts +33 -65
  348. package/src/tools/grep.ts +81 -48
  349. package/src/tools/index.ts +2 -0
  350. package/src/tools/lsp.ts +81 -59
  351. package/src/tools/mcp.ts +111 -68
  352. package/src/tools/native-view.d.ts +47 -0
  353. package/src/tools/native-view.ts +102 -1
  354. package/src/tools/output-meta.d.ts +11 -1
  355. package/src/tools/output-meta.ts +23 -3
  356. package/src/tools/read.ts +7 -5
  357. package/src/tools/renderer.d.ts +37 -2
  358. package/src/tools/renderer.ts +42 -2
  359. package/src/tools/streaming-output.d.ts +20 -1
  360. package/src/tools/streaming-output.ts +149 -50
  361. package/src/tools/task.d.ts +0 -4
  362. package/src/tools/task.ts +112 -59
  363. package/src/tools/todo.ts +119 -30
  364. package/src/tools/wait.ts +34 -24
  365. package/src/tools/web-search.ts +1 -1
  366. package/src/tools/write.d.ts +9 -2
  367. package/src/tools/write.ts +147 -95
  368. package/src/tools/yield.d.ts +22 -0
  369. package/src/tools/yield.ts +225 -0
  370. package/src/tui.d.ts +31 -0
  371. package/src/tui.ts +309 -160
  372. package/src/utils.d.ts +6 -0
  373. package/src/utils.ts +19 -0
  374. package/src/vim.d.ts +19 -5
  375. package/src/vim.ts +333 -18
  376. package/src/windows-input-mode.ts +8 -0
@@ -20,7 +20,6 @@ import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node"
20
20
  import type { ComposerFacts, ComposerFactsSource } from "../status-line/types";
21
21
  import { allowsModelMentions, allowsSkillTokens, SKILL_TOKEN_RE } from "./skill-tokens";
22
22
  import { expandModelMentionTags, MODEL_MENTION_RE, modelMentionToken } from "./model-mention-syntax";
23
- import { imageAttachmentSource } from "./image-source";
24
23
  import { isVideoPath } from "./video";
25
24
  import {
26
25
  attachmentSgr,
@@ -41,7 +40,7 @@ import {
41
40
  } from "./composer-attachments";
42
41
  import { type MacOSSpellingFeatures, MacOSSpellingProvider } from "./macos-spelling";
43
42
  import { hasMagicKeyword, highlightMagicKeywords, magicKeywordRanges } from "./magic-keywords";
44
- import type { TspEditorDecoration } from "@linxiraos/pi-wire";
43
+ import type { TspEditorDecoration, TspText } from "@linxiraos/pi-wire";
45
44
  import { isNativeRendering } from "../native/state";
46
45
  import { isQueuedMessageList, parseQueueShorthand, QUEUE_LIST_MARKER_RE } from "./queue-input";
47
46
  import { type WordCompletionMethod, WordCompletionProvider } from "./word-completion";
@@ -50,8 +49,8 @@ import { fgOrPlain, theme } from "../theme/theme";
50
49
  /** A shell-mode draft's sigil (`!`, `!!`, `$`, `$$`) with its surrounding blanks; the mode chip stands in for it natively. */
51
50
  const SHELL_SIGIL_RE = /^\s*(?:!!?|\$\$?)[ \t]?/;
52
51
 
53
- /** The composer's TSP placeholder; the rotating ANSI hints (thinking effort, …) move into control tooltips. */
54
- const NATIVE_COMPOSER_PLACEHOLDER = "Ask zeta — / commands · @ files · ! bash";
52
+ /** The untitled session's TSP placeholder; the rotating ANSI hints (thinking effort, …) move into control tooltips. */
53
+ const NATIVE_COMPOSER_PLACEHOLDER = "What are we cooking?";
55
54
 
56
55
  /** Live composer state the TSP layout shows; the interactive host wires {@link CustomEditor.composerState}. */
57
56
  export interface ComposerNativeState {
@@ -67,6 +66,8 @@ export interface ComposerNativeState {
67
66
  readonly running: boolean;
68
67
  /** The viewed subagent's lineage, outermost first and the viewed agent last; undefined on the main session. */
69
68
  readonly viewing?: readonly string[];
69
+ /** The session's title, quoted in italics as the TSP placeholder; undefined until it has one. */
70
+ readonly title?: string;
70
71
  }
71
72
 
72
73
  /** Action code prefix of the viewing header's links: `focus:<agent id>`, {@link MAIN_AGENT_ID} for the main session. */
@@ -220,7 +221,7 @@ function normalizePastedPath(path: string): string {
220
221
  }
221
222
  }
222
223
  }
223
- return unquoted.replace(SHELL_ESCAPED_PATH_CHAR_REGEX, "$1");
224
+ return (unquoted.startsWith("\\~/") ? unquoted.slice(1) : unquoted).replace(SHELL_ESCAPED_PATH_CHAR_REGEX, "$1");
224
225
  }
225
226
 
226
227
  function isExplicitPastedPath(path: string): boolean {
@@ -408,7 +409,7 @@ export function extractImagePathFromText(text: string): string | undefined {
408
409
 
409
410
  /**
410
411
  * Resolve the {@link EditorTheme} from a `CustomEditor`/`Editor` constructor
411
- * argument list, tolerating both the zeta `(theme)` and upstream-pi
412
+ * argument list, tolerating both the omp `(theme)` and upstream-pi
412
413
  * `(tui, theme, keybindings)` conventions (see {@link CustomEditor}'s
413
414
  * constructor). A real `EditorTheme` is identified structurally — it exposes a
414
415
  * `borderColor` function and a `symbols` object — so a `TUI` passed in the first
@@ -478,13 +479,13 @@ export class CustomEditor extends Editor {
478
479
  chips: ComposerChipDescriptor[];
479
480
  }
480
481
  | undefined;
481
- /** Host-wired producer of per-image `file://` links (session blob store); drives clickable
482
- * chip tokens for restored drafts (esc-esc, `/tree`, branch). */
482
+ /** Host-wired producer of per-image chip targets (a file on disk, or a session blob copy);
483
+ * drives clickable chip tokens for restored drafts (esc-esc, `/tree`, branch). */
483
484
  draftImageLinkMaterializer?: (images: readonly ImageContent[]) => Promise<(string | undefined)[] | undefined>;
484
485
 
485
486
  /**
486
487
  * The host {@link TUI}, captured when a plugin constructs this editor through
487
- * the upstream-pi `(tui, theme, keybindings)` convention. Undefined for zeta's
488
+ * the upstream-pi `(tui, theme, keybindings)` convention. Undefined for omp's
488
489
  * own `new CustomEditor(theme)` callers (they drive repaints through the
489
490
  * interactive-mode wiring instead). Plugins that call `this.tui.requestRender()`
490
491
  * in their overrides read it here (issue #4766).
@@ -492,7 +493,7 @@ export class CustomEditor extends Editor {
492
493
  tui?: TUI;
493
494
 
494
495
  /**
495
- * Accept both the zeta constructor convention — `new CustomEditor(theme)` —
496
+ * Accept both the omp constructor convention — `new CustomEditor(theme)` —
496
497
  * and the upstream-pi `Editor` convention — `new Editor(tui, theme, keybindings)`
497
498
  * — that {@link ExtensionUIContext.setEditorComponent}'s factory contract
498
499
  * advertises `(tui, theme, keybindings)`. Plugins written against upstream pi
@@ -789,7 +790,7 @@ export class CustomEditor extends Editor {
789
790
  if (!materialize || images.length === 0) return;
790
791
  const links = await materialize(images);
791
792
  if (!links || this.pendingImages !== images) return;
792
- this.pendingImageLinks = images.map((image, index) => imageAttachmentSource(image)?.path ?? links[index]);
793
+ this.pendingImageLinks = links;
793
794
  this.imageLinks = this.pendingImageLinks;
794
795
  this.#requestShimmerRepaint?.();
795
796
  }
@@ -798,10 +799,21 @@ export class CustomEditor extends Editor {
798
799
  * indivisible: a stray backspace deletes the whole token instead of corrupting it. */
799
800
  override atomicTokenPattern = COMPOSER_TOKEN_REGEX;
800
801
 
802
+ /** Atom-table revision and pattern the composer token matcher was last built for. */
803
+ #tokenPatternAtomsRevision = -1;
804
+ #tokenPattern: RegExp | undefined;
805
+
801
806
  #syncComposerTokenPattern(): void {
802
- const labels = [...this.atoms].filter(([, expansion]) => expansion.startsWith("^")).map(([label]) => label);
807
+ // Rebuild only when the atom table changed or someone replaced the pattern since the last sync.
808
+ if (this.#tokenPatternAtomsRevision === this.atomsRevision && this.#tokenPattern === this.atomicTokenPattern) {
809
+ return;
810
+ }
811
+ const labels: string[] = [];
812
+ for (const [label, expansion] of this.atoms) if (expansion.startsWith("^")) labels.push(label);
803
813
  const next = composerTokenRegex(labels);
804
814
  if (next.source !== this.atomicTokenPattern.source) this.atomicTokenPattern = next;
815
+ this.#tokenPatternAtomsRevision = this.atomsRevision;
816
+ this.#tokenPattern = this.atomicTokenPattern;
805
817
  }
806
818
 
807
819
  /** Magic-keyword shimmer cadence — drives one editor repaint every 70 ms while
@@ -819,27 +831,35 @@ export class CustomEditor extends Editor {
819
831
  * timer to request the next animation frame. Undefined when nobody is
820
832
  * listening (tests, headless callers); the timer chain still self-cleans. */
821
833
  #requestShimmerRepaint: (() => void) | undefined;
822
- #queueDecorationText: string | undefined;
834
+ /** Text revision the per-revision decoration inputs below were computed for. */
835
+ #decorationRevision = -1;
836
+ #decorationText = "";
823
837
  #decorationLines: readonly string[] = [""];
824
838
  #queueShorthandActive = false;
825
839
  #queueListActive = false;
826
840
 
827
841
  /** Decorate magic keywords, attachments, and the queue-composer header/list markers.
828
842
  * Queue shorthand reserves its first logical line as a dim `Queueing` label; sequential
829
- * item markers use the accent color so separate follow-ups remain visible while composing. */
843
+ * item markers use the accent color so separate follow-ups remain visible while composing.
844
+ * Called once per layout segment, so whole-buffer inputs are computed once per text revision. */
830
845
  override decorateText = (text: string, context: EditorTextDecorationContext): string => {
831
846
  this.#syncComposerTokenPattern();
832
- const editorText = this.getText();
847
+ if (this.#decorationRevision !== this.textRevision) {
848
+ this.#decorationRevision = this.textRevision;
849
+ const editorText = this.getText();
850
+ if (this.#decorationText !== editorText) {
851
+ this.#decorationText = editorText;
852
+ this.#decorationLines = this.getLines();
853
+ const queueBody = parseQueueShorthand(editorText);
854
+ this.#queueShorthandActive = queueBody !== undefined;
855
+ this.#queueListActive = queueBody !== undefined && isQueuedMessageList(queueBody);
856
+ }
857
+ }
858
+ // One string instance per revision: whole-buffer memos downstream hit on identity.
859
+ const editorText = this.#decorationText;
833
860
  const animated = this.focused && this.#shimmerEnabled() && hasMagicKeyword(editorText);
834
861
  const phase = animated ? (Date.now() % CustomEditor.SHIMMER_PERIOD_MS) / CustomEditor.SHIMMER_PERIOD_MS : 0;
835
862
  if (animated) this.#scheduleShimmerFrame();
836
- if (this.#queueDecorationText !== editorText) {
837
- this.#queueDecorationText = editorText;
838
- this.#decorationLines = this.getLines();
839
- const queueBody = parseQueueShorthand(editorText);
840
- this.#queueShorthandActive = queueBody !== undefined;
841
- this.#queueListActive = queueBody !== undefined && isQueuedMessageList(queueBody);
842
- }
843
863
  let sourceSearchOffset = 0;
844
864
  const locateSource = (value: string): number => {
845
865
  const offset = text.indexOf(value, sourceSearchOffset);
@@ -1018,10 +1038,18 @@ export class CustomEditor extends Editor {
1018
1038
  protected override get nativeSendable(): boolean {
1019
1039
  return this.onSubmit !== undefined && !this.disableSubmit;
1020
1040
  }
1021
- /** Viewing a subagent, the draft goes to it: the placeholder names it. */
1022
- override describePlaceholder = (): string => {
1023
- const agent = this.composerState().viewing?.at(-1);
1024
- return agent === undefined ? NATIVE_COMPOSER_PLACEHOLDER : `Message ${agent}`;
1041
+ /** The quoted-title placeholder, kept while the title stands so the editor node stays reused. */
1042
+ #titlePlaceholder: { title: string; text: TspText } | undefined;
1043
+ /** Viewing a subagent, the draft goes to it: the placeholder names it; else the session's title, quoted in italics. */
1044
+ override describePlaceholder = (): TspText => {
1045
+ const { viewing, title } = this.composerState();
1046
+ const agent = viewing?.at(-1);
1047
+ if (agent !== undefined) return `Message ${agent}`;
1048
+ if (!title) return NATIVE_COMPOSER_PLACEHOLDER;
1049
+ if (this.#titlePlaceholder?.title !== title) {
1050
+ this.#titlePlaceholder = { title, text: [{ t: `“${title}”`, s: "em" }] };
1051
+ }
1052
+ return this.#titlePlaceholder.text;
1025
1053
  };
1026
1054
  /** A shell-mode draft highlights as its language. */
1027
1055
  override describeLanguage = (): string | undefined => this.composerState().shell?.kind;
@@ -4,7 +4,8 @@
4
4
  * to the session's `local://` root, and generated video contact-sheet previews.
5
5
  * Symbol metadata stays out of serialized/model-bound image data while traveling
6
6
  * with the draft object, until AgentSession creates the hidden companion message
7
- * that tells the model the path (and link materialization prefers it over a blob copy).
7
+ * that tells the model the path. The model keeps `local://` references across
8
+ * `/move`; chips for internal URLs instead use a stable blob copy.
8
9
  */
9
10
  import type { ImageContent } from "@linxiraos/pi-ai";
10
11
  import { isRecord } from "@linxiraos/pi-utils";
@@ -1,5 +1,5 @@
1
1
  /** Shared assistant transcript construction and model-authored link caching. */
2
- import type { AssistantMessage, Model } from "@linxiraos/pi-ai";
2
+ import type { AssistantMessage, Model, TextContent } from "@linxiraos/pi-ai";
3
3
  import { getMarkdownLinkUrls } from "../index";
4
4
  import { EMPTY_LINK_TARGETS } from "../render/render-utils";
5
5
  import type { ImageBudget } from "../components/image";
@@ -18,10 +18,13 @@ export interface AssistantMessageHost {
18
18
  readonly proseOnlyThinking: boolean;
19
19
  readonly expandThinkingBlocks: boolean;
20
20
  readonly assistantImagesVisible: boolean;
21
+ /** Whether the viewed session's tables get charts: the main session's do, a focused subagent's do not. */
22
+ readonly tableChartsVisible: boolean;
21
23
  readonly hideToolActivity: boolean;
22
24
  readonly toolOutputExpanded: boolean;
23
25
  readonly ui: { requestRender(): void; readonly imageBudget: ImageBudget };
24
- resolveAssistantMessageLinks(texts: readonly string[]): Promise<ReadonlyMap<string, string>>;
26
+ /** Resolve already-extracted Markdown link destinations to local targets. */
27
+ resolveAssistantMessageLinkHrefs(hrefs: readonly string[]): Promise<ReadonlyMap<string, string>>;
25
28
  }
26
29
 
27
30
  const kMarkdownLinkTargets = Symbol("markdownLinkTargets");
@@ -29,14 +32,26 @@ type SessionWithMarkdownLinkTargets = AssistantMessageSession & {
29
32
  [kMarkdownLinkTargets]?: ReadonlyMap<string, string>;
30
33
  };
31
34
 
32
- function assistantTextBlocks(messages: readonly AssistantMessage[]): string[] {
33
- const texts: string[] = [];
34
- for (const message of messages) {
35
- for (const content of message.content) {
36
- if (content.type === "text") texts.push(content.text);
35
+ /** Link destinations per text block, revalidated against the block's text (streaming blocks grow in place). */
36
+ const textBlockHrefs = new WeakMap<TextContent, { text: string; hrefs: readonly string[] }>();
37
+
38
+ /**
39
+ * Distinct Markdown link destinations authored in `message`'s text blocks.
40
+ * Each block is lexed once per text revision; transcript rebuilds and the
41
+ * message_end refresh reuse the result.
42
+ */
43
+ function assistantMessageLinkHrefs(message: AssistantMessage): string[] {
44
+ const hrefs = new Set<string>();
45
+ for (const content of message.content) {
46
+ if (content.type !== "text") continue;
47
+ let memo = textBlockHrefs.get(content);
48
+ if (memo?.text !== content.text) {
49
+ memo = { text: content.text, hrefs: getMarkdownLinkUrls(content.text) };
50
+ textBlockHrefs.set(content, memo);
37
51
  }
52
+ for (const href of memo.hrefs) hrefs.add(href);
38
53
  }
39
- return texts;
54
+ return [...hrefs];
40
55
  }
41
56
 
42
57
  /**
@@ -51,13 +66,12 @@ export async function refreshAssistantMessageLinkTargets(
51
66
  ): Promise<ReadonlyMap<string, string>> {
52
67
  const session: SessionWithMarkdownLinkTargets = ctx.viewSession;
53
68
  const previous = session[kMarkdownLinkTargets] ?? EMPTY_LINK_TARGETS;
54
- const texts = assistantTextBlocks(messages);
55
69
  const hrefs = new Set<string>();
56
- for (const text of texts) {
57
- for (const href of getMarkdownLinkUrls(text)) hrefs.add(href);
70
+ for (const message of messages) {
71
+ for (const href of assistantMessageLinkHrefs(message)) hrefs.add(href);
58
72
  }
59
73
  if (hrefs.size === 0) return previous;
60
- const resolved = await ctx.resolveAssistantMessageLinks(texts);
74
+ const resolved = await ctx.resolveAssistantMessageLinkHrefs([...hrefs]);
61
75
  let changed = false;
62
76
  for (const href of hrefs) {
63
77
  if (previous.get(href) !== resolved.get(href)) {
@@ -85,12 +99,9 @@ export function assistantMessageLinkTargets(
85
99
  targets: ReadonlyMap<string, string>,
86
100
  ): ReadonlyMap<string, string> {
87
101
  const selected = new Map<string, string>();
88
- for (const content of message.content) {
89
- if (content.type !== "text") continue;
90
- for (const href of getMarkdownLinkUrls(content.text)) {
91
- const target = targets.get(href);
92
- if (target) selected.set(href, target);
93
- }
102
+ for (const href of assistantMessageLinkHrefs(message)) {
103
+ const target = targets.get(href);
104
+ if (target) selected.set(href, target);
94
105
  }
95
106
  return selected;
96
107
  }
@@ -116,6 +127,7 @@ export function createAssistantMessageComponent(
116
127
  ctx.expandThinkingBlocks,
117
128
  );
118
129
  component.setImagesVisible(ctx.assistantImagesVisible);
130
+ component.setTableChartsVisible(ctx.tableChartsVisible);
119
131
  component.setToolResultImagesVisible(!ctx.hideToolActivity);
120
132
  component.setExpanded(ctx.toolOutputExpanded);
121
133
  // A wire the `stream-revision` axis marks `possible` can rewrite text it has
@@ -56,6 +56,8 @@ export class MacOSSpellingProvider implements EditorTextAssistProvider {
56
56
  #availabilityChecked = false;
57
57
  #cacheGeneration = 0;
58
58
  #typoCache = new Map<string, readonly native.SpellingRange[]>();
59
+ /** {@link #projectTypoRanges} answers for the current {@link #typoCache}; segments re-ask every frame. */
60
+ #projectionMemo = new Map<string, readonly native.SpellingRange[] | undefined>();
59
61
  #typoInFlight = new Map<string, Promise<readonly native.SpellingRange[]>>();
60
62
  #automaticTypoActive = false;
61
63
  #automaticTypoQueue = new Map<string, string>();
@@ -237,6 +239,7 @@ export class MacOSSpellingProvider implements EditorTextAssistProvider {
237
239
  return request;
238
240
  }
239
241
  #projectTypoRanges(text: string): readonly native.SpellingRange[] | undefined {
242
+ if (this.#projectionMemo.has(text)) return this.#projectionMemo.get(text);
240
243
  let projected: native.SpellingRange[] | undefined;
241
244
  let matchLength = -1;
242
245
  for (const [previous, ranges] of this.#typoCache) {
@@ -265,6 +268,8 @@ export class MacOSSpellingProvider implements EditorTextAssistProvider {
265
268
  });
266
269
  matchLength = prefix + suffix;
267
270
  }
271
+ if (this.#projectionMemo.size >= CACHE_LIMIT) this.#projectionMemo.clear();
272
+ this.#projectionMemo.set(text, projected);
268
273
  return projected;
269
274
  }
270
275
 
@@ -316,6 +321,7 @@ export class MacOSSpellingProvider implements EditorTextAssistProvider {
316
321
  const hadProjectedRanges = (this.#projectTypoRanges(text)?.length ?? 0) > 0;
317
322
  if (this.#typoCache.size >= CACHE_LIMIT) this.#typoCache.clear();
318
323
  this.#typoCache.set(text, ranges);
324
+ this.#projectionMemo.clear();
319
325
  if (ranges.length > 0 || hadProjectedRanges) this.onUpdate?.();
320
326
  return ranges;
321
327
  }
@@ -323,6 +329,7 @@ export class MacOSSpellingProvider implements EditorTextAssistProvider {
323
329
  #clearCaches(): void {
324
330
  this.#cacheGeneration++;
325
331
  this.#typoCache.clear();
332
+ this.#projectionMemo.clear();
326
333
  this.#typoInFlight.clear();
327
334
  this.#automaticTypoQueue.clear();
328
335
  }
@@ -148,6 +148,9 @@ export function magicKeywordRanges(text: string): { from: number; to: number }[]
148
148
  return ranges.sort((a, b) => a.from - b.from);
149
149
  }
150
150
 
151
+ /** Last {@link hasMagicKeyword} answer: the live editor asks once per layout segment with the same buffer. */
152
+ let lastProbe: { text: string; registry: readonly RegisteredKeyword[]; found: boolean } | undefined;
153
+
151
154
  /**
152
155
  * Cheap test for "does this text contain any registered keyword as standalone
153
156
  * prose?". Short-circuits on a substring probe before paying for the
@@ -155,8 +158,14 @@ export function magicKeywordRanges(text: string): { from: number; to: number }[]
155
158
  * `String#includes` per word. Used by the live editor to gate the shimmer timer.
156
159
  */
157
160
  export function hasMagicKeyword(text: string): boolean {
161
+ if (lastProbe?.text === text && lastProbe.registry === registry) return lastProbe.found;
162
+ let found = false;
158
163
  for (const keyword of registry) {
159
- if (text.includes(keyword.word) && containsMagicKeyword(text, keyword.word)) return true;
164
+ if (text.includes(keyword.word) && containsMagicKeyword(text, keyword.word)) {
165
+ found = true;
166
+ break;
167
+ }
160
168
  }
161
- return false;
169
+ lastProbe = { text, registry, found };
170
+ return found;
162
171
  }
@@ -5,9 +5,7 @@ import { modelMentionDisplayName } from "./model-mention-syntax";
5
5
  import type {
6
6
  buildSearchAffinity as BuildSearchAffinity,
7
7
  ModelBrowserItem,
8
- rankModelItems as RankModelItems,
9
- SearchAffinity,
10
- SessionModelScope,
8
+ ModelItemRanker as ModelItemRankerClass,
11
9
  SessionModelScopeCache as SessionModelScopeCacheClass,
12
10
  } from "../overlays/model-browser";
13
11
  import { theme } from "../theme/theme";
@@ -21,7 +19,7 @@ export type ModelMentionCandidateSource = (query: string) => ReadonlyArray<Model
21
19
  interface ModelBrowserModules {
22
20
  SessionModelScopeCache: typeof SessionModelScopeCacheClass;
23
21
  buildSearchAffinity: typeof BuildSearchAffinity;
24
- rankModelItems: typeof RankModelItems;
22
+ ModelItemRanker: typeof ModelItemRankerClass;
25
23
  }
26
24
 
27
25
  /** Synchronous first-use boundary for the interactive model browser implementation. */
@@ -80,7 +78,7 @@ export function applyModelMentionCompletion(
80
78
 
81
79
  /**
82
80
  * Create a session-scoped model candidate lookup using picker ordering. The
83
- * scope and search affinity are reused across queries until their inputs change.
81
+ * scope and its prepared ranker are reused across queries until their inputs change.
84
82
  */
85
83
  export function createModelMentionSource(host: {
86
84
  source: ModelBrowserSource;
@@ -88,20 +86,22 @@ export function createModelMentionSource(host: {
88
86
  scopedModels: () => ReadonlyArray<Model>;
89
87
  }): ModelMentionCandidateSource {
90
88
  let scopeCache: SessionModelScopeCacheClass | undefined;
91
- let affinityScope: SessionModelScope | undefined;
92
- let affinityProviderOrder: readonly string[] | undefined;
93
- let affinity: SearchAffinity | undefined;
89
+ let ranker: ModelItemRankerClass | undefined;
90
+ let rankerProviderOrder: readonly string[] | undefined;
94
91
  return query => {
95
- const { SessionModelScopeCache, buildSearchAffinity, rankModelItems } = loadModelBrowser();
92
+ const { SessionModelScopeCache, buildSearchAffinity, ModelItemRanker } = loadModelBrowser();
96
93
  scopeCache ??= new SessionModelScopeCache(host.source, host.registry);
97
94
  const scope = scopeCache.get(host.scopedModels());
98
95
  if (!query.trim()) return scope.items;
99
96
  const providerOrder = host.source.modelProviderOrder;
100
- if (!affinity || affinityScope !== scope || affinityProviderOrder !== providerOrder) {
101
- affinity = buildSearchAffinity(providerOrder, scope.roles, scope.mruOrder);
102
- affinityScope = scope;
103
- affinityProviderOrder = providerOrder;
97
+ if (ranker?.items !== scope.items || rankerProviderOrder !== providerOrder) {
98
+ ranker = new ModelItemRanker(scope.items, {
99
+ roles: scope.roles,
100
+ mruOrder: scope.mruOrder,
101
+ affinity: buildSearchAffinity(providerOrder, scope.roles, scope.mruOrder),
102
+ });
103
+ rankerProviderOrder = providerOrder;
104
104
  }
105
- return rankModelItems(query, scope.items, { roles: scope.roles, mruOrder: scope.mruOrder, affinity });
105
+ return ranker.rank(query);
106
106
  };
107
107
  }
@@ -6,17 +6,17 @@ Start your prompt with `$ ` to run Python — `$$ ` runs it without adding the o
6
6
  You can /btw to ask a side question
7
7
  Use /tan to fork the current conversation into a background agent
8
8
  With default keybindings, {key:ctrl+d} deletes the character under the cursor instead of quitting your draft — see /hotkeys for your exit key
9
- Find out which model you emotionally abuse the most with `zeta stats`
9
+ Find out which model you emotionally abuse the most with `zetacode stats`
10
10
  Try task isolation to create CoW worktrees
11
- Need a cheap nested model call? Use `completion(x...)`. Have a big batch of tasks? Ask a subagent to use it!
11
+ Need a cheap nested model call? Use `completion(x...)`
12
12
  Spaghetti code? Try complaining with /omfg
13
- Did you know? Each kitty/tmux/cmux/zellij/wezterm split keeps its own session — `zeta -c` resumes the right one
13
+ Did you know? Each kitty/tmux/cmux/zellij/wezterm split keeps its own session — `zetacode -c` resumes the right one
14
14
  Drop the word `ultrathink` in your message for harder multi-step reasoning — watch it glow rainbow as you type
15
15
  Say `orchestrate` in your message to drive a multi-phase task with parallel subagents — watch it glow as you type
16
16
  Say `workflowz` in your message to drive the task with parallel subagents in eval — watch it glow as you type
17
17
  Bulk data to classify or triage? Say `jevify` in your message — the eval kernel's `judge()` processes the batch and you read only what it flags — watch it glow as you type
18
18
  Log in to several accounts of the same provider — `/login` again — and zeta load-balances across them automatically
19
- Run `zeta auth-broker serve` once and every machine pulls live tokens over the wire — refresh keys never leave the host; `zeta auth-gateway` fronts it as a drop-in proxy any OpenAI-compatible client can hit
19
+ Run `zetacode auth-broker serve` once and every machine pulls live tokens over the wire — refresh keys never leave the host; `zetacode auth-gateway` fronts it as a drop-in proxy any OpenAI-compatible client can hit
20
20
  Press {key:alt+p} (or /switch) to switch provider, and {key:ctrl+p} to cycle role models smol -> slow -> etc
21
21
  Press {key:ctrl+r} to search your prompt history and reuse a past message
22
22
  `/force read` pins the next turn to one specific tool when the model keeps reaching for the wrong one
@@ -29,4 +29,5 @@ Turn on `/advisor` to attach a second model that reviews every turn and quietly
29
29
  Try starting your prompt with a ->, and writing a list (1. Do X, 2. Do Y)
30
30
  Press {key:shift+tab} to cycle through reasoning effort levels
31
31
  zeta can reconfigure and extend itself — ask any questions you have!
32
- Lint/type errors piling up? `zeta cleanse` (or /cleanse right here) hunts project diagnostics and fixes them with parallel subagents — {key:escape} cancels
32
+ Lint/type errors piling up? `zetacode cleanse` (or /cleanse right here) hunts project diagnostics and fixes them with parallel subagents — {key:escape} cancels
33
+ [NO-TERN] Psst, zeta has a natural habitat 🐦 [tern](https://scl.so/tern)