@deepseek-harness-tui/dsh-tui 0.11.0 → 0.11.2

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 (484) hide show
  1. package/README.md +55 -20
  2. package/assets/whale-girl/whale-girl-dark.png +0 -0
  3. package/assets/whale-girl/whale-girl-happy.png +0 -0
  4. package/assets/whale-girl/whale-girl.png +0 -0
  5. package/bin/dsh-tui.js +63 -3
  6. package/cordis.patch.yml +43 -20
  7. package/cordis.yml +6 -4
  8. package/lib/settings.json +1272 -0
  9. package/lib/types/activityPrefs.d.ts +24 -0
  10. package/lib/types/activityPrefs.d.ts.map +1 -1
  11. package/lib/types/activityPrefs.js +50 -1
  12. package/lib/types/adapter/channel/state.d.ts.map +1 -1
  13. package/lib/types/adapter/channel/state.js +3 -1
  14. package/lib/types/adapter/channel/ui-policy.d.ts +9 -2
  15. package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
  16. package/lib/types/adapter/channel/ui-policy.js +14 -1
  17. package/lib/types/adapter/kernel/replay.d.ts.map +1 -1
  18. package/lib/types/adapter/kernel/replay.js +2 -0
  19. package/lib/types/adapter/ports/channel-display.d.ts +12 -0
  20. package/lib/types/adapter/ports/channel-display.d.ts.map +1 -1
  21. package/lib/types/adapter/ports/channel-session.d.ts +38 -0
  22. package/lib/types/adapter/ports/channel-session.d.ts.map +1 -1
  23. package/lib/types/adapter/ports/channel-settings.d.ts +12 -0
  24. package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
  25. package/lib/types/adapter/ports/channel-ui.d.ts +53 -7
  26. package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
  27. package/lib/types/adapter/ports/channel-view.d.ts +43 -12
  28. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
  29. package/lib/types/adapter/ports/channel.d.ts +4 -1
  30. package/lib/types/adapter/ports/channel.d.ts.map +1 -1
  31. package/lib/types/commands.d.ts.map +1 -1
  32. package/lib/types/commands.js +2 -0
  33. package/lib/types/components/ActivityLine.d.ts +7 -2
  34. package/lib/types/components/ActivityLine.d.ts.map +1 -1
  35. package/lib/types/components/ActivityLine.js +0 -8
  36. package/lib/types/components/BalanceReportRow.d.ts +10 -2
  37. package/lib/types/components/BalanceReportRow.d.ts.map +1 -1
  38. package/lib/types/components/BalanceReportRow.js +18 -4
  39. package/lib/types/components/CompactionStatusRow.d.ts +24 -0
  40. package/lib/types/components/CompactionStatusRow.d.ts.map +1 -0
  41. package/lib/types/components/CompactionStatusRow.js +72 -0
  42. package/lib/types/components/GoalTodoPanel.js +2 -2
  43. package/lib/types/components/HelpMenu.d.ts +2 -2
  44. package/lib/types/components/HelpMenu.d.ts.map +1 -1
  45. package/lib/types/components/HelpMenu.js +5 -4
  46. package/lib/types/components/InlineMathParagraph.d.ts +22 -0
  47. package/lib/types/components/InlineMathParagraph.d.ts.map +1 -0
  48. package/lib/types/components/InlineMathParagraph.js +178 -0
  49. package/lib/types/components/LogoV2.d.ts +41 -3
  50. package/lib/types/components/LogoV2.d.ts.map +1 -1
  51. package/lib/types/components/LogoV2.js +148 -24
  52. package/lib/types/components/Markdown.d.ts +10 -3
  53. package/lib/types/components/Markdown.d.ts.map +1 -1
  54. package/lib/types/components/Markdown.js +47 -14
  55. package/lib/types/components/MathBlock.d.ts +13 -0
  56. package/lib/types/components/MathBlock.d.ts.map +1 -0
  57. package/lib/types/components/MathBlock.js +136 -0
  58. package/lib/types/components/MessageList.d.ts +10 -1
  59. package/lib/types/components/MessageList.d.ts.map +1 -1
  60. package/lib/types/components/MessageList.js +15 -5
  61. package/lib/types/components/MigratePicker.d.ts +30 -0
  62. package/lib/types/components/MigratePicker.d.ts.map +1 -0
  63. package/lib/types/components/MigratePicker.js +38 -0
  64. package/lib/types/components/PromptInput.d.ts +17 -0
  65. package/lib/types/components/PromptInput.d.ts.map +1 -1
  66. package/lib/types/components/PromptInput.js +96 -9
  67. package/lib/types/components/SplitDiffView.d.ts.map +1 -1
  68. package/lib/types/components/SplitDiffView.js +3 -1
  69. package/lib/types/components/StarPrompt.d.ts +53 -0
  70. package/lib/types/components/StarPrompt.d.ts.map +1 -0
  71. package/lib/types/components/StarPrompt.js +281 -0
  72. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  73. package/lib/types/components/StreamingMarkdown.js +20 -3
  74. package/lib/types/components/SubagentCard.d.ts.map +1 -1
  75. package/lib/types/components/SubagentCard.js +12 -6
  76. package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
  77. package/lib/types/components/SubagentDetailScene.js +8 -3
  78. package/lib/types/components/TimelineRail.d.ts.map +1 -1
  79. package/lib/types/components/TimelineRail.js +9 -1
  80. package/lib/types/components/Whale.d.ts +17 -8
  81. package/lib/types/components/Whale.d.ts.map +1 -1
  82. package/lib/types/components/Whale.js +25 -15
  83. package/lib/types/components/WhaleGirl.d.ts +29 -0
  84. package/lib/types/components/WhaleGirl.d.ts.map +1 -0
  85. package/lib/types/components/WhaleGirl.js +32 -0
  86. package/lib/types/components/WorkingSpinner.d.ts +4 -1
  87. package/lib/types/components/WorkingSpinner.d.ts.map +1 -1
  88. package/lib/types/components/WorkingSpinner.js +2 -2
  89. package/lib/types/components/bigfont.d.ts +47 -18
  90. package/lib/types/components/bigfont.d.ts.map +1 -1
  91. package/lib/types/components/bigfont.js +55 -40
  92. package/lib/types/components/design-system/HintLine.d.ts +1 -2
  93. package/lib/types/components/design-system/HintLine.d.ts.map +1 -1
  94. package/lib/types/components/design-system/HintLine.js +1 -2
  95. package/lib/types/components/design-system/ThemeProvider.d.ts +6 -0
  96. package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
  97. package/lib/types/components/design-system/ThemeProvider.js +40 -1
  98. package/lib/types/components/maidPortrait.d.ts +44 -0
  99. package/lib/types/components/maidPortrait.d.ts.map +1 -0
  100. package/lib/types/components/maidPortrait.js +178 -0
  101. package/lib/types/components/mathPreview.d.ts +25 -0
  102. package/lib/types/components/mathPreview.d.ts.map +1 -0
  103. package/lib/types/components/mathPreview.js +48 -0
  104. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -1
  105. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  106. package/lib/types/components/messages/AssistantThinkingMessage.js +4 -2
  107. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +2 -2
  108. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  109. package/lib/types/components/messages/AssistantToolUseMessage.js +31 -26
  110. package/lib/types/components/messages/TranscriptImages.d.ts.map +1 -1
  111. package/lib/types/components/messages/TranscriptImages.js +11 -1
  112. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +14 -2
  113. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
  114. package/lib/types/components/questions/AskUserQuestionPanel.js +80 -38
  115. package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
  116. package/lib/types/components/questions/PlanReviewPanel.js +3 -3
  117. package/lib/types/components/sessions/ForeignSessionRow.d.ts +34 -0
  118. package/lib/types/components/sessions/ForeignSessionRow.d.ts.map +1 -0
  119. package/lib/types/components/sessions/ForeignSessionRow.js +43 -0
  120. package/lib/types/components/sessions/SourceTabs.d.ts +52 -0
  121. package/lib/types/components/sessions/SourceTabs.d.ts.map +1 -0
  122. package/lib/types/components/sessions/SourceTabs.js +70 -0
  123. package/lib/types/components/splashEggs.d.ts +56 -0
  124. package/lib/types/components/splashEggs.d.ts.map +1 -0
  125. package/lib/types/components/splashEggs.js +67 -0
  126. package/lib/types/components/splashFonts.d.ts +119 -0
  127. package/lib/types/components/splashFonts.d.ts.map +1 -0
  128. package/lib/types/components/splashFonts.js +267 -0
  129. package/lib/types/components/splashLayout.d.ts +41 -0
  130. package/lib/types/components/splashLayout.d.ts.map +1 -0
  131. package/lib/types/components/splashLayout.js +40 -0
  132. package/lib/types/components/whaleGirlSprite.d.ts +17 -0
  133. package/lib/types/components/whaleGirlSprite.d.ts.map +1 -0
  134. package/lib/types/components/whaleGirlSprite.js +47 -0
  135. package/lib/types/deepseekPricing.d.ts +74 -0
  136. package/lib/types/deepseekPricing.d.ts.map +1 -1
  137. package/lib/types/deepseekPricing.js +110 -11
  138. package/lib/types/dsh-adapter/activity-store.d.ts +221 -0
  139. package/lib/types/dsh-adapter/activity-store.d.ts.map +1 -0
  140. package/lib/types/dsh-adapter/activity-store.js +359 -0
  141. package/lib/types/dsh-adapter/channel/action-readiness.d.ts +1 -1
  142. package/lib/types/dsh-adapter/channel/action-readiness.d.ts.map +1 -1
  143. package/lib/types/dsh-adapter/channel/action-readiness.js +6 -1
  144. package/lib/types/dsh-adapter/channel/background-action.d.ts +2 -1
  145. package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -1
  146. package/lib/types/dsh-adapter/channel/background-action.js +2 -0
  147. package/lib/types/dsh-adapter/channel/binding-events.d.ts +15 -14
  148. package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
  149. package/lib/types/dsh-adapter/channel/binding-events.js +70 -21
  150. package/lib/types/dsh-adapter/channel/compaction.d.ts +2 -2
  151. package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
  152. package/lib/types/dsh-adapter/channel/compaction.js +35 -4
  153. package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -1
  154. package/lib/types/dsh-adapter/channel/local-actions.js +6 -1
  155. package/lib/types/dsh-adapter/channel/model-switch.d.ts +1 -2
  156. package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -1
  157. package/lib/types/dsh-adapter/channel/model-switch.js +6 -2
  158. package/lib/types/dsh-adapter/channel/paths.d.ts.map +1 -1
  159. package/lib/types/dsh-adapter/channel/paths.js +7 -1
  160. package/lib/types/dsh-adapter/channel/preferences.d.ts +1 -1
  161. package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -1
  162. package/lib/types/dsh-adapter/channel/preferences.js +16 -0
  163. package/lib/types/dsh-adapter/channel/projection.d.ts +1 -2
  164. package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
  165. package/lib/types/dsh-adapter/channel/projection.js +127 -17
  166. package/lib/types/dsh-adapter/channel/question-record.d.ts +76 -0
  167. package/lib/types/dsh-adapter/channel/question-record.d.ts.map +1 -0
  168. package/lib/types/dsh-adapter/channel/question-record.js +107 -0
  169. package/lib/types/dsh-adapter/channel/session-adoption.d.ts +1 -1
  170. package/lib/types/dsh-adapter/channel/session-adoption.d.ts.map +1 -1
  171. package/lib/types/dsh-adapter/channel/session-adoption.js +1 -0
  172. package/lib/types/dsh-adapter/channel/session-lineage.d.ts +42 -0
  173. package/lib/types/dsh-adapter/channel/session-lineage.d.ts.map +1 -0
  174. package/lib/types/dsh-adapter/channel/session-lineage.js +51 -0
  175. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +3 -1
  176. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -1
  177. package/lib/types/dsh-adapter/channel/session-live-adoption.js +10 -3
  178. package/lib/types/dsh-adapter/channel/session-metadata.d.ts +2 -1
  179. package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
  180. package/lib/types/dsh-adapter/channel/session-metadata.js +43 -9
  181. package/lib/types/dsh-adapter/channel/session-reset.d.ts +1 -1
  182. package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -1
  183. package/lib/types/dsh-adapter/channel/session-reset.js +7 -1
  184. package/lib/types/dsh-adapter/channel/session-resume.d.ts +2 -1
  185. package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
  186. package/lib/types/dsh-adapter/channel/session-resume.js +5 -2
  187. package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
  188. package/lib/types/dsh-adapter/channel/settings-host.js +8 -0
  189. package/lib/types/dsh-adapter/channel/state.d.ts +19 -1
  190. package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
  191. package/lib/types/dsh-adapter/channel/state.js +8 -3
  192. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +32 -17
  193. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
  194. package/lib/types/dsh-adapter/channel/subagent-projection.js +309 -8
  195. package/lib/types/dsh-adapter/channel/types.d.ts +1 -1
  196. package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -1
  197. package/lib/types/dsh-adapter/channel.d.ts +1 -1
  198. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  199. package/lib/types/dsh-adapter/channel.js +34 -18
  200. package/lib/types/dsh-adapter/compat/index.d.ts +1 -1
  201. package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -1
  202. package/lib/types/dsh-adapter/compat/index.js +1 -1
  203. package/lib/types/dsh-adapter/compat/messages.d.ts +6 -0
  204. package/lib/types/dsh-adapter/compat/messages.d.ts.map +1 -1
  205. package/lib/types/dsh-adapter/compat/messages.js +9 -0
  206. package/lib/types/dsh-adapter/compat/sessionLog.d.ts +18 -0
  207. package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -1
  208. package/lib/types/dsh-adapter/compat/sessionLog.js +18 -3
  209. package/lib/types/dsh-adapter/compat/settings.d.ts +2 -0
  210. package/lib/types/dsh-adapter/compat/settings.d.ts.map +1 -1
  211. package/lib/types/dsh-adapter/compat/settings.js +14 -0
  212. package/lib/types/dsh-adapter/contract.d.ts +5 -4
  213. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  214. package/lib/types/dsh-adapter/contract.js +9 -5
  215. package/lib/types/dsh-adapter/index.d.ts +36 -1
  216. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  217. package/lib/types/dsh-adapter/index.js +22 -6
  218. package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts +3 -0
  219. package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts.map +1 -0
  220. package/lib/types/dsh-adapter/migrate/adapters/claude-code.js +131 -0
  221. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.d.ts +17 -0
  222. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.d.ts.map +1 -0
  223. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.js +329 -0
  224. package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts +3 -0
  225. package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts.map +1 -0
  226. package/lib/types/dsh-adapter/migrate/adapters/codex.js +102 -0
  227. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.d.ts +16 -0
  228. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.d.ts.map +1 -0
  229. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.js +289 -0
  230. package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts +3 -0
  231. package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts.map +1 -0
  232. package/lib/types/dsh-adapter/migrate/adapters/grok-build.js +117 -0
  233. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.d.ts +13 -0
  234. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.d.ts.map +1 -0
  235. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.js +178 -0
  236. package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts +3 -0
  237. package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts.map +1 -0
  238. package/lib/types/dsh-adapter/migrate/adapters/omp.js +133 -0
  239. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.d.ts +60 -0
  240. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.d.ts.map +1 -0
  241. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.js +178 -0
  242. package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts +8 -0
  243. package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts.map +1 -0
  244. package/lib/types/dsh-adapter/migrate/adapters/scan.js +40 -0
  245. package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts +3 -0
  246. package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts.map +1 -0
  247. package/lib/types/dsh-adapter/migrate/adapters/zcode.js +93 -0
  248. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.d.ts +9 -0
  249. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.d.ts.map +1 -0
  250. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.js +89 -0
  251. package/lib/types/dsh-adapter/migrate/bin-path.d.ts +6 -0
  252. package/lib/types/dsh-adapter/migrate/bin-path.d.ts.map +1 -0
  253. package/lib/types/dsh-adapter/migrate/bin-path.js +30 -0
  254. package/lib/types/dsh-adapter/migrate/browse.d.ts +42 -0
  255. package/lib/types/dsh-adapter/migrate/browse.d.ts.map +1 -0
  256. package/lib/types/dsh-adapter/migrate/browse.js +90 -0
  257. package/lib/types/dsh-adapter/migrate/cli.d.ts +9 -0
  258. package/lib/types/dsh-adapter/migrate/cli.d.ts.map +1 -0
  259. package/lib/types/dsh-adapter/migrate/cli.js +106 -0
  260. package/lib/types/dsh-adapter/migrate/import-one.d.ts +89 -0
  261. package/lib/types/dsh-adapter/migrate/import-one.d.ts.map +1 -0
  262. package/lib/types/dsh-adapter/migrate/import-one.js +133 -0
  263. package/lib/types/dsh-adapter/migrate/index.d.ts +35 -0
  264. package/lib/types/dsh-adapter/migrate/index.d.ts.map +1 -0
  265. package/lib/types/dsh-adapter/migrate/index.js +107 -0
  266. package/lib/types/dsh-adapter/migrate/parse/injection.d.ts +40 -0
  267. package/lib/types/dsh-adapter/migrate/parse/injection.d.ts.map +1 -0
  268. package/lib/types/dsh-adapter/migrate/parse/injection.js +127 -0
  269. package/lib/types/dsh-adapter/migrate/parse/jsonl.d.ts +28 -0
  270. package/lib/types/dsh-adapter/migrate/parse/jsonl.d.ts.map +1 -0
  271. package/lib/types/dsh-adapter/migrate/parse/jsonl.js +40 -0
  272. package/lib/types/dsh-adapter/migrate/parse/role-turns.d.ts +28 -0
  273. package/lib/types/dsh-adapter/migrate/parse/role-turns.d.ts.map +1 -0
  274. package/lib/types/dsh-adapter/migrate/parse/role-turns.js +50 -0
  275. package/lib/types/dsh-adapter/migrate/parse/title.d.ts +18 -0
  276. package/lib/types/dsh-adapter/migrate/parse/title.d.ts.map +1 -0
  277. package/lib/types/dsh-adapter/migrate/parse/title.js +29 -0
  278. package/lib/types/dsh-adapter/migrate/parse/tools.d.ts +62 -0
  279. package/lib/types/dsh-adapter/migrate/parse/tools.d.ts.map +1 -0
  280. package/lib/types/dsh-adapter/migrate/parse/tools.js +110 -0
  281. package/lib/types/dsh-adapter/migrate/picker.d.ts +64 -0
  282. package/lib/types/dsh-adapter/migrate/picker.d.ts.map +1 -0
  283. package/lib/types/dsh-adapter/migrate/picker.js +86 -0
  284. package/lib/types/dsh-adapter/migrate/recent-agents.d.ts +40 -0
  285. package/lib/types/dsh-adapter/migrate/recent-agents.d.ts.map +1 -0
  286. package/lib/types/dsh-adapter/migrate/recent-agents.js +100 -0
  287. package/lib/types/dsh-adapter/migrate/sessionize.d.ts +39 -0
  288. package/lib/types/dsh-adapter/migrate/sessionize.d.ts.map +1 -0
  289. package/lib/types/dsh-adapter/migrate/sessionize.js +271 -0
  290. package/lib/types/dsh-adapter/migrate/types.d.ts +176 -0
  291. package/lib/types/dsh-adapter/migrate/types.d.ts.map +1 -0
  292. package/lib/types/dsh-adapter/migrate/types.js +11 -0
  293. package/lib/types/dsh-adapter/migrate/uuid.d.ts +7 -0
  294. package/lib/types/dsh-adapter/migrate/uuid.d.ts.map +1 -0
  295. package/lib/types/dsh-adapter/migrate/uuid.js +25 -0
  296. package/lib/types/dsh-adapter/plugin.d.ts +5 -3
  297. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  298. package/lib/types/dsh-adapter/plugin.js +168 -372
  299. package/lib/types/dsh-adapter/providerWizard.d.ts +17 -0
  300. package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -1
  301. package/lib/types/dsh-adapter/providerWizard.js +254 -66
  302. package/lib/types/dsh-adapter/questions.d.ts +22 -15
  303. package/lib/types/dsh-adapter/questions.d.ts.map +1 -1
  304. package/lib/types/dsh-adapter/questions.js +47 -45
  305. package/lib/types/dsh-adapter/sessions/digest.d.ts +11 -6
  306. package/lib/types/dsh-adapter/sessions/digest.d.ts.map +1 -1
  307. package/lib/types/dsh-adapter/sessions/digest.js +20 -13
  308. package/lib/types/dsh-adapter/sessions/frames.d.ts +3 -1
  309. package/lib/types/dsh-adapter/sessions/frames.d.ts.map +1 -1
  310. package/lib/types/dsh-adapter/sessions/frames.js +5 -4
  311. package/lib/types/dsh-adapter/sessions/list.d.ts +6 -1
  312. package/lib/types/dsh-adapter/sessions/list.d.ts.map +1 -1
  313. package/lib/types/dsh-adapter/sessions/list.js +188 -164
  314. package/lib/types/dsh-adapter/sessions/recovery.d.ts +16 -0
  315. package/lib/types/dsh-adapter/sessions/recovery.d.ts.map +1 -0
  316. package/lib/types/dsh-adapter/sessions/recovery.js +108 -0
  317. package/lib/types/dsh-adapter/sessions/snapshot.d.ts +7 -0
  318. package/lib/types/dsh-adapter/sessions/snapshot.d.ts.map +1 -0
  319. package/lib/types/dsh-adapter/sessions/snapshot.js +90 -0
  320. package/lib/types/dsh-adapter/sessions/store.d.ts +10 -4
  321. package/lib/types/dsh-adapter/sessions/store.d.ts.map +1 -1
  322. package/lib/types/dsh-adapter/sessions/store.js +62 -25
  323. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
  324. package/lib/types/dsh-adapter/settings-sections.js +7 -4
  325. package/lib/types/dsh-adapter/sideQuestion.d.ts +41 -2
  326. package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -1
  327. package/lib/types/dsh-adapter/sideQuestion.js +98 -2
  328. package/lib/types/dsh-adapter/subagents.d.ts +44 -6
  329. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
  330. package/lib/types/dsh-adapter/subagents.js +163 -26
  331. package/lib/types/herdr.d.ts +2 -0
  332. package/lib/types/herdr.d.ts.map +1 -1
  333. package/lib/types/herdr.js +9 -3
  334. package/lib/types/history.d.ts +13 -1
  335. package/lib/types/history.d.ts.map +1 -1
  336. package/lib/types/history.js +15 -2
  337. package/lib/types/i18n.d.ts +512 -41
  338. package/lib/types/i18n.d.ts.map +1 -1
  339. package/lib/types/i18n.js +199 -20
  340. package/lib/types/ink/components/App.d.ts +2 -2
  341. package/lib/types/ink/components/App.d.ts.map +1 -1
  342. package/lib/types/ink/components/App.js +5 -1
  343. package/lib/types/ink/components/Image.d.ts +14 -1
  344. package/lib/types/ink/components/Image.d.ts.map +1 -1
  345. package/lib/types/ink/components/Image.js +2 -2
  346. package/lib/types/ink/events/input-event.js +3 -3
  347. package/lib/types/ink/hooks/use-terminal-images.d.ts +12 -0
  348. package/lib/types/ink/hooks/use-terminal-images.d.ts.map +1 -1
  349. package/lib/types/ink/hooks/use-terminal-images.js +13 -0
  350. package/lib/types/ink/ink.d.ts +6 -0
  351. package/lib/types/ink/ink.d.ts.map +1 -1
  352. package/lib/types/ink/ink.js +16 -1
  353. package/lib/types/ink/kitty-graphics.d.ts +44 -3
  354. package/lib/types/ink/kitty-graphics.d.ts.map +1 -1
  355. package/lib/types/ink/kitty-graphics.js +184 -23
  356. package/lib/types/ink/log-update.d.ts.map +1 -1
  357. package/lib/types/ink/log-update.js +19 -1
  358. package/lib/types/ink/output.d.ts +24 -2
  359. package/lib/types/ink/output.d.ts.map +1 -1
  360. package/lib/types/ink/output.js +83 -5
  361. package/lib/types/ink/parse-keypress.d.ts +26 -1
  362. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  363. package/lib/types/ink/parse-keypress.js +156 -13
  364. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  365. package/lib/types/ink/render-node-to-output.js +8 -1
  366. package/lib/types/ink/screen.d.ts +24 -0
  367. package/lib/types/ink/screen.d.ts.map +1 -1
  368. package/lib/types/ink/screen.js +89 -0
  369. package/lib/types/ink/selection.d.ts +68 -18
  370. package/lib/types/ink/selection.d.ts.map +1 -1
  371. package/lib/types/ink/selection.js +178 -31
  372. package/lib/types/ink/sixel-codec.d.ts +12 -1
  373. package/lib/types/ink/sixel-codec.d.ts.map +1 -1
  374. package/lib/types/ink/sixel-codec.js +29 -5
  375. package/lib/types/ink/sixel-graphics.d.ts.map +1 -1
  376. package/lib/types/ink/sixel-graphics.js +5 -3
  377. package/lib/types/ink/styles.d.ts +9 -0
  378. package/lib/types/ink/styles.d.ts.map +1 -1
  379. package/lib/types/ink/terminal-image.d.ts +8 -0
  380. package/lib/types/ink/terminal-image.d.ts.map +1 -1
  381. package/lib/types/ink/terminal-querier.d.ts +7 -1
  382. package/lib/types/ink/terminal-querier.d.ts.map +1 -1
  383. package/lib/types/ink/terminal-querier.js +12 -2
  384. package/lib/types/ink/timeline-rail.d.ts +5 -0
  385. package/lib/types/ink/timeline-rail.d.ts.map +1 -1
  386. package/lib/types/math/inline-layout.d.ts +29 -0
  387. package/lib/types/math/inline-layout.d.ts.map +1 -0
  388. package/lib/types/math/inline-layout.js +106 -0
  389. package/lib/types/math/layout.d.ts +58 -0
  390. package/lib/types/math/layout.d.ts.map +1 -0
  391. package/lib/types/math/layout.js +59 -0
  392. package/lib/types/math/renderer.d.ts +64 -0
  393. package/lib/types/math/renderer.d.ts.map +1 -0
  394. package/lib/types/math/renderer.js +256 -0
  395. package/lib/types/screens/Chat.d.ts +17 -1
  396. package/lib/types/screens/Chat.d.ts.map +1 -1
  397. package/lib/types/screens/Chat.js +618 -57
  398. package/lib/types/screens/SessionSupervisor.d.ts +2 -1
  399. package/lib/types/screens/SessionSupervisor.d.ts.map +1 -1
  400. package/lib/types/screens/SessionSupervisor.js +156 -19
  401. package/lib/types/screens/Settings.d.ts.map +1 -1
  402. package/lib/types/screens/Settings.js +49 -11
  403. package/lib/types/screens/StatusLine.d.ts +5 -1
  404. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  405. package/lib/types/screens/StatusLine.js +47 -17
  406. package/lib/types/screens/chatOverlay.d.ts +5 -0
  407. package/lib/types/screens/chatOverlay.d.ts.map +1 -1
  408. package/lib/types/screens/chatOverlay.js +1 -0
  409. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.d.ts +47 -0
  410. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.d.ts.map +1 -0
  411. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.js +65 -0
  412. package/lib/types/screens/sessionSupervisor/model.d.ts +12 -0
  413. package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -1
  414. package/lib/types/screens/sessionSupervisor/model.js +26 -0
  415. package/lib/types/screens/sessionSupervisor/useForeignSessions.d.ts +107 -0
  416. package/lib/types/screens/sessionSupervisor/useForeignSessions.d.ts.map +1 -0
  417. package/lib/types/screens/sessionSupervisor/useForeignSessions.js +312 -0
  418. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts +4 -1
  419. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -1
  420. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +97 -14
  421. package/lib/types/sessionHistory.d.ts +2 -2
  422. package/lib/types/sessionHistory.d.ts.map +1 -1
  423. package/lib/types/sessionHistory.js +31 -5
  424. package/lib/types/settings/definitions.d.ts +681 -0
  425. package/lib/types/settings/definitions.d.ts.map +1 -0
  426. package/lib/types/settings/definitions.js +511 -0
  427. package/lib/types/starAction.d.ts +44 -0
  428. package/lib/types/starAction.d.ts.map +1 -0
  429. package/lib/types/starAction.js +52 -0
  430. package/lib/types/terminal-utils/latex.d.ts +10 -0
  431. package/lib/types/terminal-utils/latex.d.ts.map +1 -0
  432. package/lib/types/terminal-utils/latex.js +1417 -0
  433. package/lib/types/terminal-utils/markdown.d.ts +3 -1
  434. package/lib/types/terminal-utils/markdown.d.ts.map +1 -1
  435. package/lib/types/terminal-utils/markdown.js +26 -1
  436. package/lib/types/terminal-utils/math.d.ts +66 -0
  437. package/lib/types/terminal-utils/math.d.ts.map +1 -0
  438. package/lib/types/terminal-utils/math.js +337 -0
  439. package/lib/types/tips.d.ts.map +1 -1
  440. package/lib/types/tips.js +6 -0
  441. package/lib/types/tuiDisplayPrefs.d.ts +67 -0
  442. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
  443. package/lib/types/tuiDisplayPrefs.js +59 -0
  444. package/lib/types/ui.d.ts +1 -1
  445. package/lib/types/ui.d.ts.map +1 -1
  446. package/lib/types/ui.js +1 -1
  447. package/lib/types/usageStats.d.ts +98 -0
  448. package/lib/types/usageStats.d.ts.map +1 -0
  449. package/lib/types/usageStats.js +169 -0
  450. package/lib/types/utils/bmp.d.ts +17 -0
  451. package/lib/types/utils/bmp.d.ts.map +1 -0
  452. package/lib/types/utils/bmp.js +154 -0
  453. package/lib/types/utils/clipboard.d.ts +14 -2
  454. package/lib/types/utils/clipboard.d.ts.map +1 -1
  455. package/lib/types/utils/clipboard.js +143 -8
  456. package/lib/types/utils/fold-long-lines.d.ts +1 -1
  457. package/lib/types/utils/fold-long-lines.d.ts.map +1 -1
  458. package/lib/types/utils/fold-long-lines.js +3 -2
  459. package/lib/types/utils/keymap.d.ts +4 -1
  460. package/lib/types/utils/keymap.d.ts.map +1 -1
  461. package/lib/types/utils/keymap.js +8 -0
  462. package/lib/types/utils/modifiers.d.ts +4 -3
  463. package/lib/types/utils/modifiers.d.ts.map +1 -1
  464. package/lib/types/utils/modifiers.js +4 -3
  465. package/lib/types/working-activity.d.ts +10 -9
  466. package/lib/types/working-activity.d.ts.map +1 -1
  467. package/lib/types/working-activity.js +17 -10
  468. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/LICENSE +202 -0
  469. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/NOTICE +20 -0
  470. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/index.d.ts +16 -0
  471. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/bundled-packages.json +4 -0
  472. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/index.mjs +20 -0
  473. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/index.mjs.LEGAL.txt +35 -0
  474. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/package.json +29 -0
  475. package/package.json +117 -99
  476. package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +0 -19
  477. package/lib/types/components/design-system/KeyboardShortcutHint.d.ts.map +0 -1
  478. package/lib/types/components/design-system/KeyboardShortcutHint.js +0 -14
  479. package/lib/types/dsh-adapter/channel/activity.d.ts +0 -20
  480. package/lib/types/dsh-adapter/channel/activity.d.ts.map +0 -1
  481. package/lib/types/dsh-adapter/channel/activity.js +0 -113
  482. package/lib/types/terminal-utils/terminal.d.ts +0 -18
  483. package/lib/types/terminal-utils/terminal.d.ts.map +0 -1
  484. package/lib/types/terminal-utils/terminal.js +0 -96
@@ -3,6 +3,7 @@ import { SpinnerGlyph } from '../components/Spinner/SpinnerGlyph.js';
3
3
  import type { ApprovalSnapshot } from '../dsh-adapter/approvals.js';
4
4
  import type { TuiWorkspaceTarget } from '../workspaces.js';
5
5
  import type { ChannelUi as Channel } from '../adapter/channel/ui-policy.js';
6
+ import type { ResumeResult } from '../adapter/ports/channel-view.js';
6
7
  import { SupervisorLiveState, sessionMatchesQuery } from './sessionSupervisor/model.js';
7
8
  export { sessionMatchesQuery };
8
9
  /**
@@ -40,7 +41,7 @@ export declare function SessionSupervisor({ channel, home, onClose, onOpenSessio
40
41
  /** Leave the screen and show the conversation. */
41
42
  onClose(): void;
42
43
  /** Mount a persisted session (the channel's unified resume path). */
43
- onOpenSession(sessionId: string): Promise<boolean>;
44
+ onOpenSession(sessionId: string): Promise<ResumeResult>;
44
45
  /** Start a fresh session in the workspace at `path`. */
45
46
  onNewSession(target: TuiWorkspaceTarget): Promise<boolean>;
46
47
  /** Stop a background session of this terminal; false when it is not ours. */
@@ -1 +1 @@
1
- {"version":3,"file":"SessionSupervisor.d.ts","sourceRoot":"","sources":["../../../src/screens/SessionSupervisor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAA;AAarE,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAA;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AASnE,OAAO,KAAK,EAAqB,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAC7E,OAAO,KAAK,EAAE,SAAS,IAAI,OAAO,EAAE,MAAM,iCAAiC,CAAA;AAE3E,OAAO,EAAkN,mBAAmB,EAAsD,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAC3V,OAAO,EAAE,mBAAmB,EAAE,CAAA;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,IAAI,EACJ,OAAO,EACP,aAAa,EACb,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,SAAS,EACT,WAAW,GACZ,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAA;IACZ,kDAAkD;IAClD,OAAO,IAAI,IAAI,CAAA;IACf,qEAAqE;IACrE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAClD,wDAAwD;IACxD,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC1D,6EAA6E;IAC7E,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAClD;;;;OAIG;IACH,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACjC,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,UAAU,GAAG,IAAI,CAAA;IACrD;;;;OAIG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAAA;CAChE,GAAG,KAAK,CAAC,SAAS,CA8hBlB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOzF;AAED,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"SessionSupervisor.d.ts","sourceRoot":"","sources":["../../../src/screens/SessionSupervisor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAA;AAarE,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAA;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AASnE,OAAO,KAAK,EAAqB,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAC7E,OAAO,KAAK,EAAE,SAAS,IAAI,OAAO,EAAE,MAAM,iCAAiC,CAAA;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAMpE,OAAO,EAAkN,mBAAmB,EAAsD,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAC3V,OAAO,EAAE,mBAAmB,EAAE,CAAA;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,IAAI,EACJ,OAAO,EACP,aAAa,EACb,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,SAAS,EACT,WAAW,GACZ,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAA;IACZ,kDAAkD;IAClD,OAAO,IAAI,IAAI,CAAA;IACf,qEAAqE;IACrE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IACvD,wDAAwD;IACxD,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC1D,6EAA6E;IAC7E,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAClD;;;;OAIG;IACH,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACjC,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,UAAU,GAAG,IAAI,CAAA;IACrD;;;;OAIG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAAA;CAChE,GAAG,KAAK,CAAC,SAAS,CA2tBlB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOzF;AAED,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React from 'react';
2
+ import React, { useCallback, useMemo, useRef, useState } from 'react';
3
3
  import { Box, Text, useInput, useTerminalSize } from '../ui.js';
4
4
  import { t } from '../i18n.js';
5
5
  import { Divider } from '../components/design-system/Divider.js';
@@ -15,6 +15,10 @@ import { useAnimationFrame } from '../ink/hooks/use-animation-frame.js';
15
15
  import { isPlainReturn, isMod } from '../utils/modifiers.js';
16
16
  import { truncateWidth } from '../sessions/format.js';
17
17
  import { useSessionSupervisor } from './sessionSupervisor/useSessionSupervisor.js';
18
+ import { DSH_TAB, useForeignSessions } from './sessionSupervisor/useForeignSessions.js';
19
+ import { ForeignSessionPanes } from './sessionSupervisor/ForeignSessionPanes.js';
20
+ import { SourceTabs, layoutSourceTabs, sourceTabsWidth } from '../components/sessions/SourceTabs.js';
21
+ import { stringWidth } from '../ink/stringWidth.js';
18
22
  import { SESSION_ROW_LINES, MENU_ACTIONS, MENU_WIDTH, MENU_HEIGHT, MENU_LABEL_KEYS, samePath, sessionMatchesQuery } from './sessionSupervisor/model.js';
19
23
  export { sessionMatchesQuery };
20
24
  /**
@@ -49,7 +53,54 @@ export function SessionSupervisor({ channel, home, onClose, onOpenSession, onNew
49
53
  const { columns, rows } = useTerminalSize();
50
54
  const inset = React.useContext(PageInsetContext);
51
55
  const isTerminalFocused = useTerminalFocus();
52
- const { entries, sessions, loading, notice, setNotice, query, setQuery, holderOf, listedSessions, railEntries, countOf, railFocus, setRailFocus, setFocusSessionId, activePane, pins, menu, setMenu, rename, setRename, confirmRemove, setConfirmRemove, railRef, menuRef, queryRef, now, reload, selected, visibleSessions, sessionIndex, cardFocused, sessionAt, activateList, activateRail, railWidth, railVisible, sessionWidth, railEntryCapacity, sessionListHeight, persistPin, selectEntry, openSession, newSessionIn, renameEntry, removeEntry, stopSession, closeMenu, activateMenu, moveRail, moveSession, focusedSession, } = useSessionSupervisor({ channel, home, onOpenSession, onNewSession, onStopSession, liveStateOf, columns, rows });
56
+ const { entries, sessions, loading, refreshing, notice, setNotice, query, setQuery, holderOf, listedSessions, railEntries, countOf, railFocus, setRailFocus, setFocusSessionId, activePane, pins, menu, setMenu, rename, setRename, confirmRemove, setConfirmRemove, railRef, menuRef, queryRef, now, reload, selected, visibleSessions, sessionIndex, cardFocused, sessionAt, activateList, activateRail, railWidth, railVisible, sessionWidth, railEntryCapacity, sessionListHeight, noticeRows, persistPin, selectEntry, openSession, newSessionIn, renameEntry, removeEntry, stopSession, closeMenu, activateMenu, moveRail, moveSession, focusedSession, } = useSessionSupervisor({ channel, home, onOpenSession, onNewSession, onStopSession, liveStateOf, columns, rows });
57
+ /**
58
+ * The source tab: this screen's own sessions ({@link DSH_TAB}) or another
59
+ * coding agent's, by agent id. Every open starts on DSH — the screen is
60
+ * where you manage your sessions first, and a foreign tab is a place you
61
+ * visit.
62
+ */
63
+ const [tab, setTab] = useState(DSH_TAB);
64
+ /** The `+N` dropdown of folded tabs, anchored where it was clicked. */
65
+ const [tabMenu, setTabMenu] = useState(undefined);
66
+ const tabMenuRef = useRef(tabMenu);
67
+ tabMenuRef.current = tabMenu;
68
+ const foreign = useForeignSessions({ channel, tab, registry: entries, query, setNotice, onOpenSession });
69
+ /**
70
+ * Only sources with data get a tab, after DSH, in a fixed order: ranking
71
+ * them by recency would mean stat-ing every conversation of every source
72
+ * each time this screen opens.
73
+ */
74
+ const tabs = useMemo(() => {
75
+ if (foreign.sources.length === 0)
76
+ return [];
77
+ return [{ id: DSH_TAB, label: 'DSH' }, ...foreign.sources.map(source => ({ id: source.agentId, label: source.label }))];
78
+ }, [foreign.sources]);
79
+ const activeSource = foreign.sources.find(source => source.agentId === tab);
80
+ // A source that vanished on refresh takes its tab with it; land on DSH
81
+ // rather than on a tab the strip no longer draws.
82
+ React.useEffect(() => {
83
+ if (tab !== DSH_TAB && activeSource === undefined)
84
+ setTab(DSH_TAB);
85
+ }, [tab, activeSource]);
86
+ const closeTabMenu = useCallback(() => {
87
+ tabMenuRef.current = undefined;
88
+ setTabMenu(undefined);
89
+ }, []);
90
+ /** Switch source. The query and notice belong to the tab they were made on. */
91
+ const switchTab = useCallback((id) => {
92
+ closeMenu();
93
+ closeTabMenu();
94
+ setQuery('');
95
+ setNotice(undefined);
96
+ setTab(id);
97
+ }, [closeMenu, closeTabMenu, setQuery, setNotice]);
98
+ const cycleTab = useCallback((by) => {
99
+ if (tabs.length < 2)
100
+ return;
101
+ const index = Math.max(0, tabs.findIndex(candidate => candidate.id === tab));
102
+ switchTab(tabs[(index + by + tabs.length) % tabs.length].id);
103
+ }, [tabs, tab, switchTab]);
53
104
  useInput((input, key) => {
54
105
  // Modal layers own the keyboard, in the same order they render.
55
106
  if (rename !== undefined) {
@@ -109,6 +160,26 @@ export function SessionSupervisor({ channel, home, onClose, onOpenSession, onNew
109
160
  }
110
161
  return;
111
162
  }
163
+ if (tabMenuRef.current !== undefined) {
164
+ const current = tabMenuRef.current;
165
+ const count = Math.max(1, tabLayout.hidden.length);
166
+ if (key.upArrow || key.downArrow) {
167
+ const next = { ...current, item: (current.item + (key.upArrow ? count - 1 : 1)) % count };
168
+ tabMenuRef.current = next;
169
+ setTabMenu(next);
170
+ }
171
+ else if (isPlainReturn(key)) {
172
+ const target = tabLayout.hidden[current.item];
173
+ if (target !== undefined)
174
+ switchTab(target.id);
175
+ else
176
+ closeTabMenu();
177
+ }
178
+ else {
179
+ closeTabMenu();
180
+ }
181
+ return;
182
+ }
112
183
  if (key.escape) {
113
184
  if (notice !== undefined) {
114
185
  setNotice(undefined);
@@ -122,17 +193,14 @@ export function SessionSupervisor({ channel, home, onClose, onOpenSession, onNew
122
193
  return;
123
194
  }
124
195
  if (key.tab) {
125
- // Shift+Tab keeps the keyboard route to the focused workspace's action
126
- // menu. Plain Tab does nothing here: panes are chosen with ←/→ now, and
127
- // Tab is the composer's business.
128
- if (key.shift && activePane === 'rail') {
129
- const entry = railEntries[railRef.current];
130
- if (entry !== undefined) {
131
- const next = { path: entry.path, ...keyboardMenuAnchor, item: 0 };
132
- menuRef.current = next;
133
- setMenu(next);
134
- }
135
- }
196
+ // Tab / Shift+Tab walk the source tabs. Shift+Tab used to open the
197
+ // focused workspace's menu, which Enter on the rail already does, so
198
+ // the route was given up to the tabs.
199
+ cycleTab(key.shift ? -1 : 1);
200
+ return;
201
+ }
202
+ if (tab !== DSH_TAB) {
203
+ foreignKey(input, key);
136
204
  return;
137
205
  }
138
206
  // ←/→ choose the column. There is exactly one `❯` on screen because exactly
@@ -235,6 +303,67 @@ export function SessionSupervisor({ channel, home, onClose, onOpenSession, onNew
235
303
  const workingCount = listedSessions.filter(session => liveStateOf(session.id)?.status === 'working').length;
236
304
  const [, spinnerTime] = useAnimationFrame(workingCount > 0 ? 120 : null);
237
305
  const spinnerFrame = Math.floor(spinnerTime / 120);
306
+ /**
307
+ * Keys on a source tab: the same pane model as DSH (←/→ pick the column,
308
+ * ↑/↓ move, typing filters), with what a foreign source cannot do left out —
309
+ * no workspace menu, no new session, no stop — and Ctrl+L rescanning the
310
+ * source instead of re-listing.
311
+ */
312
+ function foreignKey(input, key) {
313
+ if (key.leftArrow) {
314
+ foreign.activateRail();
315
+ return;
316
+ }
317
+ if (key.rightArrow) {
318
+ foreign.activateList();
319
+ return;
320
+ }
321
+ const by = key.upArrow || key.wheelUp || key.pageUp ? -1 : key.downArrow || key.wheelDown || key.pageDown ? 1 : 0;
322
+ if (by !== 0) {
323
+ if (foreign.pane === 'rail')
324
+ foreign.moveRail(by);
325
+ else
326
+ foreign.moveList(by);
327
+ return;
328
+ }
329
+ if (key.backspace || key.delete) {
330
+ setQuery(text => text.slice(0, -1));
331
+ return;
332
+ }
333
+ if (isMod(key) && input === 'l') {
334
+ foreign.rescan();
335
+ return;
336
+ }
337
+ if (isMod(key))
338
+ return;
339
+ if (isPlainReturn(key)) {
340
+ // The rail has no menu here, so Enter on it steps into the list.
341
+ if (foreign.pane === 'rail')
342
+ foreign.activateList();
343
+ else if (foreign.focusedRow !== undefined)
344
+ foreign.openRow(foreign.focusedRow);
345
+ return;
346
+ }
347
+ if (!key.meta && !key.super && input && !key.return) {
348
+ const typed = input.replace(/\p{Cc}/gu, '');
349
+ if (typed.length > 0)
350
+ setQuery(text => text + typed);
351
+ }
352
+ }
353
+ // Header: title, subtitle, and the source strip on the right. Width runs
354
+ // out in a fixed order — the subtitle goes first, then trailing tabs fold
355
+ // into `+N`; the active tab never folds.
356
+ const titleText = ` ▣ ${t('supervisor-title')}`;
357
+ const subtitleText = ` ${t('supervisor-subtitle')}`;
358
+ /** One column between title and strip, one after the strip. */
359
+ const HEADER_GAPS = 2;
360
+ const fullStrip = tabs.length === 0 ? 0 : sourceTabsWidth(tabs, 0, DSH_TAB);
361
+ const showSubtitle = tabs.length === 0
362
+ || stringWidth(titleText) + stringWidth(subtitleText) + HEADER_GAPS + fullStrip <= columns;
363
+ const tabBudget = columns - stringWidth(titleText) - (showSubtitle ? stringWidth(subtitleText) : 0) - HEADER_GAPS;
364
+ const tabLayout = layoutSourceTabs(tabs, tab, tabBudget);
365
+ const tabMenuWidth = Math.max(12, ...tabLayout.hidden.map(hidden => stringWidth(hidden.label) + 6));
366
+ const withTabHint = (text) => (tabs.length === 0 ? text : `${text} · ${t('supervisor-hint-tabs')}`);
238
367
  const railHint = rename !== undefined
239
368
  ? t('home-hint-rename')
240
369
  : confirmRemove !== undefined
@@ -242,8 +371,8 @@ export function SessionSupervisor({ channel, home, onClose, onOpenSession, onNew
242
371
  : menu !== undefined
243
372
  ? t('home-hint-menu')
244
373
  : activePane === 'rail'
245
- ? t('home-hint-list')
246
- : t('supervisor-hint-list');
374
+ ? withTabHint(t('home-hint-list'))
375
+ : withTabHint(t('supervisor-hint-list'));
247
376
  const railWindowTopIndex = railWindowTop(railFocus, railEntries.length, railEntryCapacity);
248
377
  const visibleRailRows = railEntries.slice(railWindowTopIndex, railWindowTopIndex + railEntryCapacity);
249
378
  /** Content-local anchor for a keyboard-opened menu (screen coords minus inset). */
@@ -263,7 +392,12 @@ export function SessionSupervisor({ channel, home, onClose, onOpenSession, onNew
263
392
  sessionTop = Math.max(0, sessionIndex - 1);
264
393
  const visibleSessionRows = visibleSessions.slice(sessionTop, sessionTop + sessionCapacity);
265
394
  const liveCount = listedSessions.filter(session => liveStateOf(session.id)?.live === true).length;
266
- return (_jsxs(Box, { flexDirection: "column", width: columns, height: rows, onClick: menu !== undefined ? closeMenu : undefined, children: [_jsxs(Box, { height: 1, flexShrink: 0, overflow: "hidden", children: [_jsx(Text, { color: "remember", bold: true, children: ` ▣ ${t('supervisor-title')}` }), _jsx(Text, { dimColor: true, children: ` ${t('supervisor-subtitle')}` })] }), _jsx(Divider, { bleed: true }), _jsxs(Box, { flexDirection: "row", flexGrow: 1, flexShrink: 1, overflow: "hidden", children: [railVisible && (_jsxs("ink-box", { style: { flexDirection: 'column', width: railWidth, height: '100%', flexShrink: 0, overflow: 'hidden' }, onClick: activateRail, onMouseEnter: activateRail, onWheel: (event) => {
395
+ return (_jsxs(Box, { flexDirection: "column", width: columns, height: rows, onClick: menu !== undefined ? closeMenu : tabMenu !== undefined ? closeTabMenu : undefined, children: [_jsxs(Box, { height: 1, flexShrink: 0, overflow: "hidden", children: [_jsxs(Box, { flexGrow: 1, flexShrink: 1, overflow: "hidden", children: [_jsx(Text, { color: "remember", bold: true, children: titleText }), showSubtitle && _jsx(Text, { dimColor: true, children: subtitleText })] }), tabs.length > 0 && (_jsx(Box, { flexShrink: 0, marginRight: 1, children: _jsx(SourceTabs, { layout: tabLayout, active: tab, leadId: DSH_TAB, onSelect: switchTab, onOverflow: (event) => {
396
+ closeMenu();
397
+ const next = { col: event.col, row: event.row, item: 0 };
398
+ tabMenuRef.current = next;
399
+ setTabMenu(next);
400
+ } }) }))] }), _jsx(Divider, { bleed: true }), tab !== DSH_TAB && (_jsx(ForeignSessionPanes, { model: foreign, sourceLabel: activeSource?.label ?? tab, home: home, now: now, query: query, notice: notice, railVisible: railVisible, railWidth: railWidth, railEntryCapacity: railEntryCapacity, sessionWidth: sessionWidth, rows: rows, isTerminalFocused: isTerminalFocused })), tab === DSH_TAB && (_jsxs(Box, { flexDirection: "row", flexGrow: 1, flexShrink: 1, overflow: "hidden", children: [railVisible && (_jsxs("ink-box", { style: { flexDirection: 'column', width: railWidth, height: '100%', flexShrink: 0, overflow: 'hidden' }, onClick: activateRail, onMouseEnter: activateRail, onWheel: (event) => {
267
401
  moveRail(event.deltaY >= 0 ? 1 : -1);
268
402
  }, children: [_jsx(Box, { height: 1, flexShrink: 0, overflow: "hidden", paddingX: 1, children: _jsx(Text, { dimColor: true, children: truncateWidth(t('home-section-workspaces', { n: railEntries.length }), railWidth - 2) }) }), !loading && railEntries.length === 0 && (_jsx(Box, { paddingX: 1, children: _jsx(Text, { dimColor: true, italic: true, wrap: "truncate-end", children: truncateWidth(t('home-no-workspaces'), railWidth - 2) }) })), visibleRailRows.map((entry) => {
269
403
  const absolute = railEntries.indexOf(entry);
@@ -280,7 +414,7 @@ export function SessionSupervisor({ channel, home, onClose, onOpenSession, onNew
280
414
  menuRef.current = next;
281
415
  setMenu(next);
282
416
  } }, entry.id));
283
- }), _jsx(Box, { flexGrow: 1 }), _jsx(Box, { flexShrink: 0, paddingX: 1, children: _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: railHint }) }) })] })), railVisible && (_jsx(Box, { width: 1, flexShrink: 0, flexDirection: "column", children: _jsx(Text, { dimColor: true, children: '│' }) })), _jsxs(Box, { flexDirection: "column", width: sessionWidth, height: "100%", flexShrink: 0, overflow: "hidden", onClick: activateList, onMouseEnter: activateList, children: [_jsx(Box, { height: 1, flexShrink: 0, overflow: "hidden", children: _jsxs(Box, { flexShrink: 1, overflow: "hidden", children: [_jsx(Text, { color: "remember", bold: true, children: truncateWidth(` ${t('home-sessions-title', { name: selected?.title ?? t('supervisor-title') })}`, Math.max(4, sessionWidth - 3)) }), _jsx(Text, { dimColor: true, children: ` ${truncateWidth(t('supervisor-counts', { working: workingCount, live: liveCount, total: visibleSessions.length }), Math.max(4, sessionWidth - 3))}` })] }) }), _jsx(Box, { height: 1, flexShrink: 0, paddingX: 1, children: _jsx(SearchBox, { query: query, isFocused: activePane === 'list', isTerminalFocused: isTerminalFocused, placeholder: truncateWidth(t('supervisor-filter-placeholder'), Math.max(8, sessionWidth - 6)), prefix: "/", borderless: true, width: Math.max(8, sessionWidth - 2) }) }), _jsxs(Box, { flexDirection: "column", flexShrink: 0, onClick: (event) => {
417
+ }), _jsx(Box, { flexGrow: 1 }), _jsx(Box, { flexShrink: 0, paddingX: 1, children: _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: railHint }) }) })] })), railVisible && (_jsx(Box, { width: 1, flexShrink: 0, flexDirection: "column", children: _jsx(Text, { dimColor: true, children: '│' }) })), _jsxs(Box, { flexDirection: "column", width: sessionWidth, height: "100%", flexShrink: 0, overflow: "hidden", onClick: activateList, onMouseEnter: activateList, children: [_jsx(Box, { height: 1, flexShrink: 0, overflow: "hidden", children: _jsxs(Box, { flexShrink: 1, overflow: "hidden", children: [_jsx(Text, { color: "remember", bold: true, children: truncateWidth(` ${t('home-sessions-title', { name: selected?.title ?? t('supervisor-title') })}`, Math.max(4, sessionWidth - 3)) }), _jsx(Text, { dimColor: true, children: ` ${truncateWidth(t('supervisor-counts', { working: workingCount, live: liveCount, total: visibleSessions.length }) + (refreshing ? ` · ${t('home-sessions-refreshing')}` : ''), Math.max(4, sessionWidth - 3))}` })] }) }), _jsx(Box, { height: 1, flexShrink: 0, paddingX: 1, children: _jsx(SearchBox, { query: query, isFocused: activePane === 'list', isTerminalFocused: isTerminalFocused, placeholder: truncateWidth(t('supervisor-filter-placeholder'), Math.max(8, sessionWidth - 6)), prefix: "/", borderless: true, width: Math.max(8, sessionWidth - 2) }) }), _jsxs(Box, { flexDirection: "column", flexShrink: 0, onClick: (event) => {
284
418
  event.stopImmediatePropagation();
285
419
  if (selected !== undefined)
286
420
  newSessionIn(selected);
@@ -305,7 +439,7 @@ export function SessionSupervisor({ channel, home, onClose, onOpenSession, onNew
305
439
  menuRef.current = next;
306
440
  setMenu(next);
307
441
  } }, session.id));
308
- })] }), _jsx(Box, { flexShrink: 0, height: 1, overflow: "hidden", children: _jsx(Text, { color: notice?.tone === 'error' ? 'error' : 'success', children: notice === undefined ? ' ' : ` ${truncateWidth(notice.text, Math.max(0, sessionWidth - 3))}` }) }), _jsx(Box, { flexShrink: 0, children: _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: filtered ? t('supervisor-hint-filter') : t('supervisor-hint-list') }) }) })] })] }), rename !== undefined && (_jsx(Box, { height: 1, flexShrink: 0, children: _jsx(SearchBox, { query: rename.draft, isFocused: true, isTerminalFocused: isTerminalFocused, placeholder: t('home-rename-placeholder'), prefix: "\u270E", borderless: true, width: "100%" }) })), confirmRemove !== undefined && (_jsx(Box, { flexShrink: 0, paddingX: 1, onClick: () => {
442
+ })] }), _jsx(Box, { flexShrink: 0, flexDirection: "column", height: noticeRows.length, overflow: "hidden", children: noticeRows.map((line, index) => (_jsx(Text, { color: notice?.tone === 'error' ? 'error' : 'success', children: ` ${line}` }, index))) }), _jsx(Box, { flexShrink: 0, children: _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: filtered ? t('supervisor-hint-filter') : withTabHint(t('supervisor-hint-list')) }) }) })] })] })), rename !== undefined && (_jsx(Box, { height: 1, flexShrink: 0, children: _jsx(SearchBox, { query: rename.draft, isFocused: true, isTerminalFocused: isTerminalFocused, placeholder: t('home-rename-placeholder'), prefix: "\u270E", borderless: true, width: "100%" }) })), confirmRemove !== undefined && (_jsx(Box, { flexShrink: 0, paddingX: 1, onClick: () => {
309
443
  const path = confirmRemove;
310
444
  setConfirmRemove(undefined);
311
445
  removeEntry(path);
@@ -314,7 +448,10 @@ export function SessionSupervisor({ channel, home, onClose, onOpenSession, onNew
314
448
  const entry = railEntries.find(candidate => samePath(candidate.path, menu.path));
315
449
  if (entry !== undefined)
316
450
  activateMenu(entry, index);
317
- }, children: _jsx(Text, { color: action === 'remove' ? 'error' : undefined, children: ` ${index === menu.item ? '❯' : ' '} ${t(MENU_LABEL_KEYS[action])}` }) }, action))) })), approval !== null && (_jsx(Box, { flexShrink: 0, flexDirection: "column", position: "absolute", bottom: 1, left: 0, width: columns, children: _jsx(ApprovalPanel, { approval: approval, background: approval.agentId !== channel.agentId, onDecide: onApprove }) }))] }));
451
+ }, children: _jsx(Text, { color: action === 'remove' ? 'error' : undefined, children: ` ${index === menu.item ? '❯' : ' '} ${t(MENU_LABEL_KEYS[action])}` }) }, action))) })), tabMenu !== undefined && tabLayout.hidden.length > 0 && (_jsx(Box, { position: "absolute", left: Math.max(0, Math.min(tabMenu.col - inset.x - tabMenuWidth + 2, Math.max(0, columns - tabMenuWidth))), top: Math.max(0, Math.min(tabMenu.row - inset.y + 1, Math.max(0, rows - tabLayout.hidden.length - 2))), width: tabMenuWidth, height: tabLayout.hidden.length + 2, flexDirection: "column", flexShrink: 0, borderStyle: "round", borderColor: "permission", backgroundColor: "toolCardBackground", children: tabLayout.hidden.map((hidden, index) => (_jsx(Box, { height: 1, flexShrink: 0, backgroundColor: index === tabMenu.item ? 'userMessageBackgroundHover' : undefined, onMouseEnter: () => setTabMenu(current => (current === undefined ? current : { ...current, item: index })), onClick: (event) => {
452
+ event.stopImmediatePropagation();
453
+ switchTab(hidden.id);
454
+ }, children: _jsx(Text, { children: truncateWidth(` ${index === tabMenu.item ? '❯' : ' '} ${hidden.label}`, tabMenuWidth - 2) }) }, hidden.id))) })), approval !== null && (_jsx(Box, { flexShrink: 0, flexDirection: "column", position: "absolute", bottom: 1, left: 0, width: columns, children: _jsx(ApprovalPanel, { approval: approval, background: approval.agentId !== channel.agentId, onDecide: onApprove }) }))] }));
318
455
  }
319
456
  /**
320
457
  * Scroll anchor for the rail: the first entry index to show.
@@ -1 +1 @@
1
- {"version":3,"file":"Settings.d.ts","sourceRoot":"","sources":["../../../src/screens/Settings.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAczB,OAAO,KAAK,EAAE,SAAS,IAAI,OAAO,EAAE,MAAM,iCAAiC,CAAA;AAuP3E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,OAAO,GACR,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,GAAG,KAAK,CAAC,SAAS,CAojBlB"}
1
+ {"version":3,"file":"Settings.d.ts","sourceRoot":"","sources":["../../../src/screens/Settings.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAczB,OAAO,KAAK,EAAE,SAAS,IAAI,OAAO,EAAE,MAAM,iCAAiC,CAAA;AAkS3E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,OAAO,GACR,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,GAAG,KAAK,CAAC,SAAS,CAikBlB"}
@@ -9,6 +9,25 @@ import { stringWidth } from '../ink/stringWidth.js';
9
9
  import { POINTER, TICK, MULTIPLICATION_X } from '../terminal-utils/figures.js';
10
10
  import { getLang, t } from '../i18n.js';
11
11
  import { SettingsForm } from '../dsh-adapter/settingsEditor.js';
12
+ function rootRowsFor(section) {
13
+ const rows = section.fields
14
+ .filter(field => field.group === undefined)
15
+ .map(field => ({ kind: 'field', field }));
16
+ for (const group of section.groups ?? []) {
17
+ if (group.mode === 'inline') {
18
+ const fields = section.fields.filter(field => field.group === group.id);
19
+ if (fields.length === 0)
20
+ continue;
21
+ rows.push({ kind: 'header', group });
22
+ for (const field of fields)
23
+ rows.push({ kind: 'field', field });
24
+ }
25
+ else {
26
+ rows.push({ kind: 'page', group });
27
+ }
28
+ }
29
+ return rows;
30
+ }
12
31
  /** Pick the provider-owned translation for the active language. */
13
32
  function pick(text, descriptions) {
14
33
  return descriptions?.[getLang()] ?? text;
@@ -41,6 +60,15 @@ function FieldRow({ label, kind, value, selectLabel, focused, editing, invalid,
41
60
  function GroupRow({ title, focused, onClick, onMouseEnter, }) {
42
61
  return (_jsxs(Box, { flexDirection: "row", height: 1, flexShrink: 0, overflow: "hidden", onClick: onClick, onMouseEnter: onMouseEnter, children: [_jsx(Text, { color: focused ? 'suggestion' : undefined, children: focused ? padTo(POINTER, 2) : ' ' }), _jsx(Text, { bold: focused, children: title }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: focused ? 'suggestion' : 'subtle', children: '›' })] }));
43
62
  }
63
+ /**
64
+ * A non-focusable topic header on the root page — the inline twin of
65
+ * GroupRow: it names the run of fields below it instead of hiding them
66
+ * on a subpage. One line, dim, indented to the label column so the rows
67
+ * below keep their pointer gutter and value chips aligned.
68
+ */
69
+ function GroupHeaderRow({ title }) {
70
+ return (_jsx(Box, { flexDirection: "row", height: 1, flexShrink: 0, overflow: "hidden", children: _jsxs(Text, { dimColor: true, children: [' ', title] }) }));
71
+ }
44
72
  /** 区块卡片的边框色(沿用输入框的 panel 边框 token)。 */
45
73
  const CARD_BORDER = 'promptBorder';
46
74
  /**
@@ -175,12 +203,13 @@ export function Settings({ channel, onClose, }) {
175
203
  ? activeSection.fields
176
204
  .filter(field => field.group === activeGroupSpec.id)
177
205
  .map(field => ({ kind: 'field', ns: activeSection.ns, field }))
178
- : sections.flatMap(section => [
179
- ...section.fields
180
- .filter(field => field.group === undefined)
181
- .map(field => ({ kind: 'field', ns: section.ns, field })),
182
- ...(section.groups ?? []).map(group => ({ kind: 'group', ns: section.ns, group })),
183
- ]);
206
+ : sections.flatMap(section => rootRowsFor(section).flatMap((row) => {
207
+ if (row.kind === 'field')
208
+ return [{ kind: 'field', ns: section.ns, field: row.field }];
209
+ if (row.kind === 'page')
210
+ return [{ kind: 'group', ns: section.ns, group: row.group }];
211
+ return [];
212
+ }));
184
213
  const effFocus = Math.min(focusIndex, Math.max(0, focusable.length - 1));
185
214
  const focused = focusable.length === 0 ? undefined : focusable[effFocus];
186
215
  /**
@@ -465,11 +494,20 @@ export function Settings({ channel, onClose, }) {
465
494
  lines: 1,
466
495
  node: (_jsx(CardTop, { title: pick(section.title, section.descriptions), subtitle: section.ns, badges: sectionBadges(section), columns: columns })),
467
496
  });
468
- for (const field of section.fields) {
469
- if (field.group === undefined)
470
- addField(section, field);
471
- }
472
- for (const group of section.groups ?? []) {
497
+ for (const row of rootRowsFor(section)) {
498
+ if (row.kind === 'header') {
499
+ entries.push({
500
+ key: `header:${section.ns}:${row.group.id}`,
501
+ lines: 1,
502
+ node: (_jsx(CardRow, { children: _jsx(GroupHeaderRow, { title: pick(row.group.title, row.group.descriptions) }) })),
503
+ });
504
+ continue;
505
+ }
506
+ if (row.kind === 'field') {
507
+ addField(section, row.field);
508
+ continue;
509
+ }
510
+ const group = row.group;
473
511
  const isFocused = focused?.kind === 'group' && focused.ns === section.ns && focused.group === group;
474
512
  const index = focusCursor;
475
513
  focusCursor += 1;
@@ -1,10 +1,14 @@
1
1
  import React from 'react';
2
+ import { type ActivityLineValue } from '../components/ActivityLine.js';
2
3
  import type { ChannelUi as Channel } from '../adapter/channel/ui-policy.js';
3
4
  import type { WaveBand } from '../dsh-adapter/types.js';
4
- export declare function StatusLine({ channel, selectionActive, helpOpen, wake, }: {
5
+ export declare function StatusLine({ channel, selectionActive, helpOpen, wake, activity: projectedActivity, }: {
5
6
  channel: Channel;
6
7
  selectionActive?: boolean;
7
8
  helpOpen?: boolean;
9
+ /** Activity value published by the working-activity plugin for this session.
10
+ * Preferred over the channel's own copy when the composition provides it. */
11
+ activity?: ActivityLineValue;
8
12
  /**
9
13
  * The session projected onto the status line's few columns, plus the
10
14
  * animation tick and the self-retiring key hint.
@@ -1 +1 @@
1
- {"version":3,"file":"StatusLine.d.ts","sourceRoot":"","sources":["../../../src/screens/StatusLine.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAczB,OAAO,KAAK,EAAE,SAAS,IAAI,OAAO,EAAE,MAAM,iCAAiC,CAAA;AAkB3E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAqHvD,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,eAAuB,EACvB,QAAgB,EAChB,IAAI,GACL,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CACvD,qBA8ZA;AAED,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AA4KD,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKvF;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EACL;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACzD,SAAS,GACZ,MAAM,GAAG,SAAS,CAIpB"}
1
+ {"version":3,"file":"StatusLine.d.ts","sourceRoot":"","sources":["../../../src/screens/StatusLine.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,OAAO,EAAoC,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AAOxG,OAAO,KAAK,EAAE,SAAS,IAAI,OAAO,EAAE,MAAM,iCAAiC,CAAA;AAqB3E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAqHvD,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,eAAuB,EACvB,QAAgB,EAChB,IAAI,EACJ,QAAQ,EAAE,iBAAiB,GAC5B,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;kFAC8E;IAC9E,QAAQ,CAAC,EAAE,iBAAiB,CAAA;IAC5B;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CACvD,qBA+aA;AAED,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AA0LD,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKvF;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EACL;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACzD,SAAS,GACZ,MAAM,GAAG,SAAS,CAIpB"}
@@ -4,13 +4,16 @@ import { Box, Text, useTerminalSize, useTheme } from '../ui.js';
4
4
  import { formatTokens } from '../terminal-utils/format.js';
5
5
  import { t } from '../i18n.js';
6
6
  import { formatContextUsage, DEFAULT_STATUS_BAR, normalizeStatusBar } from '../tuiDisplayPrefs.js';
7
- import { estimateSessionCostCny, estimateSessionCostSplitCny, isDeepSeekOfficialProvider, isPeakHour } from '../deepseekPricing.js';
7
+ import { estimateSessionCostSnapshotCny, isDeepSeekOfficialProvider, isPeakHour } from '../deepseekPricing.js';
8
8
  import { ActivityLine, contextPressurePct } from '../components/ActivityLine.js';
9
9
  import { GoalStatusChip } from '../components/GoalTodoPanel.js';
10
10
  import { formatJobDuration } from '../dsh-adapter/jobs.js';
11
11
  /** Stable fallback for stubbed channels: verify/repro harnesses render the
12
12
  * real Chat with partial channel literals that predate the jobs field. */
13
13
  const NO_BACKGROUND_JOBS = [];
14
+ /** 同上:partial channel 字面量可能早于 mainCost/subagentCost 字段(R4 兼容)。 */
15
+ const NO_MAIN_COST = {};
16
+ const NO_SUBAGENT_COST = [];
14
17
  import { modeDisplayName } from '../sessionModes.js';
15
18
  import { MiniWake } from '../components/trajectory/MiniWake.js';
16
19
  import { ContextBarView } from '../components/ContextBarView.js';
@@ -69,7 +72,7 @@ function FieldLine({ parts, hoverProps, }) {
69
72
  const visible = parts.filter(part => part.node !== null && part.node !== undefined && part.node !== false);
70
73
  return (_jsx(_Fragment, { children: visible.map((part, index) => (_jsxs(React.Fragment, { children: [index > 0 ? _jsx(Text, { dimColor: true, children: " \u00B7 " }) : null, _jsx(Box, { flexShrink: 1, ...(part.id === undefined ? {} : hoverProps(part.id)), children: part.tooltip === undefined || part.tooltip === '' ? (_jsx(Text, { wrap: "truncate", children: part.node })) : (_jsx(TooltipTarget, { content: part.tooltip, children: _jsx(Text, { wrap: "truncate", children: part.node }) })) })] }, part.key))) }));
71
74
  }
72
- export function StatusLine({ channel, selectionActive = false, helpOpen = false, wake, }) {
75
+ export function StatusLine({ channel, selectionActive = false, helpOpen = false, wake, activity: projectedActivity, }) {
73
76
  const { columns } = useTerminalSize();
74
77
  const [themeName] = useTheme();
75
78
  const [hover, setHover] = React.useState(null);
@@ -212,20 +215,32 @@ export function StatusLine({ channel, selectionActive = false, helpOpen = false,
212
215
  node: (_jsxs(Text, { color: "inactiveShimmer", children: [formatTokens(channel.tokens.input), "\u2192", formatTokens(channel.tokens.output)] })),
213
216
  }]
214
217
  : []),
215
- // Estimated session spend (≈¥): only for official DeepSeek providers
216
- // whose model has a known price, and only once the estimate is non-zero
217
- // (a fresh session showing ¥0.00 is noise). The trailing 峰/谷 marker
218
- // shows the current billing window. Hover shows the breakdown.
218
+ // Estimated session spend (≈¥): only for official DeepSeek providers.
219
+ // Visible once there is a priced amount or at least one unpriced token (a
220
+ // fresh, fully priced zero session keeps hiding ¥0.00 as noise; unpriced
221
+ // usage still needs the 未计价 marker). The estimate merges the main
222
+ // session (by model) with the subagents' own durable usage, so delegating
223
+ // work no longer silently undercounts. The trailing 峰/谷 marker shows
224
+ // the current billing window; the total>0 shape is unchanged. Hover shows
225
+ // the breakdown.
219
226
  ...(statusBar.cost && isDeepSeekOfficialProvider(channel.provider)
220
227
  ? (() => {
221
- const estimate = estimateSessionCostCny(channel.tokens, channel.model);
222
- return estimate === undefined || estimate <= 0
223
- ? []
224
- : [{
228
+ const estimate = estimateSessionCostSnapshotCny({
229
+ provider: channel.provider,
230
+ main: channel.mainCost ?? NO_MAIN_COST,
231
+ subagents: channel.subagentCost ?? NO_SUBAGENT_COST,
232
+ fallbackTokens: channel.tokens,
233
+ fallbackModel: channel.model,
234
+ });
235
+ return estimate !== undefined && (estimate.total > 0 || estimate.unpricedTokens > 0)
236
+ ? [{
225
237
  key: 'cost',
226
238
  id: 'cost',
227
- node: (_jsxs(Text, { color: "inactiveShimmer", children: [t('status-cost-label'), "\u00A5", estimate.toFixed(2), " ", t(isPeakHour() ? 'cost-now-peak' : 'cost-now-idle')] })),
228
- }];
239
+ node: (_jsxs(Text, { color: "inactiveShimmer", children: [t('status-cost-label'), estimate.total > 0
240
+ ? _jsxs(_Fragment, { children: ["\u00A5", estimate.total.toFixed(2), " ", t(isPeakHour() ? 'cost-now-peak' : 'cost-now-idle')] })
241
+ : _jsxs(_Fragment, { children: [" ", t('cost-unpriced', { tokens: formatTokens(estimate.unpricedTokens) })] })] })),
242
+ }]
243
+ : [];
229
244
  })()
230
245
  : []),
231
246
  ];
@@ -291,14 +306,18 @@ export function StatusLine({ channel, selectionActive = false, helpOpen = false,
291
306
  : statusBar.shortcutHint && !helpOpen
292
307
  ? t('statusline-hint-shortcuts')
293
308
  : '';
294
- const activity = channel.workingActivity;
309
+ const activity = projectedActivity;
295
310
  const showActivity = statusBar.activity &&
296
311
  !channel.working &&
297
312
  activity !== undefined &&
298
313
  activity.line !== '' &&
299
314
  activity.phase !== 'idle';
300
315
  const showTrajectory = statusBar.trajectory && wake !== undefined;
301
- const barWidth = columns - 4;
316
+ // The root Box below paints paddingX={1} inside width={columns}, so the
317
+ // content area is `columns - 2` cells wide — size the bar from the same
318
+ // arithmetic or its right edge falls 2 columns short of the status row's
319
+ // (the v0.8.0 paddingX 2→1 tightening left the old `columns - 4` stale).
320
+ const barWidth = columns - 2;
302
321
  const barColors = themeName === 'light'
303
322
  ? undefined
304
323
  : { freeFill: '#2E3440', freeText: '#8D95A6' };
@@ -384,11 +403,22 @@ function buildHoverDetail(hover, channel, usage, contextUsed, columns, barColors
384
403
  return (_jsxs(Text, { wrap: "truncate", children: [dim('in '), input.toLocaleString(), " \u00B7 ", dim('out '), output.toLocaleString(), " \u00B7", ' ', dim('total '), (input + output).toLocaleString()] }));
385
404
  }
386
405
  case 'cost': {
387
- const split = estimateSessionCostSplitCny(channel.tokens, channel.model);
388
- if (split === undefined)
406
+ const estimate = estimateSessionCostSnapshotCny({
407
+ provider: channel.provider,
408
+ main: channel.mainCost ?? NO_MAIN_COST,
409
+ subagents: channel.subagentCost ?? NO_SUBAGENT_COST,
410
+ fallbackTokens: channel.tokens,
411
+ fallbackModel: channel.model,
412
+ });
413
+ // Same visibility contract as the field: a priced amount or unpriced
414
+ // tokens (with the 未计价 row) both warrant the breakdown; the old
415
+ // total>0 gate hid the only explanation for an all-unpriced session.
416
+ if (estimate === undefined || (estimate.total <= 0 && estimate.unpricedTokens <= 0))
389
417
  return null;
390
418
  const { input, output, cacheRead } = channel.tokens;
391
- return (_jsxs(Text, { wrap: "truncate", children: [dim('≈¥'), split.total.toFixed(2), " \u00B7 ", dim('peak '), "\u00A5", split.peak.toFixed(2), ' · ', dim('idle '), "\u00A5", split.idle.toFixed(2), " \u00B7 ", dim('in '), formatTokens(input), ' · ', dim('out '), formatTokens(output), " \u00B7 ", dim('cache '), formatTokens(cacheRead), ' · ', t('status-cost-note')] }));
419
+ return (_jsxs(Text, { wrap: "truncate", children: [dim('≈¥'), estimate.total.toFixed(2), " \u00B7 ", dim('peak '), "\u00A5", estimate.peak.toFixed(2), ' · ', dim('idle '), "\u00A5", estimate.idle.toFixed(2), " \u00B7 ", dim('in '), formatTokens(input), ' · ', dim('out '), formatTokens(output), " \u00B7 ", dim('cache '), formatTokens(cacheRead), ' · ', t('cost-split-main', { cost: estimate.main.toFixed(2) }), ' · ', t('cost-split-subagent', { cost: estimate.subagent.toFixed(2) }), estimate.unpricedTokens > 0
420
+ ? _jsxs(_Fragment, { children: [' · ', t('cost-unpriced', { tokens: formatTokens(estimate.unpricedTokens) })] })
421
+ : null, ' · ', t('status-cost-note')] }));
392
422
  }
393
423
  case 'goal': {
394
424
  const goal = channel.goal;
@@ -66,6 +66,11 @@ export type ChatOverlay = {
66
66
  } | {
67
67
  kind: 'skills';
68
68
  index: number;
69
+ } | {
70
+ kind: 'migrate';
71
+ index: number;
72
+ } | {
73
+ kind: 'migrate-confirm';
69
74
  } | {
70
75
  kind: 'activity';
71
76
  index: number;
@@ -1 +1 @@
1
- {"version":3,"file":"chatOverlay.d.ts","sourceRoot":"","sources":["../../../src/screens/chatOverlay.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chatOverlay.d.ts","sourceRoot":"","sources":["../../../src/screens/chatOverlay.ts"],"names":[],"mappings":"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"}
@@ -50,6 +50,7 @@ export function chatOverlayReducer(state, action) {
50
50
  || state.kind === 'workspace-flow'
51
51
  || state.kind === 'model'
52
52
  || state.kind === 'skills'
53
+ || state.kind === 'migrate'
53
54
  || state.kind === 'activity'
54
55
  || state.kind === 'color'
55
56
  || state.kind === 'effort'
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import type { ForeignSessionsModel } from './useForeignSessions.js';
3
+ /**
4
+ * Chrome the right pane of a source tab spends outside its rows: the screen
5
+ * header and divider, the pane banner, the filter, the notice and the hints.
6
+ * Two rows fewer than the DSH pane, which also carries the new-session card.
7
+ */
8
+ export declare const FOREIGN_PANE_CHROME_ROWS = 6;
9
+ /**
10
+ * First visible row of a scroll window that keeps `focus` on screen, the same
11
+ * anchoring the DSH list uses.
12
+ * @param focus - Cursor index.
13
+ * @param total - Rows in the list.
14
+ * @param capacity - Rows the window shows.
15
+ * @returns Index of the first row to draw.
16
+ */
17
+ export declare function windowTop(focus: number, total: number, capacity: number): number;
18
+ /**
19
+ * The two panes of a source tab: the source's directories on the left, the
20
+ * conversations of the selected one on the right.
21
+ *
22
+ * Presentational only; every value and action comes from
23
+ * {@link ForeignSessionsModel}. The shape follows the DSH panes on purpose so
24
+ * the tabs read as one screen, with what a foreign source cannot do removed:
25
+ * no workspace menu (the rail is derived, not a ledger), no new-session card,
26
+ * no live state and no pins.
27
+ */
28
+ export declare function ForeignSessionPanes({ model, sourceLabel, home, now, query, notice, railVisible, railWidth, railEntryCapacity, sessionWidth, rows, isTerminalFocused, }: {
29
+ model: ForeignSessionsModel;
30
+ /** The active source's display name. */
31
+ sourceLabel: string;
32
+ home: string;
33
+ now: number;
34
+ query: string;
35
+ notice: {
36
+ text: string;
37
+ tone: 'info' | 'error';
38
+ } | undefined;
39
+ railVisible: boolean;
40
+ railWidth: number;
41
+ railEntryCapacity: number;
42
+ sessionWidth: number;
43
+ /** Terminal rows of the whole screen. */
44
+ rows: number;
45
+ isTerminalFocused: boolean;
46
+ }): React.ReactNode;
47
+ //# sourceMappingURL=ForeignSessionPanes.d.ts.map