@linxiraos/pi-tui 1.1.27 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (373) hide show
  1. package/CHANGELOG.md +47 -463
  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 +1 -1
  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 +6 -1
  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/types.d.ts +1 -0
  95. package/dist/types/status-line/component.d.ts +3 -0
  96. package/dist/types/status-line/host.d.ts +4 -1
  97. package/dist/types/status-line/segments.d.ts +2 -0
  98. package/dist/types/status-line/types.d.ts +14 -3
  99. package/dist/types/terminal-capabilities.d.ts +27 -35
  100. package/dist/types/terminal-multiplexer.d.ts +127 -14
  101. package/dist/types/terminal.d.ts +22 -6
  102. package/dist/types/theme/active-symbols.d.ts +1 -1
  103. package/dist/types/theme/schema.d.ts +11 -2
  104. package/dist/types/theme/symbols.d.ts +1 -1
  105. package/dist/types/theme/theme-class.d.ts +7 -0
  106. package/dist/types/theme/theme.d.ts +1 -1
  107. package/dist/types/theme/tui-adapters.d.ts +3 -0
  108. package/dist/types/tmux.d.ts +11 -4
  109. package/dist/types/tools/daemon.d.ts +1 -1
  110. package/dist/types/tools/eval.d.ts +22 -3
  111. package/dist/types/tools/glob.d.ts +4 -0
  112. package/dist/types/tools/native-view.d.ts +47 -0
  113. package/dist/types/tools/output-meta.d.ts +11 -1
  114. package/dist/types/tools/renderer.d.ts +37 -2
  115. package/dist/types/tools/streaming-output.d.ts +20 -1
  116. package/dist/types/tools/task.d.ts +0 -4
  117. package/dist/types/tools/write.d.ts +9 -2
  118. package/dist/types/tools/yield.d.ts +22 -0
  119. package/dist/types/tui.d.ts +31 -0
  120. package/dist/types/utils.d.ts +6 -0
  121. package/dist/types/vim.d.ts +19 -5
  122. package/package.json +13 -9
  123. package/src/app-keybindings.d.ts +1 -1
  124. package/src/app-keybindings.ts +1 -1
  125. package/src/apps/autoresearch-dashboard.ts +7 -3
  126. package/src/apps/cleanse-board.ts +2 -2
  127. package/src/apps/cleanse-picker.ts +1 -1
  128. package/src/apps/debug/log-viewer.ts +188 -72
  129. package/src/apps/debug/raw-sse-buffer.ts +8 -0
  130. package/src/apps/debug/raw-sse.ts +39 -5
  131. package/src/apps/git/diff-pane.ts +26 -5
  132. package/src/apps/git/git-tui.ts +2 -2
  133. package/src/apps/git/help.ts +29 -20
  134. package/src/apps/if-bench-board.ts +2 -2
  135. package/src/apps/ps-top.ts +2 -2
  136. package/src/apps/setup-model-picker.ts +1 -1
  137. package/src/autocomplete.d.ts +5 -2
  138. package/src/autocomplete.ts +67 -43
  139. package/src/charts/chart-plan.d.ts +674 -0
  140. package/src/charts/chart-plan.ts +5081 -0
  141. package/src/charts/chart-svg.d.ts +59 -0
  142. package/src/charts/chart-svg.ts +4657 -0
  143. package/src/charts/table-data.d.ts +175 -0
  144. package/src/charts/table-data.ts +1478 -0
  145. package/src/chat/advisor-message.ts +11 -0
  146. package/src/chat/assistant-message.d.ts +5 -0
  147. package/src/chat/assistant-message.ts +219 -50
  148. package/src/chat/chat-transcript-builder.d.ts +2 -0
  149. package/src/chat/chat-transcript-builder.ts +5 -3
  150. package/src/chat/compaction-summary-message.d.ts +1 -0
  151. package/src/chat/compaction-summary-message.ts +8 -0
  152. package/src/chat/execution-shared.d.ts +6 -5
  153. package/src/chat/execution-shared.ts +42 -25
  154. package/src/chat/fence-figure.d.ts +42 -0
  155. package/src/chat/fence-figure.ts +80 -0
  156. package/src/chat/figure-markdown.d.ts +42 -0
  157. package/src/chat/figure-markdown.ts +174 -0
  158. package/src/chat/messages.d.ts +1 -1
  159. package/src/chat/messages.ts +1 -1
  160. package/src/chat/read-tool-group.ts +6 -4
  161. package/src/chat/skill-message.ts +6 -0
  162. package/src/chat/svg-figure.d.ts +33 -0
  163. package/src/chat/svg-figure.ts +399 -0
  164. package/src/chat/svg-source.d.ts +49 -0
  165. package/src/chat/svg-source.ts +188 -0
  166. package/src/chat/table-chart.d.ts +89 -0
  167. package/src/chat/table-chart.ts +294 -0
  168. package/src/chat/tool-execution.d.ts +2 -0
  169. package/src/chat/tool-execution.ts +80 -6
  170. package/src/chat/user-message.d.ts +15 -2
  171. package/src/chat/user-message.ts +55 -3
  172. package/src/chrome/shared.ts +53 -0
  173. package/src/chrome/transcript-container.d.ts +6 -0
  174. package/src/chrome/transcript-container.ts +93 -13
  175. package/src/components/box.d.ts +1 -0
  176. package/src/components/box.ts +5 -0
  177. package/src/components/disclosure.d.ts +1 -0
  178. package/src/components/disclosure.ts +8 -0
  179. package/src/components/editor.d.ts +15 -4
  180. package/src/components/editor.ts +294 -46
  181. package/src/components/form.d.ts +1 -0
  182. package/src/components/form.ts +8 -0
  183. package/src/components/image.d.ts +12 -44
  184. package/src/components/image.ts +47 -151
  185. package/src/components/key-value-list.d.ts +1 -0
  186. package/src/components/key-value-list.ts +4 -0
  187. package/src/components/layout/row.d.ts +1 -0
  188. package/src/components/layout/row.ts +7 -0
  189. package/src/components/layout/stack.d.ts +1 -0
  190. package/src/components/layout/stack.ts +7 -0
  191. package/src/components/markdown.d.ts +36 -3
  192. package/src/components/markdown.ts +433 -318
  193. package/src/components/scroll-view.d.ts +1 -0
  194. package/src/components/scroll-view.ts +5 -0
  195. package/src/components/section.d.ts +1 -0
  196. package/src/components/section.ts +5 -0
  197. package/src/components/settings-list.ts +2 -0
  198. package/src/components/table.d.ts +1 -0
  199. package/src/components/table.ts +4 -0
  200. package/src/components/text.d.ts +1 -0
  201. package/src/components/text.ts +7 -0
  202. package/src/components/tree-view.d.ts +7 -0
  203. package/src/components/tree-view.ts +38 -8
  204. package/src/components/truncated-text.d.ts +1 -0
  205. package/src/components/truncated-text.ts +5 -0
  206. package/src/desktop-notify.ts +1 -1
  207. package/src/fuzzy.d.ts +29 -1
  208. package/src/fuzzy.ts +115 -30
  209. package/src/key-hint-format.d.ts +1 -1
  210. package/src/key-hint-format.ts +1 -1
  211. package/src/keybinding-matchers.d.ts +3 -0
  212. package/src/keybinding-matchers.ts +6 -2
  213. package/src/keybindings.d.ts +1 -1
  214. package/src/keybindings.ts +1 -1
  215. package/src/kitty-graphics.d.ts +2 -2
  216. package/src/kitty-graphics.ts +4 -4
  217. package/src/loop-watchdog.d.ts +8 -7
  218. package/src/loop-watchdog.ts +18 -13
  219. package/src/multiplexers/cmux.d.ts +16 -0
  220. package/src/multiplexers/cmux.ts +29 -0
  221. package/src/multiplexers/herdr.d.ts +26 -0
  222. package/src/multiplexers/herdr.ts +64 -0
  223. package/src/multiplexers/notify.d.ts +13 -0
  224. package/src/multiplexers/notify.ts +24 -0
  225. package/src/multiplexers/orca.d.ts +12 -0
  226. package/src/multiplexers/orca.ts +16 -0
  227. package/src/multiplexers/screen.d.ts +9 -0
  228. package/src/multiplexers/screen.ts +15 -0
  229. package/src/multiplexers/tmux.d.ts +29 -0
  230. package/src/multiplexers/tmux.ts +40 -0
  231. package/src/multiplexers/types.d.ts +100 -0
  232. package/src/multiplexers/types.ts +110 -0
  233. package/src/multiplexers/wmux.d.ts +12 -0
  234. package/src/multiplexers/wmux.ts +16 -0
  235. package/src/multiplexers/zellij.d.ts +12 -0
  236. package/src/multiplexers/zellij.ts +24 -0
  237. package/src/native/backend.d.ts +3 -2
  238. package/src/native/backend.ts +174 -18
  239. package/src/native/blobs.d.ts +7 -3
  240. package/src/native/blobs.ts +47 -12
  241. package/src/native/encode.d.ts +3 -4
  242. package/src/native/encode.ts +58 -31
  243. package/src/native/overlay.d.ts +5 -0
  244. package/src/native/overlay.ts +13 -0
  245. package/src/native/reconcile.ts +4 -0
  246. package/src/overlays/agent-hub-projection.d.ts +6 -5
  247. package/src/overlays/agent-hub-projection.ts +124 -13
  248. package/src/overlays/agent-hub-types.d.ts +9 -0
  249. package/src/overlays/agent-hub-types.ts +6 -0
  250. package/src/overlays/agent-hub.ts +44 -29
  251. package/src/overlays/agent-transcript-viewer.ts +91 -23
  252. package/src/overlays/agents-hub.ts +28 -8
  253. package/src/overlays/annotation-overlay.ts +293 -90
  254. package/src/overlays/annotation-types.ts +2 -0
  255. package/src/overlays/ask-dialog.ts +7 -10
  256. package/src/overlays/btw-history-panel.ts +12 -1
  257. package/src/overlays/copy-selector.ts +30 -8
  258. package/src/overlays/extensions/state-manager.ts +52 -12
  259. package/src/overlays/history-search.ts +100 -7
  260. package/src/overlays/hook-selector.ts +12 -5
  261. package/src/overlays/jobs-panel.ts +28 -46
  262. package/src/overlays/model-browser.ts +341 -110
  263. package/src/overlays/model-hub.ts +300 -49
  264. package/src/overlays/move-overlay.ts +28 -14
  265. package/src/overlays/oauth-selector.ts +54 -70
  266. package/src/overlays/plan-review-overlay.ts +194 -70
  267. package/src/overlays/plugin-settings.ts +3 -3
  268. package/src/overlays/report-panel.ts +2 -2
  269. package/src/overlays/rewind-selector.ts +86 -17
  270. package/src/overlays/session-observer-registry.d.ts +2 -0
  271. package/src/overlays/session-observer-registry.ts +10 -2
  272. package/src/overlays/session-selector.ts +64 -26
  273. package/src/overlays/settings-defs.ts +4 -3
  274. package/src/overlays/settings-selector.ts +33 -8
  275. package/src/overlays/snapcompact-shape-preview.ts +2 -3
  276. package/src/overlays/stats-notice.ts +1 -1
  277. package/src/overlays/tree-selector.ts +41 -20
  278. package/src/overlays/usage-dashboard.ts +100 -50
  279. package/src/overlays/usage-display.ts +10 -4
  280. package/src/prompt/attachment-chips.ts +15 -11
  281. package/src/prompt/composer-attachments.ts +6 -4
  282. package/src/prompt/composer.ts +4 -15
  283. package/src/prompt/custom-editor.ts +54 -26
  284. package/src/prompt/image-source.ts +2 -1
  285. package/src/prompt/interactive-context-helpers.ts +30 -18
  286. package/src/prompt/macos-spelling.ts +7 -0
  287. package/src/prompt/magic-keywords.ts +11 -2
  288. package/src/prompt/model-mention-autocomplete.ts +14 -14
  289. package/src/prompt/tips.txt +6 -5
  290. package/src/prompt/welcome.ts +55 -12
  291. package/src/prompt/word-completion.ts +38 -5
  292. package/src/render/composite.d.ts +2 -0
  293. package/src/render/composite.ts +64 -0
  294. package/src/render/output-pane.d.ts +1 -0
  295. package/src/render/output-pane.ts +6 -0
  296. package/src/render/render-utils.d.ts +1 -0
  297. package/src/render/render-utils.ts +11 -0
  298. package/src/render/tool-card.d.ts +6 -0
  299. package/src/render/tool-card.ts +15 -0
  300. package/src/render/width-aware-text.d.ts +2 -0
  301. package/src/render/width-aware-text.ts +5 -0
  302. package/src/setup/scenes/model.ts +2 -1
  303. package/src/setup/scenes/types.ts +1 -0
  304. package/src/status-line/component.ts +292 -78
  305. package/src/status-line/host.ts +4 -1
  306. package/src/status-line/segments.ts +40 -22
  307. package/src/status-line/types.ts +15 -3
  308. package/src/terminal-capabilities.d.ts +27 -35
  309. package/src/terminal-capabilities.ts +75 -189
  310. package/src/terminal-multiplexer.d.ts +127 -14
  311. package/src/terminal-multiplexer.ts +112 -33
  312. package/src/terminal.d.ts +22 -6
  313. package/src/terminal.ts +139 -37
  314. package/src/theme/active-symbols.d.ts +1 -1
  315. package/src/theme/active-symbols.ts +1 -1
  316. package/src/theme/schema-validation.ts +1 -0
  317. package/src/theme/schema.d.ts +11 -2
  318. package/src/theme/schema.ts +14 -1
  319. package/src/theme/session-color.ts +1 -7
  320. package/src/theme/symbols.d.ts +1 -1
  321. package/src/theme/symbols.ts +6 -1
  322. package/src/theme/theme-class.d.ts +7 -0
  323. package/src/theme/theme-class.ts +26 -1
  324. package/src/theme/theme-schema.json +5 -1
  325. package/src/theme/theme.d.ts +1 -1
  326. package/src/theme/theme.ts +8 -4
  327. package/src/theme/tui-adapters.d.ts +3 -0
  328. package/src/theme/tui-adapters.ts +68 -0
  329. package/src/tmux.d.ts +11 -4
  330. package/src/tmux.ts +47 -11
  331. package/src/tools/ast-edit.ts +59 -35
  332. package/src/tools/ast-grep.ts +35 -16
  333. package/src/tools/bash.ts +92 -42
  334. package/src/tools/daemon.d.ts +1 -1
  335. package/src/tools/daemon.ts +1 -1
  336. package/src/tools/default-renderer.ts +35 -19
  337. package/src/tools/edit.ts +142 -120
  338. package/src/tools/eval-format/index.ts +28 -2
  339. package/src/tools/eval-format/javascript.ts +7 -5
  340. package/src/tools/eval.d.ts +22 -3
  341. package/src/tools/eval.ts +364 -208
  342. package/src/tools/fetch.ts +5 -6
  343. package/src/tools/glob.d.ts +4 -0
  344. package/src/tools/glob.ts +33 -65
  345. package/src/tools/grep.ts +81 -48
  346. package/src/tools/index.ts +2 -0
  347. package/src/tools/lsp.ts +81 -59
  348. package/src/tools/mcp.ts +111 -68
  349. package/src/tools/native-view.d.ts +47 -0
  350. package/src/tools/native-view.ts +102 -1
  351. package/src/tools/output-meta.d.ts +11 -1
  352. package/src/tools/output-meta.ts +23 -3
  353. package/src/tools/read.ts +7 -5
  354. package/src/tools/renderer.d.ts +37 -2
  355. package/src/tools/renderer.ts +42 -2
  356. package/src/tools/streaming-output.d.ts +20 -1
  357. package/src/tools/streaming-output.ts +149 -50
  358. package/src/tools/task.d.ts +0 -4
  359. package/src/tools/task.ts +112 -59
  360. package/src/tools/todo.ts +119 -30
  361. package/src/tools/wait.ts +34 -24
  362. package/src/tools/web-search.ts +1 -1
  363. package/src/tools/write.d.ts +9 -2
  364. package/src/tools/write.ts +147 -95
  365. package/src/tools/yield.d.ts +22 -0
  366. package/src/tools/yield.ts +225 -0
  367. package/src/tui.d.ts +31 -0
  368. package/src/tui.ts +309 -160
  369. package/src/utils.d.ts +6 -0
  370. package/src/utils.ts +19 -0
  371. package/src/vim.d.ts +19 -5
  372. package/src/vim.ts +333 -18
  373. package/src/windows-input-mode.ts +8 -0
@@ -2,7 +2,7 @@ import type { AgentMessage, ThinkingLevel } from "@linxiraos/pi-agent-core";
2
2
  import type { Tool, UsageLimit, UsageReport } from "@linxiraos/pi-ai";
3
3
  import type { Model } from "@linxiraos/pi-catalog/types";
4
4
  import type { CompactionBoundaries } from "./context-usage";
5
- import type { StatusLineSettings } from "./types";
5
+ import type { StatusLineSettings, StatusResetExpiry } from "./types";
6
6
 
7
7
  export interface StatusAccountIdentity {
8
8
  accountId?: string;
@@ -93,6 +93,9 @@ export interface StatusLineHost<TSession extends StatusLineSession = StatusLineS
93
93
  lookupPullRequest(cwd: string): Promise<{ stdout: string; exitCode: number }>;
94
94
  calculateTokensPerSecond(messages: readonly AgentMessage[], isStreaming: boolean): number | null;
95
95
  limitMatchesActiveAccount(report: UsageReport, limit: UsageLimit, identity: StatusAccountIdentity): boolean;
96
+ classifyResetExpiry?(report: UsageReport, nowMs: number): StatusResetExpiry | undefined;
97
+ /** One-line warning for saved resets anywhere in the pool that expire within 24 hours. */
98
+ resetExpiryNotice?(reports: readonly UsageReport[], nowMs: number): string | undefined;
96
99
  computeCompactionBoundaries(session: TSession, contextWindow: number, model?: Model): CompactionBoundaries | null;
97
100
  }
98
101
 
@@ -184,7 +184,9 @@ function getProjectDirDisplay(projectDir: string): ProjectDirDisplay {
184
184
  }
185
185
  }
186
186
  if (!scratch) {
187
- displayRoots ??= [path.join(homeDir, "Projects"), "/work"].map(normalizePathForComparison);
187
+ displayRoots ??= [path.join(homeDir, "Projects"), path.join(homeDir, "repos"), "/work"].map(
188
+ normalizePathForComparison,
189
+ );
188
190
  for (const root of displayRoots) {
189
191
  const relative = relativePathWithinNormalizedRoot(root, normalizedProjectDir);
190
192
  if (relative) {
@@ -484,6 +486,9 @@ function formatLoopLimit(
484
486
  return `${seconds}s left`;
485
487
  }
486
488
 
489
+ /** Zeta-only: the ultra plan workflow gets its own status-line label (lost in the v18.8.8 merge once already). */
490
+ export const PLAN_ULTRA_LABEL = "Plan-Ultra";
491
+
487
492
  const modeSegment: StatusLineSegment = {
488
493
  id: "mode",
489
494
  render(ctx) {
@@ -491,7 +496,8 @@ const modeSegment: StatusLineSegment = {
491
496
 
492
497
  const plan = ctx.planMode;
493
498
  if (plan && (plan.enabled || plan.paused)) {
494
- const label = plan.paused ? `Plan${pauseSuffix}` : "Plan";
499
+ const title = plan.workflow === "ultra" ? PLAN_ULTRA_LABEL : "Plan";
500
+ const label = plan.paused ? `${title}${pauseSuffix}` : title;
495
501
  const content = withIcon(theme.icon.plan, label);
496
502
  return {
497
503
  content: plan.paused ? theme.fg("warning", content) : accentFg(ctx, "accent", content),
@@ -536,9 +542,10 @@ const modeSegment: StatusLineSegment = {
536
542
  describe(ctx) {
537
543
  const plan = ctx.planMode;
538
544
  if (plan && (plan.enabled || plan.paused)) {
545
+ const title = plan.workflow === "ultra" ? PLAN_ULTRA_LABEL : "Plan";
539
546
  return plan.paused
540
- ? segView([span("Plan (paused)", "warning")], "plan", "warning")
541
- : segView([span("Plan", accentToken(ctx, "accent"))], "plan");
547
+ ? segView([span(`${title} (paused)`, "warning")], "plan", "warning")
548
+ : segView([span(title, accentToken(ctx, "accent"))], "plan");
542
549
  }
543
550
  if (ctx.prewalk?.enabled) return segView([span("Prewalk", accentToken(ctx, "accent"))], "prewalk");
544
551
  const goal = ctx.goalMode;
@@ -677,19 +684,15 @@ const gitSegment: StatusLineSegment = {
677
684
  const showBranch = opts.showBranch !== false;
678
685
  const spans: TspSpan[] = [];
679
686
  if (showBranch && branch) spans.push(span(branch, colorName));
680
- const indicators: TspSpan[] = [];
681
687
  if (status) {
682
- if (opts.showUnstaged !== false && status.unstaged > 0) {
683
- indicators.push(span(`*${status.unstaged}`, "statusLineDirty"));
684
- }
685
- if (opts.showStaged !== false && status.staged > 0) {
686
- indicators.push(span(`+${status.staged}`, "statusLineStaged"));
687
- }
688
- if (opts.showUntracked !== false && status.untracked > 0) {
689
- indicators.push(span(`?${status.untracked}`, "statusLineUntracked"));
690
- }
688
+ // Spans join as one text: each count after the branch or a previous count leads with a space.
689
+ const push = (text: string, token: string): void => {
690
+ spans.push(span(spans.length > 0 ? ` ${text}` : text, token));
691
+ };
692
+ if (opts.showUnstaged !== false && status.unstaged > 0) push(`*${status.unstaged}`, "statusLineDirty");
693
+ if (opts.showStaged !== false && status.staged > 0) push(`+${status.staged}`, "statusLineStaged");
694
+ if (opts.showUntracked !== false && status.untracked > 0) push(`?${status.untracked}`, "statusLineUntracked");
691
695
  }
692
- spans.push(...indicators);
693
696
  if (spans.length === 0) return null;
694
697
  return segView(spans, showBranch && branch ? "branch" : "git", isDirty ? "warning" : undefined);
695
698
  },
@@ -968,16 +971,19 @@ const sessionSegment: StatusLineSegment = {
968
971
  },
969
972
  };
970
973
 
974
+ /** Short (first-label) machine hostname; resolved once — `os.hostname()` is a syscall per call. */
975
+ let shortHostname: string | undefined;
976
+
971
977
  const hostnameSegment: StatusLineSegment = {
972
978
  id: "hostname",
973
979
  render(ctx) {
974
- const name = ctx.hostname ?? os.hostname().split(".")[0];
980
+ const name = ctx.hostname ?? (shortHostname ??= os.hostname().split(".")[0]);
975
981
  const content = withIcon(theme.icon.host, name);
976
982
  const ansi = sessionAccentAnsi(ctx);
977
983
  return { content: ansi ? `${ansi}${content}\x1b[39m` : content, visible: true };
978
984
  },
979
985
  describe(ctx) {
980
- const name = ctx.hostname ?? os.hostname().split(".")[0];
986
+ const name = ctx.hostname ?? (shortHostname ??= os.hostname().split(".")[0]);
981
987
  return segView([span(name, sessionAccentAnsi(ctx) ? "accent" : undefined)], "host");
982
988
  },
983
989
  };
@@ -1081,6 +1087,7 @@ const VIM_MODE_LABELS: Record<NonNullable<SegmentContext["vim"]>["mode"], string
1081
1087
  normal: "NORMAL",
1082
1088
  visual: "VISUAL",
1083
1089
  "visual-line": "V-LINE",
1090
+ replace: "REPLACE",
1084
1091
  };
1085
1092
 
1086
1093
  /**
@@ -1093,6 +1100,7 @@ const VIM_MODE_ICON_KEYS: Record<NonNullable<SegmentContext["vim"]>["mode"], Sym
1093
1100
  normal: "icon.vimNormal",
1094
1101
  visual: "icon.vimVisual",
1095
1102
  "visual-line": "icon.vimVisualLine",
1103
+ replace: "icon.vimReplace",
1096
1104
  };
1097
1105
 
1098
1106
  const VIM_MODE_COLORS: Record<NonNullable<SegmentContext["vim"]>["mode"], ThemeColor> = {
@@ -1100,6 +1108,7 @@ const VIM_MODE_COLORS: Record<NonNullable<SegmentContext["vim"]>["mode"], ThemeC
1100
1108
  normal: "accent",
1101
1109
  visual: "warning",
1102
1110
  "visual-line": "warning",
1111
+ replace: "accent",
1103
1112
  };
1104
1113
 
1105
1114
  const vimSegment: StatusLineSegment = {
@@ -1187,6 +1196,12 @@ function formatUsageReset(value: number, unit: "m" | "h"): string {
1187
1196
  return hours > 0 ? `${days}d ${hours}h` : `${days}d`;
1188
1197
  }
1189
1198
 
1199
+ /** Expiring saved resets outrank the usable/unusable color: red within 24 hours, yellow within 7 days. */
1200
+ function resetCreditsColor(resets: NonNullable<NonNullable<SegmentContext["usage"]>["resetCredits"]>): ThemeColor {
1201
+ if (resets.expiring) return resets.expiring.tier === "imminent" ? "error" : "warning";
1202
+ return resets.redeemableCount > 0 ? "success" : "warning";
1203
+ }
1204
+
1190
1205
  const usageSegment: StatusLineSegment = {
1191
1206
  id: "usage",
1192
1207
  render(ctx) {
@@ -1221,7 +1236,8 @@ const usageSegment: StatusLineSegment = {
1221
1236
  resetText += ` (${resets.redeemableCount} usable)`;
1222
1237
  }
1223
1238
  if (resets.expiryHours !== undefined) {
1224
- resetText += ` exp ${formatUsageReset(resets.expiryHours, "h")}`;
1239
+ const expiring = resets.expiring ? `▲ ${resets.expiring.count} ` : "";
1240
+ resetText += ` ${expiring}exp ${formatUsageReset(resets.expiryHours, "h")}`;
1225
1241
  } else if (resets.expired) {
1226
1242
  resetText += " expired";
1227
1243
  }
@@ -1229,7 +1245,7 @@ const usageSegment: StatusLineSegment = {
1229
1245
  const reason = truncateToWidth(sanitizeStatusText(resets.unavailableReason), TRUNCATE_LENGTHS.SHORT);
1230
1246
  if (reason) resetText += ` ${reason}`;
1231
1247
  }
1232
- parts.push(theme.fg(resets.redeemableCount > 0 ? "success" : "warning", resetText));
1248
+ parts.push(theme.fg(resetCreditsColor(resets), resetText));
1233
1249
  }
1234
1250
  const content = withIcon(theme.icon.time, parts.join(theme.sep.dot));
1235
1251
  return { content, visible: true };
@@ -1254,13 +1270,15 @@ const usageSegment: StatusLineSegment = {
1254
1270
  const resets = u.resetCredits;
1255
1271
  let resetText = `✦ ${resets.bankedCount}`;
1256
1272
  if (resets.redeemableCount !== resets.bankedCount) resetText += ` (${resets.redeemableCount} usable)`;
1257
- if (resets.expiryHours !== undefined) resetText += ` exp ${formatUsageReset(resets.expiryHours, "h")}`;
1258
- else if (resets.expired) resetText += " expired";
1273
+ if (resets.expiryHours !== undefined) {
1274
+ const expiring = resets.expiring ? `▲ ${resets.expiring.count} ` : "";
1275
+ resetText += ` ${expiring}exp ${formatUsageReset(resets.expiryHours, "h")}`;
1276
+ } else if (resets.expired) resetText += " expired";
1259
1277
  if (resets.redeemableCount === 0 && resets.unavailableReason) {
1260
1278
  const reason = sanitizeStatusText(resets.unavailableReason);
1261
1279
  if (reason) resetText += ` ${reason}`;
1262
1280
  }
1263
- parts.push([span(resetText, resets.redeemableCount > 0 ? "success" : "warning")]);
1281
+ parts.push([span(resetText, resetCreditsColor(resets))]);
1264
1282
  }
1265
1283
  const spans: TspSpan[] = [];
1266
1284
  for (const part of parts) {
@@ -95,6 +95,8 @@ export interface SegmentContext {
95
95
  planMode: {
96
96
  enabled: boolean;
97
97
  paused: boolean;
98
+ /** Plan workflow variant; `ultra` renders as `Plan-Ultra` in the mode segment. */
99
+ workflow?: "parallel" | "iterative" | "ultra";
98
100
  } | null;
99
101
  prewalk: {
100
102
  enabled: boolean;
@@ -114,7 +116,7 @@ export interface SegmentContext {
114
116
  } | null;
115
117
  /** Modal editing state, or null when `tui.vimMode` is off. */
116
118
  vim: {
117
- mode: "insert" | "normal" | "visual" | "visual-line";
119
+ mode: "insert" | "normal" | "visual" | "visual-line" | "replace";
118
120
  /** Half-typed operator/count (`"2d"`), empty when nothing is pending. */
119
121
  pending: string;
120
122
  /** Lines spanned by the active Visual selection; 0 outside Visual modes. */
@@ -202,10 +204,20 @@ export interface SegmentContext {
202
204
  expiryHours?: number;
203
205
  expired?: boolean;
204
206
  unavailableReason?: string;
207
+ expiring?: StatusResetExpiry;
205
208
  };
206
209
  } | null;
207
210
  }
208
211
 
212
+ /** How close an account's saved resets are to expiring, when it is worth a warning. */
213
+ export interface StatusResetExpiry {
214
+ /** `soon`: within 7 days; `imminent`: within 24 hours. */
215
+ tier: "soon" | "imminent";
216
+ count: number;
217
+ /** Expiry of the reset the warning is about (epoch ms); it can be later than the soonest banked one. */
218
+ expiresAtMs: number;
219
+ }
220
+
209
221
  export interface RenderedSegment {
210
222
  content: string; // The segment text (may include ANSI color codes)
211
223
  visible: boolean; // Whether to render (e.g., git hidden when not in repo)
@@ -227,8 +239,8 @@ export interface SegmentView {
227
239
 
228
240
  /**
229
241
  * The status line's facts for the native composer. A TSP terminal shows no
230
- * status strip: the tab title carries the session, the pane header the path
231
- * and branch, and the composer the rest.
242
+ * status strip: the tab title carries the session, the pane header the path,
243
+ * and the composer the rest (the git branch among its facts).
232
244
  */
233
245
  export interface ComposerFacts {
234
246
  /**
@@ -1,6 +1,6 @@
1
1
  import type { HangulCompatibilityJamoWidth } from "./utils";
2
2
  export * from "./terminal-multiplexer";
3
- export { isInsideTmux, wrapTmuxPassthrough } from "./tmux";
3
+ export { wrapTmuxPassthrough } from "./tmux";
4
4
  export declare enum ImageProtocol {
5
5
  Kitty = "\u001B_G",
6
6
  Iterm2 = "\u001B]1337;File=",
@@ -55,12 +55,6 @@ export declare class TerminalInfo {
55
55
  formatNotification(message: string | TerminalNotification): string;
56
56
  sendNotification(message: string | TerminalNotification): void;
57
57
  }
58
- /**
59
- * Whether the agent process is running inside a Zellij session. Read fresh on
60
- * each call (like {@link isInsideTmux}) so a session attached/detached mid-run
61
- * is observed and tests can toggle `Bun.env.ZELLIJ` per case.
62
- */
63
- export declare function isInsideZellij(env?: NodeJS.ProcessEnv): boolean;
64
58
  /**
65
59
  * Whether the agent process runs in an SSH session, so the terminal emulator
66
60
  * is remote and host-local input/keyboard modes cannot be assumed.
@@ -96,12 +90,12 @@ export declare function synchronizedOutputUserOverride(env?: NodeJS.ProcessEnv):
96
90
  * 2. Positive `TERM_FEATURES` advertisement (`Sy`) — survives SSH/mux wrapping.
97
91
  * 3. Windows Terminal (1.24+) via `WT_SESSION`, on native win32 and the
98
92
  * WSL/SSH-fronted host alike.
99
- * 4. Herdr panes. Herdr is otherwise treated as a multiplexer so leaked
100
- * kitty/ghostty identities cannot enable placeholder graphics, but its
101
- * pane VTE is libghostty and already suppresses compositing while DEC 2026
102
- * is set. Leaving sync off lets CUP-diff paints and split write(2) chunks
103
- * composite as dirty-row patches — the live viewport tears, with the top
104
- * frozen while only the bottom refreshes.
93
+ * 4. A multiplexer session whose pane VTE honors DEC 2026 regardless of its
94
+ * DECRQM reply (Herdr's libghostty pane). Such a multiplexer still owns
95
+ * the grid, so leaked kitty/ghostty identities cannot enable placeholder
96
+ * graphics, but leaving sync off lets CUP-diff paints and split write(2)
97
+ * chunks composite as dirty-row patches — the live viewport tears, with
98
+ * the top frozen while only the bottom refreshes.
105
99
  * 5. Known direct terminals with confirmed support. SSH does *not* disable —
106
100
  * DEC 2026 passes through SSH when the outer terminal honors it.
107
101
  * 6. Everything else starts off, including risky multiplexers; the runtime
@@ -167,31 +161,29 @@ export declare function hyperlinksUserOverride(env?: NodeJS.ProcessEnv): boolean
167
161
  * Policy (highest precedence first):
168
162
  * 1. Explicit user override (`PI_NO_HYPERLINKS=1` off, `PI_FORCE_HYPERLINKS=1`
169
163
  * on). Opt-out wins ties.
170
- * 2. Herdr pane with no nested screen/tmux: on. Herdr hides the outer
171
- * terminal (`TERM=xterm-256color`, no `TERM_PROGRAM`), but it renders
172
- * OSC 8 in its own grid and opens links itself on Ctrl+click, so the
173
- * outer terminal's support does not matter.
164
+ * 2. Every multiplexer session with a hyperlink policy renders OSC 8 itself
165
+ * (`render`, e.g. Herdr): on. Herdr hides the outer terminal
166
+ * (`TERM=xterm-256color`, no `TERM_PROGRAM`), so the outer terminal's
167
+ * support does not matter.
174
168
  * 2b. Zeta workbench pane with no nested screen/tmux: on, for the same
175
169
  * reason — the workbench's terminal simulator renders OSC 8 itself and
176
170
  * opens links on Ctrl+click (`ZETA_WORKBENCH=1` is injected into every
177
171
  * pane PTY; the outer terminal is invisible from inside).
178
172
  * 3. Static terminal capability — terminals whose {@link TerminalInfo} marks
179
173
  * `hyperlinks: false` (e.g. `base`) stay off unless the user forced on.
180
- * 4. GNU screen's explicit session marker (`STY`) always off, even if tmux is
181
- * also present: a screen layer anywhere in the path cannot forward OSC 8.
182
- * 5. tmux session (`TMUX` set): enabled when tmux self-reports >= 3.4 via
183
- * `TERM_PROGRAM_VERSION` (tmux 3.4 stores OSC 8 as a cell attribute and
184
- * forwards it to outer terminals whose `terminal-features` include
185
- * `hyperlinks`). Older or unknown versions stay off; on outer terminals
186
- * without the feature configured, tmux silently drops the sequence —
187
- * identical to today. Checked before the screen-family TERM heuristic
188
- * because tmux's historical `default-terminal` is `screen-256color`, so
189
- * `TERM=screen*` inside a tmux session must NOT short-circuit to off.
190
- * 6. screen-family TERM without `TMUX` always off: screen never gained OSC 8
191
- * support.
192
- * 7. tmux-family TERM without `TMUX` env — unusual (e.g. inspection scripts);
193
- * no version available, so off.
194
- * 8. Otherwise honor the static terminal capability.
174
+ * 4. A session that never forwards OSC 8 (`drop`, e.g. GNU screen's `STY`)
175
+ * always off, even when a forwarding multiplexer is also present.
176
+ * 5. Forwarding sessions (`forward`, e.g. `TMUX`): enabled when every one
177
+ * self-reports at least its forwarding version via `TERM_PROGRAM` /
178
+ * `TERM_PROGRAM_VERSION` (tmux 3.4). Older or unknown versions stay off;
179
+ * on outer terminals without the feature configured, tmux silently drops
180
+ * the sequence. Checked before the TERM heuristic because tmux's
181
+ * historical `default-terminal` is `screen-256color`, so `TERM=screen*`
182
+ * inside a tmux session must NOT short-circuit to off.
183
+ * 6. TERM naming a multiplexer whose session markers were stripped: off,
184
+ * since no session proves the multiplexer forwards OSC 8 (screen never
185
+ * does; tmux has no version to check).
186
+ * 7. Otherwise honor the static terminal capability.
195
187
  */
196
188
  export declare function shouldEnableHyperlinksByDefault(env?: NodeJS.ProcessEnv, terminalId?: TerminalId): boolean;
197
189
  /**
@@ -343,7 +335,7 @@ export interface ParsedKittyPlacementLine {
343
335
  /**
344
336
  * Parse a frame line that consists solely of a Kitty direct placement (the
345
337
  * last line of an {@link Image} block). Returns null for anything else —
346
- * placeholder grids, tmux-wrapped placements, sixel/iTerm2 payloads — so
338
+ * placeholder grids, sixel/iTerm2 payloads — so
347
339
  * callers fall back to writing the line verbatim.
348
340
  */
349
341
  export declare function parseKittyDirectPlacementLine(line: string): ParsedKittyPlacementLine | null;
@@ -383,8 +375,8 @@ export declare function encodeKittyDeleteAllImages(): string;
383
375
  /**
384
376
  * Delete a single placement of an image (`d=i`, lowercase): removes its cells
385
377
  * and registry entry but keeps the transmitted data, so a later `a=p` under a
386
- * fresh placement id needs no retransmit. Used to clear stale placement-epoch
387
- * entries after a destructive history clear.
378
+ * fresh placement id needs no retransmit. The frame writer uses this before
379
+ * replacing a live image without deleting its archived copies.
388
380
  */
389
381
  export declare function encodeKittyDeletePlacement(imageId: number, placementId: number): string;
390
382
  export declare function encodeITerm2(base64Data: string, options?: {