@oh-my-pi/pi-tui 18.4.2 → 18.4.4

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 (463) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/types/apps/cleanse-board.d.ts +17 -0
  3. package/dist/types/apps/git/help.d.ts +16 -0
  4. package/dist/types/apps/git/sidebar.d.ts +18 -0
  5. package/dist/types/apps/live-visualizer.d.ts +10 -0
  6. package/dist/types/apps/ps-top.d.ts +15 -0
  7. package/dist/types/apps/standalone-picker.d.ts +3 -0
  8. package/dist/types/autocomplete.d.ts +8 -0
  9. package/dist/types/chat/advisor-message.d.ts +12 -2
  10. package/dist/types/chat/assistant-message.d.ts +20 -0
  11. package/dist/types/chat/bash-execution.d.ts +9 -0
  12. package/dist/types/chat/chat-transcript-builder.d.ts +6 -1
  13. package/dist/types/chat/collab-prompt-message.d.ts +4 -0
  14. package/dist/types/chat/compaction-summary-message.d.ts +15 -0
  15. package/dist/types/chat/eval-execution.d.ts +8 -0
  16. package/dist/types/chat/execution-shared.d.ts +58 -0
  17. package/dist/types/chat/late-diagnostics-message.d.ts +15 -1
  18. package/dist/types/chat/read-tool-group.d.ts +15 -0
  19. package/dist/types/chat/skill-message.d.ts +9 -0
  20. package/dist/types/chat/stripped-tool-calls-placeholder.d.ts +3 -0
  21. package/dist/types/chat/thinking-display.d.ts +2 -0
  22. package/dist/types/chat/todo-reminder.d.ts +4 -1
  23. package/dist/types/chat/tool-execution.d.ts +25 -1
  24. package/dist/types/chat/transcript-actions.d.ts +37 -0
  25. package/dist/types/chat/transcript-entry.d.ts +3 -1
  26. package/dist/types/chat/user-message.d.ts +25 -0
  27. package/dist/types/chrome/collab-qrcode.d.ts +7 -0
  28. package/dist/types/chrome/context-thresholds.d.ts +11 -0
  29. package/dist/types/chrome/countdown-timer.d.ts +9 -3
  30. package/dist/types/chrome/diff.d.ts +12 -0
  31. package/dist/types/chrome/dynamic-border.d.ts +3 -0
  32. package/dist/types/chrome/format.d.ts +6 -0
  33. package/dist/types/chrome/message-divider.d.ts +13 -0
  34. package/dist/types/chrome/message-frame.d.ts +10 -0
  35. package/dist/types/chrome/message-notice.d.ts +23 -0
  36. package/dist/types/chrome/overlay-box.d.ts +11 -2
  37. package/dist/types/chrome/qrcode.d.ts +7 -0
  38. package/dist/types/chrome/segment-track.d.ts +7 -0
  39. package/dist/types/chrome/selector-helpers.d.ts +0 -6
  40. package/dist/types/chrome/status-notice.d.ts +14 -0
  41. package/dist/types/chrome/streaming-panel.d.ts +3 -0
  42. package/dist/types/chrome/tool-activity.d.ts +3 -0
  43. package/dist/types/chrome/transcript-container.d.ts +13 -0
  44. package/dist/types/chrome/transcript-status.d.ts +15 -3
  45. package/dist/types/components/box.d.ts +7 -0
  46. package/dist/types/components/disclosure.d.ts +9 -0
  47. package/dist/types/components/editor.d.ts +42 -0
  48. package/dist/types/components/form.d.ts +14 -0
  49. package/dist/types/components/image.d.ts +7 -0
  50. package/dist/types/components/input.d.ts +20 -1
  51. package/dist/types/components/key-value-list.d.ts +3 -0
  52. package/dist/types/components/layout/geometry.d.ts +16 -0
  53. package/dist/types/components/layout/row.d.ts +7 -0
  54. package/dist/types/components/layout/split-pane.d.ts +8 -0
  55. package/dist/types/components/layout/stack.d.ts +6 -0
  56. package/dist/types/components/loader.d.ts +48 -0
  57. package/dist/types/components/markdown.d.ts +8 -0
  58. package/dist/types/components/metric.d.ts +7 -0
  59. package/dist/types/components/progress-bar.d.ts +3 -0
  60. package/dist/types/components/scroll-view.d.ts +6 -0
  61. package/dist/types/components/section.d.ts +3 -0
  62. package/dist/types/components/select-list.d.ts +33 -0
  63. package/dist/types/components/settings-list.d.ts +68 -0
  64. package/dist/types/components/spacer.d.ts +4 -0
  65. package/dist/types/components/tab-bar.d.ts +9 -0
  66. package/dist/types/components/table.d.ts +7 -0
  67. package/dist/types/components/text.d.ts +6 -0
  68. package/dist/types/components/tree-view.d.ts +9 -0
  69. package/dist/types/components/truncated-text.d.ts +3 -0
  70. package/dist/types/components/wizard-step.d.ts +6 -0
  71. package/dist/types/hotkeys-markdown.d.ts +24 -0
  72. package/dist/types/index.d.ts +5 -0
  73. package/dist/types/latex-block.d.ts +7 -0
  74. package/dist/types/loop-watchdog.d.ts +9 -0
  75. package/dist/types/native/apply.d.ts +39 -0
  76. package/dist/types/native/backend.d.ts +94 -0
  77. package/dist/types/native/blobs.d.ts +29 -0
  78. package/dist/types/native/describe.d.ts +56 -0
  79. package/dist/types/native/encode.d.ts +50 -0
  80. package/dist/types/native/icons.d.ts +18 -0
  81. package/dist/types/native/memo.d.ts +27 -0
  82. package/dist/types/native/node.d.ts +107 -0
  83. package/dist/types/native/overlay.d.ts +64 -0
  84. package/dist/types/native/picker.d.ts +124 -0
  85. package/dist/types/native/reconcile.d.ts +41 -0
  86. package/dist/types/native/settle.d.ts +11 -0
  87. package/dist/types/native/spans.d.ts +21 -0
  88. package/dist/types/native/state.d.ts +6 -0
  89. package/dist/types/native/tone.d.ts +24 -0
  90. package/dist/types/overlays/advisor-config.d.ts +20 -0
  91. package/dist/types/overlays/agent-hub-renderer.d.ts +27 -11
  92. package/dist/types/overlays/agent-hub.d.ts +10 -0
  93. package/dist/types/overlays/agent-transcript-viewer.d.ts +7 -0
  94. package/dist/types/overlays/agents-hub.d.ts +8 -0
  95. package/dist/types/overlays/annotation-overlay.d.ts +3 -0
  96. package/dist/types/overlays/ask-dialog.d.ts +23 -0
  97. package/dist/types/overlays/bordered-loader.d.ts +3 -0
  98. package/dist/types/overlays/btw-history-panel.d.ts +9 -0
  99. package/dist/types/overlays/btw-panel.d.ts +3 -0
  100. package/dist/types/overlays/cleanse-panel.d.ts +5 -2
  101. package/dist/types/overlays/composer-shape-preview.d.ts +7 -1
  102. package/dist/types/overlays/copy-selector.d.ts +38 -0
  103. package/dist/types/overlays/error-banner.d.ts +9 -0
  104. package/dist/types/overlays/extensions/extension-list.d.ts +1 -0
  105. package/dist/types/overlays/history-search.d.ts +18 -0
  106. package/dist/types/overlays/hook-editor.d.ts +28 -1
  107. package/dist/types/overlays/hook-input.d.ts +3 -0
  108. package/dist/types/overlays/hook-selector.d.ts +10 -0
  109. package/dist/types/overlays/hub-frame.d.ts +18 -0
  110. package/dist/types/overlays/jobs-panel.d.ts +24 -0
  111. package/dist/types/overlays/login-dialog.d.ts +10 -0
  112. package/dist/types/overlays/logout-account-selector.d.ts +4 -0
  113. package/dist/types/overlays/mcp-add-wizard.d.ts +4 -0
  114. package/dist/types/overlays/model-browser.d.ts +69 -0
  115. package/dist/types/overlays/model-hub.d.ts +7 -0
  116. package/dist/types/overlays/model-picker.d.ts +9 -1
  117. package/dist/types/overlays/move-overlay.d.ts +3 -0
  118. package/dist/types/overlays/oauth-selector.d.ts +4 -0
  119. package/dist/types/overlays/omfg-panel.d.ts +3 -0
  120. package/dist/types/overlays/pause-screen.d.ts +12 -0
  121. package/dist/types/overlays/plan-review-overlay.d.ts +5 -0
  122. package/dist/types/overlays/plan-save-overlay.d.ts +10 -0
  123. package/dist/types/overlays/plugin-selector.d.ts +4 -0
  124. package/dist/types/overlays/plugin-settings.d.ts +30 -0
  125. package/dist/types/overlays/queue-mode-selector.d.ts +4 -0
  126. package/dist/types/overlays/reset-usage-selector.d.ts +8 -0
  127. package/dist/types/overlays/rewind-selector.d.ts +5 -0
  128. package/dist/types/overlays/session-info-overlay.d.ts +19 -1
  129. package/dist/types/overlays/session-selector.d.ts +64 -1
  130. package/dist/types/overlays/settings-defs.d.ts +14 -0
  131. package/dist/types/overlays/settings-selector.d.ts +21 -0
  132. package/dist/types/overlays/show-images-selector.d.ts +4 -0
  133. package/dist/types/overlays/snapcompact-shape-preview.d.ts +2 -0
  134. package/dist/types/overlays/stats-notice.d.ts +8 -0
  135. package/dist/types/overlays/theme-selector.d.ts +11 -0
  136. package/dist/types/overlays/thinking-selector.d.ts +4 -0
  137. package/dist/types/overlays/tree-selector.d.ts +60 -2
  138. package/dist/types/overlays/usage-dashboard.d.ts +26 -3
  139. package/dist/types/overlays/usage-row.d.ts +36 -2
  140. package/dist/types/prompt/attachment-chips.d.ts +8 -0
  141. package/dist/types/prompt/composer-attachments.d.ts +15 -3
  142. package/dist/types/prompt/composer.d.ts +18 -1
  143. package/dist/types/prompt/custom-editor.d.ts +48 -2
  144. package/dist/types/prompt/editor-top-gap.d.ts +2 -0
  145. package/dist/types/prompt/macos-spelling.d.ts +6 -0
  146. package/dist/types/prompt/magic-keywords.d.ts +9 -0
  147. package/dist/types/prompt/queued-messages.d.ts +23 -0
  148. package/dist/types/prompt/skill-tokens.d.ts +4 -2
  149. package/dist/types/prompt/welcome.d.ts +16 -0
  150. package/dist/types/render/code-cell.d.ts +10 -0
  151. package/dist/types/render/file-list.d.ts +8 -0
  152. package/dist/types/render/hyperlink.d.ts +14 -0
  153. package/dist/types/render/output-block.d.ts +43 -0
  154. package/dist/types/render/output-pane.d.ts +17 -0
  155. package/dist/types/render/tool-card.d.ts +8 -0
  156. package/dist/types/render/tree-list.d.ts +8 -0
  157. package/dist/types/render/width-aware-text.d.ts +7 -0
  158. package/dist/types/setup/scenes/outro.d.ts +7 -0
  159. package/dist/types/setup/scenes/sign-in.d.ts +16 -9
  160. package/dist/types/setup/scenes/splash.d.ts +8 -0
  161. package/dist/types/setup/scenes/types.d.ts +6 -27
  162. package/dist/types/setup/wizard-overlay.d.ts +9 -0
  163. package/dist/types/status-line/component.d.ts +49 -5
  164. package/dist/types/status-line/context-usage.d.ts +20 -0
  165. package/dist/types/status-line/footer.d.ts +8 -0
  166. package/dist/types/status-line/metrics.d.ts +1 -2
  167. package/dist/types/status-line/segments.d.ts +10 -1
  168. package/dist/types/status-line/types.d.ts +40 -1
  169. package/dist/types/stdin-buffer.d.ts +10 -7
  170. package/dist/types/terminal-capabilities.d.ts +1 -1
  171. package/dist/types/terminal.d.ts +36 -0
  172. package/dist/types/theme/defaults/index.d.ts +100 -0
  173. package/dist/types/theme/schema.d.ts +2 -0
  174. package/dist/types/theme/shimmer.d.ts +8 -0
  175. package/dist/types/theme/theme-class.d.ts +2 -0
  176. package/dist/types/theme/theme.d.ts +33 -1
  177. package/dist/types/tools/ask.d.ts +3 -0
  178. package/dist/types/tools/ast-edit.d.ts +10 -1
  179. package/dist/types/tools/ast-grep.d.ts +10 -1
  180. package/dist/types/tools/autoresearch.d.ts +21 -4
  181. package/dist/types/tools/bash.d.ts +30 -1
  182. package/dist/types/tools/cfg-render.d.ts +5 -1
  183. package/dist/types/tools/debug.d.ts +3 -1
  184. package/dist/types/tools/default-renderer.d.ts +6 -1
  185. package/dist/types/tools/edit.d.ts +14 -1
  186. package/dist/types/tools/eval.d.ts +12 -1
  187. package/dist/types/tools/fetch.d.ts +16 -1
  188. package/dist/types/tools/find.d.ts +15 -1
  189. package/dist/types/tools/github.d.ts +3 -0
  190. package/dist/types/tools/glob.d.ts +14 -1
  191. package/dist/types/tools/goal.d.ts +3 -1
  192. package/dist/types/tools/grep.d.ts +14 -1
  193. package/dist/types/tools/grouped-file-output.d.ts +58 -0
  194. package/dist/types/tools/json-tree.d.ts +20 -0
  195. package/dist/types/tools/lsp.d.ts +3 -10
  196. package/dist/types/tools/mcp.d.ts +16 -1
  197. package/dist/types/tools/memory.d.ts +26 -0
  198. package/dist/types/tools/native-view.d.ts +90 -0
  199. package/dist/types/tools/proc-render.d.ts +7 -1
  200. package/dist/types/tools/read.d.ts +23 -1
  201. package/dist/types/tools/renderer.d.ts +57 -0
  202. package/dist/types/tools/report-tool-issue.d.ts +3 -0
  203. package/dist/types/tools/resolve.d.ts +14 -1
  204. package/dist/types/tools/task.d.ts +3 -0
  205. package/dist/types/tools/think.d.ts +3 -0
  206. package/dist/types/tools/todo.d.ts +12 -0
  207. package/dist/types/tools/vibe.d.ts +3 -1
  208. package/dist/types/tools/wait.d.ts +3 -0
  209. package/dist/types/tools/web-search-types.d.ts +90 -0
  210. package/dist/types/tools/web-search.d.ts +9 -168
  211. package/dist/types/tools/write.d.ts +14 -1
  212. package/dist/types/tools/xdev.d.ts +13 -0
  213. package/dist/types/tui.d.ts +49 -0
  214. package/package.json +9 -9
  215. package/src/apps/autoresearch-dashboard.ts +362 -4
  216. package/src/apps/cleanse-board.ts +219 -1
  217. package/src/apps/cleanse-picker.ts +9 -1
  218. package/src/apps/debug/log-viewer.ts +15 -15
  219. package/src/apps/debug/protocol-probe.ts +2 -20
  220. package/src/apps/git/avatar.ts +2 -22
  221. package/src/apps/git/git-tui.ts +406 -59
  222. package/src/apps/git/help.ts +130 -0
  223. package/src/apps/git/sidebar.ts +491 -0
  224. package/src/apps/live-visualizer.ts +65 -0
  225. package/src/apps/ps-top.ts +448 -17
  226. package/src/apps/session-picker.ts +1 -0
  227. package/src/apps/setup-model-picker.ts +5 -1
  228. package/src/apps/standalone-picker.ts +55 -1
  229. package/src/autocomplete.ts +44 -1
  230. package/src/chat/advisor-message.ts +72 -3
  231. package/src/chat/assistant-message.ts +538 -51
  232. package/src/chat/background-tan-message.ts +4 -4
  233. package/src/chat/bash-execution.ts +81 -0
  234. package/src/chat/cache-invalidation-marker.ts +8 -0
  235. package/src/chat/chat-transcript-builder.ts +37 -6
  236. package/src/chat/collab-prompt-message.ts +15 -3
  237. package/src/chat/compaction-summary-message.ts +74 -1
  238. package/src/chat/custom-message.ts +3 -1
  239. package/src/chat/eval-execution.ts +57 -0
  240. package/src/chat/execution-shared.ts +153 -1
  241. package/src/chat/hook-message.ts +1 -0
  242. package/src/chat/late-diagnostics-message.ts +85 -2
  243. package/src/chat/read-tool-group.ts +341 -1
  244. package/src/chat/served-model-marker.ts +8 -0
  245. package/src/chat/skill-message.ts +63 -0
  246. package/src/chat/stripped-tool-calls-placeholder.ts +18 -10
  247. package/src/chat/thinking-display.ts +73 -11
  248. package/src/chat/todo-reminder.ts +34 -4
  249. package/src/chat/tool-execution.ts +385 -10
  250. package/src/chat/transcript-actions.ts +38 -0
  251. package/src/chat/transcript-browser.ts +2 -9
  252. package/src/chat/transcript-entry.ts +10 -1
  253. package/src/chat/transcript-render-helpers.ts +16 -15
  254. package/src/chat/ttsr-notification.ts +38 -1
  255. package/src/chat/user-message.ts +167 -4
  256. package/src/chrome/collab-qrcode.ts +27 -2
  257. package/src/chrome/context-thresholds.ts +34 -0
  258. package/src/chrome/countdown-timer.ts +24 -1
  259. package/src/chrome/diff.ts +60 -1
  260. package/src/chrome/dynamic-border.ts +7 -0
  261. package/src/chrome/format.ts +12 -0
  262. package/src/chrome/message-divider.ts +33 -1
  263. package/src/chrome/message-frame.ts +53 -10
  264. package/src/chrome/message-notice.ts +71 -0
  265. package/src/chrome/overlay-box.ts +45 -2
  266. package/src/chrome/qrcode.ts +28 -0
  267. package/src/chrome/segment-track.ts +26 -0
  268. package/src/chrome/selector-helpers.ts +1 -17
  269. package/src/chrome/status-notice.ts +46 -0
  270. package/src/chrome/streaming-panel.ts +25 -1
  271. package/src/chrome/tool-activity.ts +20 -0
  272. package/src/chrome/transcript-container.ts +139 -17
  273. package/src/chrome/transcript-status.ts +40 -11
  274. package/src/components/box.ts +51 -0
  275. package/src/components/disclosure.ts +33 -0
  276. package/src/components/editor.ts +239 -36
  277. package/src/components/form.ts +93 -9
  278. package/src/components/image.ts +30 -0
  279. package/src/components/input.ts +77 -26
  280. package/src/components/key-value-list.ts +18 -0
  281. package/src/components/layout/geometry.ts +44 -0
  282. package/src/components/layout/row.ts +30 -0
  283. package/src/components/layout/split-pane.ts +65 -0
  284. package/src/components/layout/stack.ts +27 -0
  285. package/src/components/loader.ts +183 -1
  286. package/src/components/markdown.ts +131 -56
  287. package/src/components/metric.ts +39 -0
  288. package/src/components/progress-bar.ts +28 -0
  289. package/src/components/scroll-view.ts +23 -0
  290. package/src/components/section.ts +16 -0
  291. package/src/components/select-list.ts +174 -25
  292. package/src/components/settings-list.ts +264 -7
  293. package/src/components/spacer.ts +17 -0
  294. package/src/components/tab-bar.ts +42 -0
  295. package/src/components/table.ts +34 -0
  296. package/src/components/text.ts +23 -0
  297. package/src/components/tree-view.ts +65 -0
  298. package/src/components/truncated-text.ts +14 -0
  299. package/src/components/wizard-step.ts +18 -9
  300. package/src/debug-server.ts +14 -7
  301. package/src/hotkeys-markdown.ts +251 -69
  302. package/src/index.ts +6 -0
  303. package/src/latex-block.ts +11 -0
  304. package/src/loop-watchdog.ts +38 -10
  305. package/src/native/apply.ts +275 -0
  306. package/src/native/backend.ts +682 -0
  307. package/src/native/blobs.ts +70 -0
  308. package/src/native/describe.ts +124 -0
  309. package/src/native/encode.ts +233 -0
  310. package/src/native/icons.ts +184 -0
  311. package/src/native/memo.ts +64 -0
  312. package/src/native/node.ts +112 -0
  313. package/src/native/overlay.ts +131 -0
  314. package/src/native/picker.ts +333 -0
  315. package/src/native/reconcile.ts +1063 -0
  316. package/src/native/settle.ts +23 -0
  317. package/src/native/spans.ts +308 -0
  318. package/src/native/state.ts +28 -0
  319. package/src/native/tone.ts +79 -0
  320. package/src/overlays/advisor-config.ts +420 -0
  321. package/src/overlays/agent-hub-renderer.ts +155 -18
  322. package/src/overlays/agent-hub.ts +1037 -44
  323. package/src/overlays/agent-transcript-viewer.ts +129 -0
  324. package/src/overlays/agents-hub.ts +688 -53
  325. package/src/overlays/annotation-overlay.ts +391 -52
  326. package/src/overlays/ask-dialog.ts +435 -24
  327. package/src/overlays/bordered-loader.ts +17 -0
  328. package/src/overlays/btw-history-panel.ts +182 -0
  329. package/src/overlays/btw-panel.ts +68 -2
  330. package/src/overlays/cleanse-panel.ts +105 -15
  331. package/src/overlays/codex-reset-fireworks.ts +65 -5
  332. package/src/overlays/composer-shape-preview.ts +26 -1
  333. package/src/overlays/copy-selector.ts +545 -23
  334. package/src/overlays/error-banner.ts +44 -0
  335. package/src/overlays/extensions/extension-list.ts +23 -17
  336. package/src/overlays/history-search.ts +175 -33
  337. package/src/overlays/hook-editor.ts +113 -6
  338. package/src/overlays/hook-input.ts +22 -1
  339. package/src/overlays/hook-selector.ts +311 -22
  340. package/src/overlays/hub-frame.ts +80 -0
  341. package/src/overlays/jobs-panel.ts +112 -0
  342. package/src/overlays/login-dialog.ts +183 -1
  343. package/src/overlays/logout-account-selector.ts +102 -4
  344. package/src/overlays/mcp-add-wizard.ts +232 -53
  345. package/src/overlays/model-browser.ts +681 -22
  346. package/src/overlays/model-hub.ts +1402 -78
  347. package/src/overlays/model-picker.ts +184 -7
  348. package/src/overlays/move-overlay.ts +45 -0
  349. package/src/overlays/oauth-selector.ts +227 -23
  350. package/src/overlays/omfg-panel.ts +86 -2
  351. package/src/overlays/pause-screen.ts +55 -4
  352. package/src/overlays/plan-review-overlay.ts +352 -0
  353. package/src/overlays/plan-save-overlay.ts +45 -0
  354. package/src/overlays/plugin-selector.ts +21 -1
  355. package/src/overlays/plugin-settings.ts +195 -5
  356. package/src/overlays/queue-mode-selector.ts +19 -1
  357. package/src/overlays/reset-usage-selector.ts +110 -40
  358. package/src/overlays/rewind-selector.ts +458 -44
  359. package/src/overlays/session-account-selector.ts +1 -1
  360. package/src/overlays/session-info-overlay.ts +137 -1
  361. package/src/overlays/session-selector.ts +807 -46
  362. package/src/overlays/settings-defs.ts +41 -0
  363. package/src/overlays/settings-selector.ts +585 -33
  364. package/src/overlays/show-images-selector.ts +18 -1
  365. package/src/overlays/snapcompact-shape-preview.ts +48 -3
  366. package/src/overlays/stats-notice.ts +31 -0
  367. package/src/overlays/theme-selector.ts +31 -1
  368. package/src/overlays/thinking-selector.ts +22 -1
  369. package/src/overlays/tree-selector.ts +570 -110
  370. package/src/overlays/usage-dashboard.ts +587 -12
  371. package/src/overlays/usage-row.ts +161 -25
  372. package/src/prompt/attachment-chips.ts +60 -0
  373. package/src/prompt/composer-attachments.ts +31 -9
  374. package/src/prompt/composer.ts +55 -2
  375. package/src/prompt/custom-editor.ts +302 -4
  376. package/src/prompt/editor-top-gap.ts +8 -0
  377. package/src/prompt/macos-spelling.ts +24 -9
  378. package/src/prompt/magic-keywords.ts +22 -1
  379. package/src/prompt/model-mention-autocomplete.ts +1 -0
  380. package/src/prompt/queued-messages.ts +101 -0
  381. package/src/prompt/skill-tokens.ts +5 -3
  382. package/src/prompt/welcome.ts +213 -6
  383. package/src/render/code-cell.ts +103 -2
  384. package/src/render/file-list.ts +29 -0
  385. package/src/render/hyperlink.ts +32 -0
  386. package/src/render/output-block.ts +110 -0
  387. package/src/render/output-pane.ts +37 -0
  388. package/src/render/tool-card.ts +137 -0
  389. package/src/render/tree-list.ts +39 -0
  390. package/src/render/width-aware-text.ts +20 -0
  391. package/src/setup/scenes/composer.ts +29 -0
  392. package/src/setup/scenes/glyph.ts +15 -0
  393. package/src/setup/scenes/model.ts +36 -8
  394. package/src/setup/scenes/outro.ts +28 -1
  395. package/src/setup/scenes/sign-in.ts +138 -24
  396. package/src/setup/scenes/splash.ts +28 -1
  397. package/src/setup/scenes/theme.ts +88 -3
  398. package/src/setup/scenes/types.ts +7 -28
  399. package/src/setup/startup-splash.ts +46 -9
  400. package/src/setup/wizard-overlay.ts +140 -23
  401. package/src/setup/wizard.ts +1 -1
  402. package/src/status-line/component.ts +414 -18
  403. package/src/status-line/context-usage.ts +279 -50
  404. package/src/status-line/footer.ts +94 -1
  405. package/src/status-line/metrics.ts +3 -6
  406. package/src/status-line/segments.ts +463 -97
  407. package/src/status-line/separators.ts +3 -16
  408. package/src/status-line/types.ts +43 -1
  409. package/src/stdin-buffer.ts +27 -21
  410. package/src/terminal-capabilities.ts +7 -0
  411. package/src/terminal.ts +153 -11
  412. package/src/theme/defaults/dark-neon-noir.json +100 -0
  413. package/src/theme/defaults/index.ts +2 -0
  414. package/src/theme/defaults/light-prism.json +5 -5
  415. package/src/theme/defaults/onyx.json +62 -62
  416. package/src/theme/mermaid-cache.ts +10 -1
  417. package/src/theme/schema.ts +15 -0
  418. package/src/theme/shimmer.ts +33 -0
  419. package/src/theme/theme-class.ts +24 -19
  420. package/src/theme/theme.ts +111 -9
  421. package/src/theme/tui-adapters.ts +14 -1
  422. package/src/tools/ask.ts +157 -1
  423. package/src/tools/ast-edit.ts +174 -1
  424. package/src/tools/ast-grep.ts +82 -2
  425. package/src/tools/autoresearch.ts +149 -1
  426. package/src/tools/bash.ts +233 -62
  427. package/src/tools/cfg-render.ts +66 -1
  428. package/src/tools/debug.ts +78 -1
  429. package/src/tools/default-renderer.ts +35 -1
  430. package/src/tools/edit.ts +357 -31
  431. package/src/tools/eval.ts +257 -1
  432. package/src/tools/fetch.ts +102 -3
  433. package/src/tools/find.ts +127 -1
  434. package/src/tools/github.ts +119 -10
  435. package/src/tools/glob.ts +116 -1
  436. package/src/tools/goal.ts +56 -1
  437. package/src/tools/grep.ts +83 -2
  438. package/src/tools/grouped-file-output.ts +205 -0
  439. package/src/tools/json-tree.ts +116 -1
  440. package/src/tools/lsp.ts +318 -1
  441. package/src/tools/mcp.ts +80 -1
  442. package/src/tools/memory.ts +93 -11
  443. package/src/tools/native-view.ts +292 -0
  444. package/src/tools/proc-render.ts +221 -1
  445. package/src/tools/read.ts +199 -4
  446. package/src/tools/renderer.ts +61 -0
  447. package/src/tools/report-tool-issue.ts +7 -1
  448. package/src/tools/resolve.ts +63 -1
  449. package/src/tools/streaming-output.ts +79 -16
  450. package/src/tools/task.ts +406 -4
  451. package/src/tools/think.ts +19 -1
  452. package/src/tools/todo.ts +89 -0
  453. package/src/tools/vibe.ts +230 -2
  454. package/src/tools/wait.ts +181 -1
  455. package/src/tools/web-search-types.ts +99 -0
  456. package/src/tools/web-search.ts +111 -170
  457. package/src/tools/write.ts +144 -5
  458. package/src/tools/xdev.ts +64 -1
  459. package/src/tui.ts +295 -4
  460. package/dist/types/setup/scenes/providers.d.ts +0 -3
  461. package/dist/types/setup/scenes/web-search.d.ts +0 -22
  462. package/src/setup/scenes/providers.ts +0 -110
  463. package/src/setup/scenes/web-search.ts +0 -165
@@ -38,16 +38,111 @@ import {
38
38
  import { canReuseCachedPr, createPrCacheContext, isSamePrCacheContext, type PrCacheContext } from "./git-utils";
39
39
  import { summarizeUsageResetCredits } from "../overlays/usage-display";
40
40
  import { getPreset } from "./presets";
41
- import { renderSegment, type SegmentContext } from "./segments";
41
+ import { describeSegment, renderSegment, type SegmentContext } from "./segments";
42
+ import type { TspProps } from "@oh-my-pi/pi-wire";
43
+ import type { NativeNode, NativeUiEvent } from "../native/node";
44
+ import { col, node, span } from "../native/describe";
45
+ import { getContextMeterThresholds, getContextUsageLevel, getContextUsageTone } from "../chrome/context-thresholds";
46
+ import { isNativeRendering } from "../native/state";
42
47
  import { getSeparator } from "./separators";
43
48
  import type {
44
49
  CollabStatus,
50
+ ComposerFacts,
51
+ ComposerFactsSource,
45
52
  EffectiveStatusLineSettings,
53
+ SegmentView,
46
54
  StatusLineSegmentId,
47
55
  StatusLineSegmentOptions,
48
56
  StatusLineSettings,
49
57
  } from "./types";
50
58
 
59
+ /** What a click on a native status segment asks omp to open. */
60
+ export type StatusLineNativeAction = "status.model" | "status.context" | "status.git" | "status.cost" | "status.path";
61
+
62
+ /** Click action per native segment: quick model picker, `/context`, `/git`, `/usage`, the project directory. */
63
+ const NATIVE_SEGMENT_ACTIONS: Partial<Record<string, StatusLineNativeAction>> = {
64
+ model: "status.model",
65
+ context_pct: "status.context",
66
+ context_total: "status.context",
67
+ git: "status.git",
68
+ cost: "status.cost",
69
+ path: "status.path",
70
+ };
71
+
72
+ /** Segments that outlast every other one as the native bar narrows (model, context, git branch). */
73
+ const PINNED_NATIVE_SEGMENTS: Partial<Record<string, true>> = {
74
+ model: true,
75
+ context_pct: true,
76
+ context_total: true,
77
+ git: true,
78
+ };
79
+ const PINNED_NATIVE_PRIORITY = 1000;
80
+
81
+ /**
82
+ * Segments a TSP terminal shows outside the composer's facts: the model chip,
83
+ * the context hairline and usage text (context, cost), Tern's pane header
84
+ * (path, git), the tab title (session name, PR), the HUD pills (subagents)
85
+ * and the editor (vim). The brand (`pi`) stays only while focus-proxied.
86
+ */
87
+ const COMPOSER_HOMED_SEGMENTS: Partial<Record<StatusLineSegmentId, true>> = {
88
+ model: true,
89
+ context_pct: true,
90
+ context_total: true,
91
+ cost: true,
92
+ path: true,
93
+ git: true,
94
+ pr: true,
95
+ session_name: true,
96
+ subagents: true,
97
+ vim: true,
98
+ };
99
+
100
+ /** Pull request the native tab title carries. */
101
+ export interface StatusLinePullRequest {
102
+ readonly number: number;
103
+ readonly url: string;
104
+ }
105
+
106
+ /** Last composer facts and the inputs they were built from. */
107
+ interface NativeFactsMemo {
108
+ facts: ComposerFacts;
109
+ /** Structural fingerprint (elapsed ages excluded: the terminal already clocks them). */
110
+ fingerprint: string;
111
+ renderRevision: number;
112
+ inputRevision: number;
113
+ clockTick: number;
114
+ externalInputs: StatusLineExternalInputs;
115
+ }
116
+
117
+ /** JSON replacer dropping `age`: a rebuilt `elapsed` differs only by send time. */
118
+ function withoutAges(key: string, value: unknown): unknown {
119
+ return key === "age" ? undefined : value;
120
+ }
121
+
122
+ /**
123
+ * Drop priority of a configured segment: the outer edges matter most, so the
124
+ * leftmost left segment and the rightmost right segment stay longest.
125
+ */
126
+ export function statusSegmentPriority(side: "left" | "right", index: number, count: number): number {
127
+ return side === "left" ? count - index : index + 1;
128
+ }
129
+
130
+ /** A native `seg` for a segment view; `dim` fades its spans while focus-proxied. */
131
+ function describeSeg(key: string, props: TspProps<"seg">, view: SegmentView, dim: boolean): NativeNode {
132
+ props.spans = dim ? view.spans.map(part => ({ ...part, s: part.s ? `${part.s} dim` : "dim" })) : view.spans;
133
+ if (view.icon !== undefined) props.icon = view.icon;
134
+ if (view.tone !== undefined) props.tone = view.tone;
135
+ if (view.title !== undefined) props.title = view.title;
136
+ return node("seg", props, view.motion, key);
137
+ }
138
+
139
+ /**
140
+ * Freshness window for the git segment's working-tree counts. A whole-worktree
141
+ * `git status` costs ~1 CPU-second on large repos and every open session polls
142
+ * it, so edits surface within this window; HEAD moves refetch immediately via
143
+ * {@link StatusLineComponent.invalidateGitCaches}.
144
+ */
145
+ const GIT_STATUS_TTL_MS = 10_000;
51
146
  const JJ_REFRESH_TTL_MS = 5000;
52
147
  const JJ_COMMAND_TIMEOUT_MS = 5_000;
53
148
  const WATCHER_FAILURE_POLL_TTL_MS = 5000;
@@ -465,7 +560,9 @@ interface GitViewTaggedRepo extends VcsRepo {
465
560
  // StatusLineComponent
466
561
  // ═══════════════════════════════════════════════════════════════════════════
467
562
 
468
- export class StatusLineComponent<TSession extends StatusLineSession = StatusLineSession> implements Component {
563
+ export class StatusLineComponent<TSession extends StatusLineSession = StatusLineSession>
564
+ implements Component, ComposerFactsSource
565
+ {
469
566
  #standalone: false | "full" | "left-only" = false;
470
567
  #topAttachment: ComposerStyle["statusAttachment"] = "top-border";
471
568
  #standaloneGap = false;
@@ -586,6 +683,7 @@ export class StatusLineComponent<TSession extends StatusLineSession = StatusLine
586
683
  #cachedGitStatus: { staged: number; unstaged: number; untracked: number } | null = null;
587
684
  #cachedGitStatusCwd: string | undefined = undefined;
588
685
  #gitStatusLastFetch = 0;
686
+ #gitStatusGeneration = 0;
589
687
  #gitStatusInFlightCwd: string | undefined = undefined;
590
688
  #cachedJjBranch: string | null = null;
591
689
  #jjBranchLastFetch = 0;
@@ -642,6 +740,11 @@ export class StatusLineComponent<TSession extends StatusLineSession = StatusLine
642
740
  // count (matching the provider and the `/context` panel), so a stable
643
741
  // message list + model window yields a stable result we can return verbatim.
644
742
  #contextUsageCache: ContextUsageMemo | undefined;
743
+ #nativeMemo: NativeFactsMemo | undefined;
744
+ /** Last pull request reported through {@link onNativePullRequest}. */
745
+ #nativePullRequest: StatusLinePullRequest | undefined;
746
+ /** Reused probe buffer for the native memo check; handed to the memo on a rebuild. */
747
+ #nativeInputsProbe = new StatusLineExternalInputs();
645
748
 
646
749
  constructor(
647
750
  private session: TSession,
@@ -796,6 +899,21 @@ export class StatusLineComponent<TSession extends StatusLineSession = StatusLine
796
899
  return this.#subagentCount;
797
900
  }
798
901
 
902
+ /**
903
+ * Running background jobs outside the subagent badge. Task jobs count only
904
+ * until their AgentRegistry ref appears; once it is running, the subagent
905
+ * badge represents that same agent. Bash and eval jobs always count.
906
+ */
907
+ runningBackgroundJobCount(): number {
908
+ return (
909
+ this.session
910
+ .getAsyncJobSnapshot()
911
+ ?.running.filter(
912
+ job => job.type !== "task" || job.agentId === undefined || !this.#runningSubagentIds.has(job.agentId),
913
+ ).length ?? 0
914
+ );
915
+ }
916
+
799
917
  /**
800
918
  * Reset the currently-attached session's active-time accumulators so
801
919
  * the `time_spent` segment starts from zero. Called from `/clear`,
@@ -1072,7 +1190,8 @@ export class StatusLineComponent<TSession extends StatusLineSession = StatusLine
1072
1190
  * the first render after speculation leaves the running state.
1073
1191
  */
1074
1192
  #syncSpeculationBlink(state: "idle" | "running" | "armed"): void {
1075
- if (state === "running" && !this.#disposed) {
1193
+ // A TSP terminal pulses the icon itself (`fx: "pulse"`).
1194
+ if (state === "running" && !this.#disposed && !isNativeRendering()) {
1076
1195
  this.#speculationBlinkTimer ??= setInterval(() => {
1077
1196
  this.#speculationBlinkOn = !this.#speculationBlinkOn;
1078
1197
  this.invalidate();
@@ -1143,7 +1262,8 @@ export class StatusLineComponent<TSession extends StatusLineSession = StatusLine
1143
1262
  }
1144
1263
 
1145
1264
  #startBrandFadeTimer(): void {
1146
- if (this.#brandFadeTimer || this.#disposed) return;
1265
+ // The native brand segment is a terminal-clocked spinner; nothing to repaint.
1266
+ if (this.#brandFadeTimer || this.#disposed || isNativeRendering()) return;
1147
1267
  this.#brandFadeTimer = setInterval(() => {
1148
1268
  const fade = this.#brandFade;
1149
1269
  if (!fade || Date.now() - fade.startedAt >= BRAND_FADE_MS) this.#stopBrandFadeTimer();
@@ -1254,6 +1374,11 @@ export class StatusLineComponent<TSession extends StatusLineSession = StatusLine
1254
1374
  this.#branchLastFetch = undefined;
1255
1375
  this.#branchCacheGeneration++;
1256
1376
  this.#cachedPrContext = undefined;
1377
+ // A HEAD move (commit, checkout, reset) changes the dirty counts; keep the
1378
+ // stale counts on screen but refetch on the next render. The generation
1379
+ // bump stops an in-flight pre-move result from re-stamping freshness.
1380
+ this.#gitStatusLastFetch = 0;
1381
+ this.#gitStatusGeneration++;
1257
1382
  // jj label/status share the git segment's lifecycle: a HEAD move (e.g. a
1258
1383
  // colocated `jj new`/bookmark move) must drop the throttled jj caches too,
1259
1384
  // so the next render refetches.
@@ -1493,11 +1618,12 @@ export class StatusLineComponent<TSession extends StatusLineSession = StatusLine
1493
1618
  if (this.#gitStatusInFlightCwd !== undefined) {
1494
1619
  return this.#cachedGitStatusCwd === gitCwd ? this.#cachedGitStatus : null;
1495
1620
  }
1496
- if (this.#cachedGitStatusCwd === gitCwd && Date.now() - this.#gitStatusLastFetch < 1000) {
1621
+ if (this.#cachedGitStatusCwd === gitCwd && Date.now() - this.#gitStatusLastFetch < GIT_STATUS_TTL_MS) {
1497
1622
  return this.#cachedGitStatus;
1498
1623
  }
1499
1624
 
1500
1625
  this.#gitStatusInFlightCwd = gitCwd;
1626
+ const generation = this.#gitStatusGeneration;
1501
1627
 
1502
1628
  (async () => {
1503
1629
  let nextStatus: { staged: number; unstaged: number; untracked: number } | null = null;
@@ -1510,7 +1636,7 @@ export class StatusLineComponent<TSession extends StatusLineSession = StatusLine
1510
1636
  const prev = this.#cachedGitStatusCwd === gitCwd ? this.#cachedGitStatus : null;
1511
1637
  this.#cachedGitStatus = nextStatus;
1512
1638
  this.#cachedGitStatusCwd = gitCwd;
1513
- this.#gitStatusLastFetch = Date.now();
1639
+ this.#gitStatusLastFetch = this.#gitStatusGeneration === generation ? Date.now() : 0;
1514
1640
  this.#gitStatusInFlightCwd = undefined;
1515
1641
  if (!this.#disposed && JSON.stringify(prev) !== JSON.stringify(nextStatus)) {
1516
1642
  this.#invalidateStatusLineRenderCache();
@@ -2666,15 +2792,7 @@ export class StatusLineComponent<TSession extends StatusLineSession = StatusLine
2666
2792
  }
2667
2793
 
2668
2794
  if (layout !== "plain-left") {
2669
- // Count task jobs only until their AgentRegistry ref appears. Once it is
2670
- // running, the subagent badge represents that same agent; bash and eval
2671
- // jobs always remain independent background work.
2672
- const runningBackgroundJobs =
2673
- this.session
2674
- .getAsyncJobSnapshot()
2675
- ?.running.filter(
2676
- job => job.type !== "task" || job.agentId === undefined || !this.#runningSubagentIds.has(job.agentId),
2677
- ).length ?? 0;
2795
+ const runningBackgroundJobs = this.runningBackgroundJobCount();
2678
2796
  if (runningBackgroundJobs > 0) {
2679
2797
  rightParts.unshift(theme.fg("statusLineSubagents", `${theme.icon.job} ${runningBackgroundJobs}`));
2680
2798
  }
@@ -3029,13 +3147,17 @@ export class StatusLineComponent<TSession extends StatusLineSession = StatusLine
3029
3147
 
3030
3148
  /**
3031
3149
  * Wire this bar into `editor` for a composer layout: the matching top-border
3032
- * provider, the autocomplete probe, and the standalone bottom-bar placement.
3033
- * Callers re-run it whenever the composer shape changes.
3150
+ * provider, the autocomplete probe, the standalone bottom-bar placement, and
3151
+ * the native composer's facts. Callers re-run it whenever the composer shape
3152
+ * changes.
3034
3153
  */
3035
3154
  attachToEditor(
3036
- editor: Pick<Editor, "isAutocompleteActive" | "setTopBorderProvider" | "setTopBorder">,
3155
+ editor: Pick<Editor, "isAutocompleteActive" | "setTopBorderProvider" | "setTopBorder"> & {
3156
+ composerFacts: ComposerFactsSource | undefined;
3157
+ },
3037
3158
  style: Pick<ComposerStyle, "statusAttachment" | "bottomBar" | "bottomBarGap">,
3038
3159
  ): void {
3160
+ editor.composerFacts = this;
3039
3161
  this.setAutocompleteActiveProbe(() => editor.isAutocompleteActive());
3040
3162
  switch (style.statusAttachment) {
3041
3163
  case "top-border":
@@ -3158,6 +3280,280 @@ export class StatusLineComponent<TSession extends StatusLineSession = StatusLine
3158
3280
  return lines;
3159
3281
  }
3160
3282
 
3283
+ /**
3284
+ * The composer's facts on a TSP terminal, which draws no status strip: the
3285
+ * context hairline, the model chip label, the usage text, and every other
3286
+ * configured segment as a `seg` in configured order with its drop priority.
3287
+ * Returns the same object while nothing changed.
3288
+ */
3289
+ describeComposerFacts(): ComposerFacts {
3290
+ const effectiveSettings = this.#resolveSettings();
3291
+ const probe = this.#nativeInputsProbe;
3292
+ this.#readStatusLineExternalInputs(probe);
3293
+ const nowMs = Date.now();
3294
+ const clockTick = this.#nativeClock(nowMs, effectiveSettings);
3295
+ const memo = this.#nativeMemo;
3296
+ if (
3297
+ memo &&
3298
+ memo.renderRevision === this.#renderRevision &&
3299
+ memo.inputRevision === this.#statusLineInputRevision &&
3300
+ memo.clockTick === clockTick &&
3301
+ this.#sameStatusLineExternalInputs(memo.externalInputs, probe)
3302
+ ) {
3303
+ return memo.facts;
3304
+ }
3305
+ this.#nativeInputsProbe = new StatusLineExternalInputs();
3306
+ const built = this.#buildComposerFacts(effectiveSettings, nowMs);
3307
+ const fingerprint = JSON.stringify(built, withoutAges);
3308
+ this.#nativeMemo = {
3309
+ facts: memo?.fingerprint === fingerprint ? memo.facts : built,
3310
+ fingerprint,
3311
+ renderRevision: this.#renderRevision,
3312
+ inputRevision: this.#statusLineInputRevision,
3313
+ clockTick,
3314
+ externalInputs: probe,
3315
+ };
3316
+ return this.#nativeMemo.facts;
3317
+ }
3318
+
3319
+ /**
3320
+ * Native status bar for the /settings appearance preview: a `status` of
3321
+ * `seg`s in configured order, each with its side and a drop priority from
3322
+ * that order, plus hook-status rows.
3323
+ */
3324
+ describePreview(): NativeNode {
3325
+ return this.#describeStatusLine(this.#resolveSettings(), Date.now());
3326
+ }
3327
+
3328
+ /**
3329
+ * Called with the branch's pull request (undefined when there is none) each
3330
+ * time it changes while the composer facts are described; the native tab
3331
+ * title carries it. Looked up only when the `pr` segment is configured.
3332
+ */
3333
+ onNativePullRequest: ((pr: StatusLinePullRequest | undefined) => void) | undefined;
3334
+
3335
+ /** The host's handler for clicks on native segments ({@link NATIVE_SEGMENT_ACTIONS}). */
3336
+ onNativeAction: ((action: StatusLineNativeAction) => void) | undefined;
3337
+
3338
+ handleNativeEvent(event: NativeUiEvent): void {
3339
+ if (event.type !== "action") return;
3340
+ for (const key in NATIVE_SEGMENT_ACTIONS) {
3341
+ const action = NATIVE_SEGMENT_ACTIONS[key];
3342
+ if (action !== event.act) continue;
3343
+ this.onNativeAction?.(action);
3344
+ return;
3345
+ }
3346
+ }
3347
+
3348
+ #buildComposerFacts(effectiveSettings: EffectiveStatusLineSettings, nowMs: number): ComposerFacts {
3349
+ const { leftSegments, rightSegments } = effectiveSettings;
3350
+ const segments = [...leftSegments, ...rightSegments];
3351
+ // Tern's pane header shows the path and branch from the pane's cwd; only the PR is looked up here.
3352
+ const ctx = this.#buildSegmentContext(
3353
+ 0,
3354
+ effectiveSettings.segmentOptions,
3355
+ false,
3356
+ false,
3357
+ this.#gitEnabled() && hasPrSegment(segments),
3358
+ nowMs,
3359
+ );
3360
+ const pr = ctx.git.pr ?? undefined;
3361
+ if (pr?.url !== this.#nativePullRequest?.url || pr?.number !== this.#nativePullRequest?.number) {
3362
+ this.#nativePullRequest = pr && { number: pr.number, url: pr.url };
3363
+ this.onNativePullRequest?.(this.#nativePullRequest);
3364
+ }
3365
+
3366
+ const dim = this.#focusedAgentId !== undefined;
3367
+ const facts: NativeNode[] = [];
3368
+ const collect = (side: "left" | "right", ids: readonly StatusLineSegmentId[]): void => {
3369
+ ids.forEach((id, index) => {
3370
+ if (COMPOSER_HOMED_SEGMENTS[id] || (id === "pi" && ctx.focusedAgentId === undefined)) return;
3371
+ const view = describeSegment(id, ctx);
3372
+ if (!view) return;
3373
+ const props: TspProps<"seg"> = {
3374
+ role: "omp.composer.fact",
3375
+ priority: statusSegmentPriority(side, index, ids.length),
3376
+ };
3377
+ facts.push(describeSeg(id, props, view, dim));
3378
+ });
3379
+ };
3380
+ collect("left", leftSegments);
3381
+ collect("right", rightSegments);
3382
+ // Hook statuses the `status` segment doesn't already carry trail the configured facts.
3383
+ if ((this.#settings.showHookStatus ?? true) && !segments.includes("status")) {
3384
+ this.#sortedHookStatuses.forEach((status, index) => {
3385
+ const text = sanitizeStatusText(status);
3386
+ if (!text) return;
3387
+ const props: TspProps<"seg"> = { role: "omp.composer.fact", priority: 0 };
3388
+ facts.push(describeSeg(`hook-${index}`, props, { spans: [span(text)] }, dim));
3389
+ });
3390
+ }
3391
+
3392
+ const pct = ctx.contextPercent;
3393
+ const window = ctx.contextWindow;
3394
+ const boundaries = ctx.autoCompactEnabled ? this.#compactionBoundaries(window) : null;
3395
+ const lines = [
3396
+ pct === null ? "Context usage unknown" : `Context ${Math.round(pct)}% used`,
3397
+ window > 0 ? `${formatNumber(ctx.contextTokens)} of ${formatNumber(window)} tokens` : "No context window",
3398
+ ];
3399
+ if (boundaries) lines.push(`Auto-compact at ${Math.round(boundaries.thresholdPercent)}%`);
3400
+ if (ctx.compactionSpeculation === "running") lines.push("Compaction summary in progress");
3401
+ else if (ctx.compactionSpeculation === "armed") lines.push("Compaction summary ready");
3402
+ const context = node(
3403
+ "meter",
3404
+ {
3405
+ role: "omp.composer.context",
3406
+ value: pct === null ? null : Math.min(1, pct / 100),
3407
+ style: "bar",
3408
+ thresholds: getContextMeterThresholds(window),
3409
+ marks: boundaries
3410
+ ? [
3411
+ {
3412
+ at: boundaries.thresholdPercent / 100,
3413
+ title: `Auto-compact at ${Math.round(boundaries.thresholdPercent)}%`,
3414
+ },
3415
+ ]
3416
+ : undefined,
3417
+ title: lines.join("\n"),
3418
+ },
3419
+ undefined,
3420
+ "context",
3421
+ );
3422
+
3423
+ const share =
3424
+ pct !== null && window > 0
3425
+ ? `${Math.round(pct)}% of ${formatNumber(window)}`
3426
+ : window > 0
3427
+ ? formatNumber(window)
3428
+ : `${formatNumber(ctx.contextTokens)} tokens`;
3429
+ const cost = describeSegment("cost", ctx)
3430
+ ?.spans.map(part => part.t)
3431
+ .join("");
3432
+ if (cost) lines.push(`Session cost ${cost}`);
3433
+ const usage = node(
3434
+ "text",
3435
+ {
3436
+ role: "omp.composer.usage",
3437
+ tone: getContextUsageTone(getContextUsageLevel(pct ?? 0, window)),
3438
+ text: cost ? `${share} · ${cost}` : share,
3439
+ wrap: "none",
3440
+ title: lines.join("\n"),
3441
+ actions: { click: "status.context" },
3442
+ },
3443
+ undefined,
3444
+ "usage",
3445
+ );
3446
+
3447
+ // The effort chip carries the thinking level.
3448
+ const modelCtx: SegmentContext = {
3449
+ ...ctx,
3450
+ options: { ...ctx.options, model: { ...ctx.options.model, showThinkingLevel: false } },
3451
+ };
3452
+ return {
3453
+ context,
3454
+ model: describeSegment("model", modelCtx) ?? { spans: [] },
3455
+ extras: node("status", { role: "omp.composer.extras", transparent: true, grow: 1 }, facts, "extras"),
3456
+ usage,
3457
+ };
3458
+ }
3459
+
3460
+ /**
3461
+ * Wall-clock granularity of the native bar. Spinners, turn timers and the
3462
+ * brand fade are terminal-clocked, so only wall-clock text (time, loop
3463
+ * countdowns) and VCS fallback polling advance it.
3464
+ */
3465
+ #nativeClock(nowMs: number, effectiveSettings: EffectiveStatusLineSettings): number {
3466
+ const segments = [...effectiveSettings.leftSegments, ...effectiveSettings.rightSegments];
3467
+ const includesTime = segments.includes("time");
3468
+ if (
3469
+ (this.#loopModeStatus?.limit?.kind === "duration" && segments.includes("mode")) ||
3470
+ (includesTime && effectiveSettings.segmentOptions?.time?.showSeconds === true)
3471
+ ) {
3472
+ return Math.floor(nowMs / 1_000);
3473
+ }
3474
+ if (includesTime) return Math.floor(nowMs / 60_000);
3475
+ if (this.#gitEnabled() && hasGitBackedSegment(segments)) return Math.floor(nowMs / 1_000);
3476
+ if (this.#gitEnabled() && hasPathSegment(segments)) return Math.floor(nowMs / WATCHER_FAILURE_POLL_TTL_MS);
3477
+ return 0;
3478
+ }
3479
+
3480
+ #describeStatusLine(effectiveSettings: EffectiveStatusLineSettings, nowMs: number): NativeNode {
3481
+ const { leftSegments, rightSegments } = effectiveSettings;
3482
+ const segments = [...leftSegments, ...rightSegments];
3483
+ const gitEnabled = this.#gitEnabled();
3484
+ const ctx = this.#buildSegmentContext(
3485
+ 0,
3486
+ effectiveSettings.segmentOptions,
3487
+ hasPathSegment(segments),
3488
+ gitEnabled && hasGitSegment(segments),
3489
+ gitEnabled && hasPrSegment(segments),
3490
+ nowMs,
3491
+ );
3492
+ const dim = this.#focusedAgentId !== undefined;
3493
+ const segs: NativeNode[] = [];
3494
+ const push = (key: string, side: "left" | "right", priority: number, view: SegmentView): void => {
3495
+ const pinned = PINNED_NATIVE_SEGMENTS[key] === true;
3496
+ const props: TspProps<"seg"> = {
3497
+ role: `omp.status.${key}`,
3498
+ side,
3499
+ priority: pinned ? PINNED_NATIVE_PRIORITY + priority : priority,
3500
+ };
3501
+ // The path truncates before anything drops.
3502
+ if (key === "path") props.min = { w: "12ch" };
3503
+ const action = NATIVE_SEGMENT_ACTIONS[key];
3504
+ if (action) props.actions = { click: action };
3505
+ segs.push(describeSeg(key, props, view, dim));
3506
+ };
3507
+ const subagentBadge = this.#subagentCount > 0;
3508
+ leftSegments.forEach((id, index) => {
3509
+ if (subagentBadge && id === "subagents") return;
3510
+ const view = describeSegment(id, ctx);
3511
+ if (view) push(id, "left", statusSegmentPriority("left", index, leftSegments.length), view);
3512
+ });
3513
+ // Live-work badges lead the right group, as in the ANSI bar; they sit on
3514
+ // the inner edge, so they drop before any configured segment.
3515
+ if (subagentBadge) {
3516
+ push("subagent-badge", "right", 0, {
3517
+ spans: [{ t: `${this.#subagentCount}`, s: "statusLineSubagents" }],
3518
+ icon: "agents",
3519
+ });
3520
+ }
3521
+ const runningBackgroundJobs = this.runningBackgroundJobCount();
3522
+ if (runningBackgroundJobs > 0) {
3523
+ push("jobs", "right", 0, {
3524
+ spans: [{ t: `${runningBackgroundJobs}`, s: "statusLineSubagents" }],
3525
+ icon: "job",
3526
+ });
3527
+ }
3528
+ rightSegments.forEach((id, index) => {
3529
+ if (subagentBadge && id === "subagents") return;
3530
+ const view = describeSegment(id, ctx);
3531
+ if (view) push(id, "right", statusSegmentPriority("right", index, rightSegments.length), view);
3532
+ });
3533
+ const bar = node(
3534
+ "status",
3535
+ { role: "omp.status", transparent: effectiveSettings.transparent === true },
3536
+ segs,
3537
+ "bar",
3538
+ );
3539
+ const showHooks = this.#settings.showHookStatus ?? true;
3540
+ if (!showHooks || this.#sortedHookStatuses.length === 0) return bar;
3541
+ return col(
3542
+ [
3543
+ bar,
3544
+ ...this.#sortedHookStatuses.map((status, index) =>
3545
+ node(
3546
+ "text",
3547
+ { text: sanitizeStatusText(status), wrap: "none", role: "omp.status.hook" },
3548
+ undefined,
3549
+ `hook-${index}`,
3550
+ ),
3551
+ ),
3552
+ ],
3553
+ { role: "omp.status.panel" },
3554
+ );
3555
+ }
3556
+
3161
3557
  render(width: number): readonly string[] {
3162
3558
  const lines: string[] = [];
3163
3559
  if (this.#standalone && !this.#autocompleteActiveProbe?.()) {