@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
@@ -10,12 +10,17 @@ import {
10
10
  renderKittyPlaceholderLines,
11
11
  setKittyGraphics,
12
12
  } from "./kitty-graphics";
13
- import { isInsideHerdr, isInsideTerminalMultiplexer } from "./terminal-multiplexer";
14
- import { isInsideTmux, resolveTmuxClientTerminalName, wrapTmuxPassthrough, wrapTmuxPassthroughIfNeeded } from "./tmux";
13
+ import {
14
+ isInsideTerminalMultiplexer,
15
+ routeTerminalMultiplexerNotification,
16
+ terminalMultiplexerForTerm,
17
+ terminalMultiplexerSessions,
18
+ } from "./terminal-multiplexer";
19
+ import { resolveTmuxClientTerminalName, wrapTmuxPassthroughIfNeeded } from "./tmux";
15
20
  import type { HangulCompatibilityJamoWidth } from "./utils";
16
21
 
17
22
  export * from "./terminal-multiplexer";
18
- export { isInsideTmux, wrapTmuxPassthrough } from "./tmux";
23
+ export { wrapTmuxPassthrough } from "./tmux";
19
24
 
20
25
  export enum ImageProtocol {
21
26
  Kitty = "\x1b_G",
@@ -45,92 +50,6 @@ export type TerminalId =
45
50
  | "base"
46
51
  | "trueColor";
47
52
 
48
- const CMUX_NOTIFICATION_TITLE = "zeta";
49
- const CMUX_SURFACE_ID_PATTERN = /^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/iu;
50
-
51
- /** Title and body for an out-of-band multiplexer notification (cmux, Herdr). */
52
- function notificationTitleAndBody(message: string | TerminalNotification): { title: string; body: string } {
53
- if (typeof message === "string") return { title: CMUX_NOTIFICATION_TITLE, body: message };
54
- return { title: message.title?.trim() || CMUX_NOTIFICATION_TITLE, body: message.body ?? "" };
55
- }
56
-
57
- /**
58
- * Route a notification through cmux when the process belongs to a concrete
59
- * surface. Workspace/socket state alone is not enough: only the injected
60
- * surface UUID identifies the pane that should receive the notification.
61
- * Returns whether cmux owns delivery so the caller can preserve every existing
62
- * terminal fallback unchanged when no valid surface is present.
63
- */
64
- function sendCmuxNotification(message: string | TerminalNotification, env: NodeJS.ProcessEnv = Bun.env): boolean {
65
- const surfaceId = env.CMUX_SURFACE_ID?.trim();
66
- if (!surfaceId || !CMUX_SURFACE_ID_PATTERN.test(surfaceId)) return false;
67
-
68
- const { title, body } = notificationTitleAndBody(message);
69
- try {
70
- const child = Bun.spawn({
71
- cmd: ["cmux", "notify", "--surface", surfaceId, "--title", title, "--body", body],
72
- stdin: "ignore",
73
- stdout: "ignore",
74
- stderr: "ignore",
75
- });
76
- child.unref();
77
- } catch {
78
- // A missing cmux binary leaves delivery to the existing terminal fallback.
79
- return false;
80
- }
81
- return true;
82
- }
83
-
84
- const HERDR_PANE_ID_PATTERN = /^[0-9A-Za-z:_-]{1,64}$/u;
85
- /**
86
- * `herdr notification show` takes the title as its first positional and reads
87
- * exactly these three values there as a help request; it has no `--`
88
- * terminator. Any other text, including one starting with `-`, is a title.
89
- */
90
- const HERDR_USAGE_TOKENS = new Set(["help", "--help", "-h"]);
91
-
92
- /**
93
- * Route a notification through Herdr when the process runs inside one of its
94
- * panes. Herdr multiplexes panes like tmux but swallows bare OSC 9 / OSC 99 and
95
- * has no DCS passthrough envelope, and its bell relay does not flag a
96
- * backgrounded tab — so without this branch a backgrounded pane gets no signal
97
- * at all that the agent finished or is waiting for input.
98
- *
99
- * `sound` maps the notification kind onto what Herdr offers: a question waiting
100
- * on the user and a turn that stopped with an error both need the human and
101
- * ring `request`, a settled turn rings `done`, anything else stays
102
- * silent. Returns whether Herdr owns delivery, so every existing terminal
103
- * fallback is preserved when the pane id is absent or the binary is missing.
104
- */
105
- function sendHerdrNotification(message: string | TerminalNotification, env: NodeJS.ProcessEnv = Bun.env): boolean {
106
- // Pane-only detection, like `isInsideHerdr`: an env-sanitizing launcher can
107
- // drop HERDR_ENV and keep the pane identity, and that pane can still be
108
- // backgrounded. The pane id itself is what the CLI needs, so it stays required.
109
- if (!isInsideHerdr(env)) return false;
110
- const paneId = env.HERDR_PANE_ID?.trim();
111
- if (!paneId || !HERDR_PANE_ID_PATTERN.test(paneId)) return false;
112
-
113
- const parsed = notificationTitleAndBody(message);
114
- const title = HERDR_USAGE_TOKENS.has(parsed.title) ? CMUX_NOTIFICATION_TITLE : parsed.title;
115
- const body = parsed.body;
116
- const kinds = typeof message === "string" ? [] : [message.type ?? []].flat();
117
- const sound =
118
- kinds.includes("ask") || kinds.includes("error") ? "request" : kinds.includes("completion") ? "done" : "none";
119
- try {
120
- const child = Bun.spawn({
121
- cmd: ["herdr", "notification", "show", title, "--body", body, "--sound", sound],
122
- stdin: "ignore",
123
- stdout: "ignore",
124
- stderr: "ignore",
125
- });
126
- child.unref();
127
- } catch {
128
- // A missing herdr binary leaves delivery to the existing terminal fallback.
129
- return false;
130
- }
131
- return true;
132
- }
133
-
134
53
  const IMAGE_MARKER_SCAN_LIMIT = 512;
135
54
  const SIXEL_MARKER_SCAN_LIMIT = 128;
136
55
  const KITTY_PLACEHOLDER_HIGH_SURROGATE = KITTY_PLACEHOLDER.charCodeAt(0);
@@ -236,33 +155,16 @@ export class TerminalInfo {
236
155
 
237
156
  sendNotification(message: string | TerminalNotification): void {
238
157
  if (isNotificationSuppressed() || isTerminalHeadless()) return;
239
- // Innermost surface first. A Herdr pane launched inside a cmux surface
240
- // inherits both `HERDR_PANE_ID` and the outer `CMUX_SURFACE_ID`; routing to
241
- // cmux there would flag the containing surface and leave the backgrounded
242
- // Herdr pane — the one actually waiting — without a sound or a marker.
243
- if (sendHerdrNotification(message)) return;
244
- if (sendCmuxNotification(message)) return;
245
158
  const formatted = this.formatNotification(message);
246
- // Under tmux, terminals whose notify protocol is OSC 9 / OSC 99 would
247
- // otherwise lose the notification entirely: tmux does not forward bare
248
- // OSC 9/99 to the outer terminal, and the bare sequence does not flag
249
- // tmux's own `monitor-bell` / `monitor-activity`. Wrap the OSC in tmux's
250
- // DCS passthrough envelope so users with `allow-passthrough on` still
251
- // get the desktop toast, then append a BEL so `monitor-bell` flags the
252
- // pane/window for everyone else — the only signal a backgrounded pane
253
- // has that the agent finished or is waiting for input. `Bell` protocol
254
- // already self-flags via tmux's bell monitoring, so leave it alone.
255
- if (this.notifyProtocol !== NotifyProtocol.Bell && isInsideTmux()) {
256
- writeTerminalSequence(`${wrapTmuxPassthrough(formatted)}\x07`);
257
- return;
258
- }
259
- // Zellij drops OSC 9/99 and has no DCS passthrough envelope, but raises its
260
- // `[!]` bell flag on a bare BEL — the same backgrounded-pane signal tmux
261
- // users get. So follow the (Zellij-swallowed) OSC with a plain BEL.
262
- if (this.notifyProtocol !== NotifyProtocol.Bell && isInsideZellij()) {
263
- writeTerminalSequence(`${formatted}\x07`);
264
- return;
265
- }
159
+ // Multiplexers that swallow or rewrite the terminal's notification get it
160
+ // first, innermost target first; the terminal sequence is the fallback.
161
+ const routed = routeTerminalMultiplexerNotification({
162
+ message,
163
+ env: Bun.env,
164
+ sequence: this.notifyProtocol === NotifyProtocol.Bell ? null : formatted,
165
+ write: writeTerminalSequence,
166
+ });
167
+ if (routed) return;
266
168
  writeTerminalSequence(formatted);
267
169
  // VTE-family terminals (Ptyxis, GNOME Terminal, Tilix, …) plus Alacritty
268
170
  // and bare xterm-on-Wayland have no in-band escape that surfaces an
@@ -276,15 +178,6 @@ export class TerminalInfo {
276
178
  }
277
179
  }
278
180
 
279
- /**
280
- * Whether the agent process is running inside a Zellij session. Read fresh on
281
- * each call (like {@link isInsideTmux}) so a session attached/detached mid-run
282
- * is observed and tests can toggle `Bun.env.ZELLIJ` per case.
283
- */
284
- export function isInsideZellij(env: NodeJS.ProcessEnv = Bun.env): boolean {
285
- return Boolean(env.ZELLIJ);
286
- }
287
-
288
181
  /**
289
182
  * Whether the agent process runs in an SSH session, so the terminal emulator
290
183
  * is remote and host-local input/keyboard modes cannot be assumed.
@@ -381,12 +274,12 @@ function advertisesSynchronizedOutput(termFeatures: string | undefined): boolean
381
274
  * 2. Positive `TERM_FEATURES` advertisement (`Sy`) — survives SSH/mux wrapping.
382
275
  * 3. Windows Terminal (1.24+) via `WT_SESSION`, on native win32 and the
383
276
  * WSL/SSH-fronted host alike.
384
- * 4. Herdr panes. Herdr is otherwise treated as a multiplexer so leaked
385
- * kitty/ghostty identities cannot enable placeholder graphics, but its
386
- * pane VTE is libghostty and already suppresses compositing while DEC 2026
387
- * is set. Leaving sync off lets CUP-diff paints and split write(2) chunks
388
- * composite as dirty-row patches — the live viewport tears, with the top
389
- * frozen while only the bottom refreshes.
277
+ * 4. A multiplexer session whose pane VTE honors DEC 2026 regardless of its
278
+ * DECRQM reply (Herdr's libghostty pane). Such a multiplexer still owns
279
+ * the grid, so leaked kitty/ghostty identities cannot enable placeholder
280
+ * graphics, but leaving sync off lets CUP-diff paints and split write(2)
281
+ * chunks composite as dirty-row patches — the live viewport tears, with
282
+ * the top frozen while only the bottom refreshes.
390
283
  * 5. Known direct terminals with confirmed support. SSH does *not* disable —
391
284
  * DEC 2026 passes through SSH when the outer terminal honors it.
392
285
  * 6. Everything else starts off, including risky multiplexers; the runtime
@@ -402,7 +295,7 @@ export function shouldEnableSynchronizedOutputByDefault(
402
295
 
403
296
  if (advertisesSynchronizedOutput(env.TERM_FEATURES)) return true;
404
297
  if (env.WT_SESSION && (!env.TERM_PROGRAM || env.TERM_PROGRAM.toLowerCase() === "windows_terminal")) return true;
405
- if (isInsideHerdr(env)) return true;
298
+ if (terminalMultiplexerSessions(env).some(multiplexer => multiplexer.honorsSynchronizedOutput)) return true;
406
299
 
407
300
  // Risky multiplexers start off even when an inner terminal id leaks through:
408
301
  // older tmux/screen synchronized-output handling is flaky and a mux may not
@@ -521,48 +414,35 @@ export function hyperlinksUserOverride(env: NodeJS.ProcessEnv = Bun.env): boolea
521
414
  return null;
522
415
  }
523
416
 
524
- /**
525
- * Parse tmux's self-reported version from `TERM_PROGRAM_VERSION`. tmux sets
526
- * `TERM_PROGRAM=tmux` and `TERM_PROGRAM_VERSION=<version>` automatically since
527
- * 3.2a; older releases (or any path that does not surface the version) yield
528
- * `null` and the caller treats tmux conservatively.
529
- */
530
- function parseTmuxVersionFromEnv(env: NodeJS.ProcessEnv): { major: number; minor: number } | null {
531
- if (env.TERM_PROGRAM?.toLowerCase() !== "tmux") return null;
532
- return parseMajorMinorVersion(env.TERM_PROGRAM_VERSION);
533
- }
534
-
535
417
  /**
536
418
  * Whether OSC 8 hyperlinks should be enabled by default.
537
419
  *
538
420
  * Policy (highest precedence first):
539
421
  * 1. Explicit user override (`PI_NO_HYPERLINKS=1` off, `PI_FORCE_HYPERLINKS=1`
540
422
  * on). Opt-out wins ties.
541
- * 2. Herdr pane with no nested screen/tmux: on. Herdr hides the outer
542
- * terminal (`TERM=xterm-256color`, no `TERM_PROGRAM`), but it renders
543
- * OSC 8 in its own grid and opens links itself on Ctrl+click, so the
544
- * outer terminal's support does not matter.
423
+ * 2. Every multiplexer session with a hyperlink policy renders OSC 8 itself
424
+ * (`render`, e.g. Herdr): on. Herdr hides the outer terminal
425
+ * (`TERM=xterm-256color`, no `TERM_PROGRAM`), so the outer terminal's
426
+ * support does not matter.
545
427
  * 2b. Zeta workbench pane with no nested screen/tmux: on, for the same
546
428
  * reason — the workbench's terminal simulator renders OSC 8 itself and
547
429
  * opens links on Ctrl+click (`ZETA_WORKBENCH=1` is injected into every
548
430
  * pane PTY; the outer terminal is invisible from inside).
549
431
  * 3. Static terminal capability — terminals whose {@link TerminalInfo} marks
550
432
  * `hyperlinks: false` (e.g. `base`) stay off unless the user forced on.
551
- * 4. GNU screen's explicit session marker (`STY`) always off, even if tmux is
552
- * also present: a screen layer anywhere in the path cannot forward OSC 8.
553
- * 5. tmux session (`TMUX` set): enabled when tmux self-reports >= 3.4 via
554
- * `TERM_PROGRAM_VERSION` (tmux 3.4 stores OSC 8 as a cell attribute and
555
- * forwards it to outer terminals whose `terminal-features` include
556
- * `hyperlinks`). Older or unknown versions stay off; on outer terminals
557
- * without the feature configured, tmux silently drops the sequence —
558
- * identical to today. Checked before the screen-family TERM heuristic
559
- * because tmux's historical `default-terminal` is `screen-256color`, so
560
- * `TERM=screen*` inside a tmux session must NOT short-circuit to off.
561
- * 6. screen-family TERM without `TMUX` always off: screen never gained OSC 8
562
- * support.
563
- * 7. tmux-family TERM without `TMUX` env — unusual (e.g. inspection scripts);
564
- * no version available, so off.
565
- * 8. Otherwise honor the static terminal capability.
433
+ * 4. A session that never forwards OSC 8 (`drop`, e.g. GNU screen's `STY`)
434
+ * always off, even when a forwarding multiplexer is also present.
435
+ * 5. Forwarding sessions (`forward`, e.g. `TMUX`): enabled when every one
436
+ * self-reports at least its forwarding version via `TERM_PROGRAM` /
437
+ * `TERM_PROGRAM_VERSION` (tmux 3.4). Older or unknown versions stay off;
438
+ * on outer terminals without the feature configured, tmux silently drops
439
+ * the sequence. Checked before the TERM heuristic because tmux's
440
+ * historical `default-terminal` is `screen-256color`, so `TERM=screen*`
441
+ * inside a tmux session must NOT short-circuit to off.
442
+ * 6. TERM naming a multiplexer whose session markers were stripped: off,
443
+ * since no session proves the multiplexer forwards OSC 8 (screen never
444
+ * does; tmux has no version to check).
445
+ * 7. Otherwise honor the static terminal capability.
566
446
  */
567
447
  export function shouldEnableHyperlinksByDefault(
568
448
  env: NodeJS.ProcessEnv = Bun.env,
@@ -571,29 +451,29 @@ export function shouldEnableHyperlinksByDefault(
571
451
  const override = hyperlinksUserOverride(env);
572
452
  if (override !== null) return override;
573
453
 
574
- if (isInsideHerdr(env) && !env.STY && !env.TMUX) return true;
454
+ const policies = terminalMultiplexerSessions(env).flatMap(multiplexer =>
455
+ multiplexer.hyperlinks === undefined ? [] : [multiplexer.hyperlinks],
456
+ );
457
+ if (policies.length > 0 && policies.every(policy => policy === "render")) return true;
575
458
 
576
459
  if (isInsideZetaWorkbench(env) && !env.STY && !env.TMUX) return true;
577
460
 
578
461
  if (!getTerminalInfo(terminalId).hyperlinks) return false;
579
462
 
580
- // STY is GNU screen's explicit session marker. It vetoes tmux enabling when
581
- // multiplexers are nested because screen cannot forward OSC 8 anywhere in the
582
- // path.
583
- if (env.STY) return false;
584
-
585
- // tmux check before TERM heuristics: TMUX is the authoritative current-session
586
- // signal and supersedes TERM, which may be `screen-256color` under tmux's
587
- // historical default-terminal setting.
588
- if (env.TMUX) {
589
- const version = parseTmuxVersionFromEnv(env);
590
- if (!version) return false;
591
- return version.major > 3 || (version.major === 3 && version.minor >= 4);
463
+ if (policies.includes("drop")) return false;
464
+
465
+ const forwarders = policies.flatMap(policy => (typeof policy === "object" ? [policy.forward] : []));
466
+ if (forwarders.length > 0) {
467
+ const termProgram = env.TERM_PROGRAM?.toLowerCase();
468
+ return forwarders.every(forward => {
469
+ if (termProgram !== forward.termProgram) return false;
470
+ const version = parseMajorMinorVersion(env.TERM_PROGRAM_VERSION);
471
+ if (!version) return false;
472
+ return version.major > forward.major || (version.major === forward.major && version.minor >= forward.minor);
473
+ });
592
474
  }
593
475
 
594
- const term = env.TERM?.toLowerCase() ?? "";
595
- if (term.startsWith("screen")) return false;
596
- if (term.startsWith("tmux")) return false;
476
+ if (terminalMultiplexerForTerm(env)) return false;
597
477
 
598
478
  return true;
599
479
  }
@@ -667,10 +547,14 @@ export function resolveImageProtocol(
667
547
  if (imageProtocol !== null && isPaseoEmbedder(env)) {
668
548
  return null;
669
549
  }
670
- // Herdr owns the pane grid but does not expose whether the attached client
671
- // enabled its experimental Kitty renderer. Outer-terminal identity variables
672
- // can leak into the pane, so only the explicit protocol override is safe.
673
- if (imageProtocol !== null && isInsideHerdr(env)) {
550
+ // Some multiplexers own the pane grid without exposing whether the attached
551
+ // client renders graphics (Herdr's experimental Kitty renderer). Outer-
552
+ // terminal identity variables can leak into the pane, so only the explicit
553
+ // protocol override is safe.
554
+ if (
555
+ imageProtocol !== null &&
556
+ terminalMultiplexerSessions(env).some(multiplexer => multiplexer.imagesRequireOverride)
557
+ ) {
674
558
  return null;
675
559
  }
676
560
  return imageProtocol;
@@ -1050,8 +934,7 @@ export function encodeKittyPlacement(options: {
1050
934
  /**
1051
935
  * Exact shape of the direct-placement line {@link Image} emits as its block's
1052
936
  * last row: optional `ESC 7` + `CUU(rows-1)` prefix, the {@link encodeKittyPlacement}
1053
- * APC, optional `ESC 8` suffix. tmux-passthrough-wrapped lines deliberately do
1054
- * not match (passthrough placements stay untouched).
937
+ * APC, optional `ESC 8` suffix. The parser unwraps tmux passthrough first.
1055
938
  */
1056
939
  const KITTY_DIRECT_PLACEMENT_LINE =
1057
940
  /^(?:\x1b7(?:\x1b\[(\d+)A)?)?\x1b_Ga=p,q=2,C=1,i=(\d+)(?:,p=(\d+))?(?:,c=(\d+))?(?:,r=(\d+))?\x1b\\(?:\x1b8)?$/;
@@ -1066,10 +949,15 @@ export interface ParsedKittyPlacementLine {
1066
949
  /**
1067
950
  * Parse a frame line that consists solely of a Kitty direct placement (the
1068
951
  * last line of an {@link Image} block). Returns null for anything else —
1069
- * placeholder grids, tmux-wrapped placements, sixel/iTerm2 payloads — so
952
+ * placeholder grids, sixel/iTerm2 payloads — so
1070
953
  * callers fall back to writing the line verbatim.
1071
954
  */
1072
955
  export function parseKittyDirectPlacementLine(line: string): ParsedKittyPlacementLine | null {
956
+ if (line.includes("\x1bPtmux;")) {
957
+ line = line.replace(/\x1bPtmux;((?:[^\x1b]|\x1b\x1b)*)\x1b\\/g, (_match, payload: string) =>
958
+ payload.replaceAll("\x1b\x1b", "\x1b"),
959
+ );
960
+ }
1073
961
  const m = KITTY_DIRECT_PLACEMENT_LINE.exec(line);
1074
962
  if (!m) return null;
1075
963
  const columns = m[4] !== undefined ? Number(m[4]) : 0;
@@ -1114,9 +1002,7 @@ export function encodeKittyPlacementLine(options: {
1114
1002
  const srcY = Math.floor((options.imageHeightPx * hiddenRows) / options.rows);
1115
1003
  params.push(`y=${srcY}`, `h=${Math.max(1, options.imageHeightPx - srcY)}`);
1116
1004
  }
1117
- // No tmux passthrough: inside tmux the component's own line arrives
1118
- // wrapped, never parses, and never reaches this rewrite.
1119
- const apc = `\x1b_G${params.join(",")}\x1b\\`;
1005
+ const apc = wrapTmuxPassthroughIfNeeded(`\x1b_G${params.join(",")}\x1b\\`);
1120
1006
  const cuu = visibleRows - 1;
1121
1007
  return cuu > 0 ? `\x1b7\x1b[${cuu}A${apc}\x1b8` : apc;
1122
1008
  }
@@ -1143,8 +1029,8 @@ export function encodeKittyDeleteAllImages(): string {
1143
1029
  /**
1144
1030
  * Delete a single placement of an image (`d=i`, lowercase): removes its cells
1145
1031
  * and registry entry but keeps the transmitted data, so a later `a=p` under a
1146
- * fresh placement id needs no retransmit. Used to clear stale placement-epoch
1147
- * entries after a destructive history clear.
1032
+ * fresh placement id needs no retransmit. The frame writer uses this before
1033
+ * replacing a live image without deleting its archived copies.
1148
1034
  */
1149
1035
  export function encodeKittyDeletePlacement(imageId: number, placementId: number): string {
1150
1036
  return wrapTmuxPassthroughIfNeeded(`\x1b_Ga=d,d=i,i=${imageId},p=${placementId},q=2\x1b\\`);
@@ -1,20 +1,133 @@
1
- /** True when this process is running inside a Herdr pane. */
2
- export declare function isInsideHerdr(env?: NodeJS.ProcessEnv): boolean;
3
- /** Terminal multiplexers zeta recognizes as owning the screen grid. */
4
- export type TerminalMultiplexer = "herdr" | "tmux" | "screen" | "zellij" | "cmux" | "wmux";
1
+ import type { TerminalMultiplexerModule, TerminalMultiplexerNotificationRequest } from "./multiplexers/types";
5
2
  /**
6
- * Classify which terminal multiplexer owns the current screen grid, or `null`
7
- * for a direct terminal. Single source of truth for both the render-path gate
3
+ * Every multiplexer omp recognizes, in classification order within each
4
+ * precedence tier. Adding a multiplexer means adding its module here.
5
+ */
6
+ declare const registry: readonly [{
7
+ readonly id: "herdr";
8
+ readonly precedence: "session";
9
+ readonly sessionEnvKeys: readonly ["HERDR_ENV", "HERDR_PANE_ID", "HERDR_TAB_ID", "HERDR_WORKSPACE_ID"];
10
+ readonly ownsScreenGrid: true;
11
+ readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
12
+ readonly notifier: {
13
+ readonly tier: "pane";
14
+ readonly send: ({ message, env }: TerminalMultiplexerNotificationRequest) => boolean;
15
+ };
16
+ readonly hyperlinks: "render";
17
+ readonly honorsSynchronizedOutput: true;
18
+ readonly imagesRequireOverride: true;
19
+ }, {
20
+ readonly id: "tmux";
21
+ readonly precedence: "session";
22
+ readonly sessionEnvKeys: readonly ["TMUX"];
23
+ readonly termPrefix: "tmux";
24
+ readonly ownsScreenGrid: true;
25
+ readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
26
+ readonly notifier: {
27
+ readonly tier: "inBand";
28
+ readonly send: ({ sequence, write }: TerminalMultiplexerNotificationRequest) => boolean;
29
+ };
30
+ readonly hyperlinks: {
31
+ readonly forward: {
32
+ readonly termProgram: "tmux";
33
+ readonly major: 3;
34
+ readonly minor: 4;
35
+ };
36
+ };
37
+ readonly backgroundColorCache: {
38
+ readonly passthrough: typeof import("./tmux").wrapTmuxPassthrough;
39
+ readonly settleMs: 100;
40
+ };
41
+ readonly expandsRepPadding: true;
42
+ readonly expiresSynchronizedOutput: true;
43
+ readonly altRestoreEndsSynchronizedOutput: true;
44
+ readonly growsBeforeSigwinch: true;
45
+ }, {
46
+ readonly id: "screen";
47
+ readonly precedence: "session";
48
+ readonly sessionEnvKeys: readonly ["STY"];
49
+ readonly termPrefix: "screen";
50
+ readonly ownsScreenGrid: true;
51
+ readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
52
+ readonly hyperlinks: "drop";
53
+ }, {
54
+ readonly id: "zellij";
55
+ readonly precedence: "session";
56
+ readonly sessionEnvKeys: readonly ["ZELLIJ"];
57
+ readonly ownsScreenGrid: true;
58
+ readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
59
+ readonly notifier: {
60
+ readonly tier: "inBand";
61
+ readonly send: ({ sequence, write }: TerminalMultiplexerNotificationRequest) => boolean;
62
+ };
63
+ readonly backgroundQueryBrokenOn: readonly ["darwin"];
64
+ }, {
65
+ readonly id: "cmux";
66
+ readonly precedence: "session";
67
+ readonly sessionEnvKeys: readonly ["CMUX_WORKSPACE_ID", "CMUX_SURFACE_ID", "CMUX_REMOTE_TRANSPORT"];
68
+ readonly ownsScreenGrid: true;
69
+ readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
70
+ readonly notifier: {
71
+ readonly tier: "surface";
72
+ readonly send: ({ message, env }: TerminalMultiplexerNotificationRequest) => boolean;
73
+ };
74
+ }, {
75
+ readonly id: "wmux";
76
+ readonly precedence: "session";
77
+ readonly sessionEnvKeys: readonly ["WMUX", "WMUX_SURFACE_ID"];
78
+ readonly ownsScreenGrid: true;
79
+ readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
80
+ }, {
81
+ readonly id: "orca";
82
+ readonly precedence: "outerApp";
83
+ readonly sessionEnvKeys: readonly ["ORCA_PANE_KEY", "ORCA_WORKTREE_ID"];
84
+ readonly ownsScreenGrid: false;
85
+ readonly isInside: (env?: NodeJS.ProcessEnv) => boolean;
86
+ }];
87
+ /** Terminal multiplexers omp recognizes. */
88
+ export type TerminalMultiplexer = (typeof registry)[number]["id"];
89
+ /** Every environment variable multiplexer classification reads, including the TERM fallback. */
90
+ export declare const TERMINAL_MULTIPLEXER_ENV_KEYS: readonly string[];
91
+ /**
92
+ * Whether an explicit session marker identifies the current provider.
93
+ *
94
+ * TERM is intentionally excluded: it is a classification fallback, not proof
95
+ * that a particular multiplexer session owns the current grid.
96
+ */
97
+ export declare function hasTerminalMultiplexerSession(multiplexer: TerminalMultiplexer, env?: NodeJS.ProcessEnv): boolean;
98
+ /**
99
+ * Every multiplexer whose explicit session markers are present, in registry
100
+ * order. Nested sessions all appear; TERM is not consulted.
101
+ */
102
+ export declare function terminalMultiplexerSessions(env?: NodeJS.ProcessEnv): TerminalMultiplexerModule<TerminalMultiplexer>[];
103
+ /**
104
+ * The multiplexer TERM names, whether or not its session markers survived.
105
+ * This is classification's TERM fallback; session markers are not consulted.
106
+ */
107
+ export declare function terminalMultiplexerForTerm(env?: NodeJS.ProcessEnv): TerminalMultiplexerModule<TerminalMultiplexer> | undefined;
108
+ /**
109
+ * Registry entry for the multiplexer hosting the current process, or
110
+ * `undefined` for a direct terminal. Same precedence as
111
+ * {@link classifyTerminalMultiplexer}.
112
+ */
113
+ export declare function classifyTerminalMultiplexerModule(env?: NodeJS.ProcessEnv): TerminalMultiplexerModule<TerminalMultiplexer> | undefined;
114
+ /**
115
+ * Classify which terminal multiplexer hosts the current process, or `null` for
116
+ * a direct terminal. Single source of truth for both the render-path gate
8
117
  * (`isInsideTerminalMultiplexer`) and the debug snapshot label.
9
118
  *
10
- * TMUX/STY/ZELLIJ, Herdr, and the CMUX/WMUX workspace/surface/remote-transport
11
- * markers are authoritative session signals. TERM can also survive when those
12
- * are stripped (`sudo` without -E, `su`, env-sanitizing launchers/ssh). Do not
13
- * use CMUX_SOCKET_PATH / WMUX_CLI / WMUX_PIPE here: they are CLI socket/path
14
- * overrides and can be set outside a CMUX/WMUX terminal. wmux is a Windows
15
- * multiplexer (Electron + xterm.js) modeled on cmux/herdr that repaints its
16
- * pane in place and exports WMUX=1 plus a native WMUX_SURFACE_ID.
119
+ * Session markers are authoritative. TERM can also survive when those markers
120
+ * are stripped (`sudo` without -E, `su`, env-sanitizing launchers/ssh), so a
121
+ * `tmux`/`screen` TERM prefix comes next. Outer applications such as Orca rank
122
+ * last so a multiplexer running inside them wins.
17
123
  */
18
124
  export declare function classifyTerminalMultiplexer(env?: NodeJS.ProcessEnv): TerminalMultiplexer | null;
19
- /** True when a terminal multiplexer owns the current screen grid. */
125
+ /** True when the classified multiplexer owns the current screen grid. */
20
126
  export declare function isInsideTerminalMultiplexer(env?: NodeJS.ProcessEnv): boolean;
127
+ /**
128
+ * Offer a notification to every active session's notifier, innermost tier
129
+ * first. Returns whether one delivered it; otherwise the terminal fallback
130
+ * applies unchanged.
131
+ */
132
+ export declare function routeTerminalMultiplexerNotification(request: TerminalMultiplexerNotificationRequest): boolean;
133
+ export {};