@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
@@ -34,10 +34,14 @@ import { POINTER } from '../../terminal-utils/figures.js';
34
34
  import { PlanReviewPanel } from './PlanReviewPanel.js';
35
35
  import { QuestionMinimizedBar } from './QuestionMinimizedBar.js';
36
36
  import { isPlainReturnInput } from '../../utils/modifiers.js';
37
- import { actionMatches, effectiveComboDisplay } from '../../utils/keymap.js';
37
+ import { actionMatches, comboDisplay, effectiveComboDisplay, primaryComboString } from '../../utils/keymap.js';
38
38
  import { flattenPasteInline } from '../../dsh-adapter/sanitize.js';
39
39
  import { readClipboard } from '../../utils/clipboard.js';
40
40
  import { listWindow } from '../listWindow.js';
41
+ /** Unmodified arrows switch questions; Ctrl/Alt/Super/Shift stay caret motion. */
42
+ function isPlainArrow(key) {
43
+ return key.ctrl !== true && key.meta !== true && key.super !== true && key.shift !== true;
44
+ }
41
45
  const CHECKED = '◉';
42
46
  const UNCHECKED = '○';
43
47
  const PENCIL = '✎';
@@ -51,7 +55,7 @@ const PENCIL = '✎';
51
55
  * PlanReviewPanel (the two panels share the same input contract).
52
56
  */
53
57
  const ANSWER_PASTE_MAX_POINTS = 8000;
54
- export function AskUserQuestionPanel({ question, position, total, answered, initialDraft, onAnswer, onCancel, onBack, readClipboardOverride, collapsed = false, onExpand, onToggleFold, fullscreen = false, }) {
58
+ export function AskUserQuestionPanel({ question, position, total, answered, initialDraft, onAnswer, onCancel, onEscape, onBack, onForward, readClipboardOverride, collapsed = false, onExpand, onToggleFold, fullscreen = false, }) {
55
59
  // Plan-mode's exit_plan_mode ask carries a presentation intent: render
56
60
  // the plan decision card instead of the generic questionnaire. The
57
61
  // branch precedes every hook so hook order stays stable per remount key.
@@ -79,6 +83,11 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
79
83
  : selectedIndices[0] ?? 0;
80
84
  const [focusIndex, setFocusIndex] = React.useState(initialFocus);
81
85
  const [checked, setChecked] = React.useState(() => new Set(multiSelect ? selectedIndices : []));
86
+ // Same stdin batch, same closure: Space / ↑ / ↓ must be visible to a
87
+ // following → before React commits. Refs are the draft source; state
88
+ // only repaints.
89
+ const focusRef = React.useRef(initialFocus);
90
+ const checkedRef = React.useRef(new Set(multiSelect ? selectedIndices : []));
82
91
  const [customText, setCustomText] = React.useState(initialCustom);
83
92
  const [customCursor, setCustomCursor] = React.useState(() => [...initialCustom].length);
84
93
  // Synchronous source of truth for the handlers (see the module header):
@@ -105,6 +114,28 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
105
114
  /** Single-select label captured by typing on a focused option — submitted
106
115
  * together with the custom text when the input row itself is Entered. */
107
116
  const [attached, setAttached] = React.useState(() => initialCustom !== '' && !multiSelect ? (initialSelected[0] ?? null) : null);
117
+ const attachedRef = React.useRef(initialCustom !== '' && !multiSelect ? (initialSelected[0] ?? null) : null);
118
+ const placeFocus = (index) => {
119
+ focusRef.current = index;
120
+ setFocusIndex(index);
121
+ };
122
+ const placeChecked = (next) => {
123
+ checkedRef.current = next;
124
+ setChecked(next);
125
+ };
126
+ const toggleCheckedAt = (index) => {
127
+ const next = new Set(checkedRef.current);
128
+ if (next.has(index))
129
+ next.delete(index);
130
+ else
131
+ next.add(index);
132
+ placeChecked(next);
133
+ };
134
+ const placeAttached = (value) => {
135
+ attachedRef.current = value;
136
+ setAttached(value);
137
+ };
138
+ const onInputRow = () => !hideCustomInput && focusRef.current === options.length;
108
139
  const [error, setError] = React.useState(null);
109
140
  const inputFocused = !hideCustomInput && focusIndex === options.length;
110
141
  // Chat chrome + panel scaffolding consume twelve rows before the option
@@ -139,7 +170,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
139
170
  const moveFocus = (delta) => {
140
171
  if (rowCount <= 1)
141
172
  return;
142
- setFocusIndex(index => (index + delta + rowCount) % rowCount);
173
+ placeFocus((focusRef.current + delta + rowCount) % rowCount);
143
174
  setError(null);
144
175
  };
145
176
  /** Append at the text tail (option-row typing has no visible cursor). */
@@ -156,7 +187,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
156
187
  points.splice(at - 1, 1);
157
188
  const next = points.join('');
158
189
  if (next === '')
159
- setAttached(null);
190
+ placeAttached(null);
160
191
  applyText(next, at - 1);
161
192
  };
162
193
  /**
@@ -181,7 +212,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
181
212
  points.splice(at, 0, ...text);
182
213
  applyText(points.join(''), at + [...text].length);
183
214
  if (!atCaret && !multiSelect)
184
- setAttached(options[focusIndex]?.label ?? null);
215
+ placeAttached(options[focusRef.current]?.label ?? null);
185
216
  return 'ok';
186
217
  };
187
218
  /** Inline error for an over-cap paste (shared by both transports). */
@@ -223,7 +254,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
223
254
  pasteBusyRef.current = false;
224
255
  });
225
256
  };
226
- const checkedLabels = () => [...checked].sort((a, b) => a - b).map(index => options[index]?.label)
257
+ const checkedLabels = () => [...checkedRef.current].sort((a, b) => a - b).map(index => options[index]?.label)
227
258
  .filter((label) => label !== undefined);
228
259
  /** Enter on a real option: the option(s) plus whatever the input row holds. */
229
260
  const submitOptions = () => {
@@ -237,7 +268,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
237
268
  onAnswer({ selected, ...(text !== '' ? { custom: text } : {}) });
238
269
  return;
239
270
  }
240
- const label = options[focusIndex]?.label;
271
+ const label = options[focusRef.current]?.label;
241
272
  if (label === undefined) {
242
273
  setError(t('question-select-or-answer'));
243
274
  return;
@@ -261,16 +292,16 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
261
292
  setError(t('question-type-answer-first'));
262
293
  return;
263
294
  }
264
- onAnswer({ selected: attached !== null ? [attached] : [], custom: text });
295
+ onAnswer({ selected: attachedRef.current !== null ? [attachedRef.current] : [], custom: text });
265
296
  };
266
297
  /** Capture the visible answer state before navigating away. */
267
298
  const currentDraft = () => {
268
299
  const selected = multiSelect
269
300
  ? checkedLabels()
270
- : inputFocused
271
- ? (attached === null ? [] : [attached])
301
+ : onInputRow()
302
+ ? (attachedRef.current === null ? [] : [attachedRef.current])
272
303
  : (() => {
273
- const label = options[focusIndex]?.label;
304
+ const label = options[focusRef.current]?.label;
274
305
  return label === undefined ? [] : [label];
275
306
  })();
276
307
  return {
@@ -299,7 +330,9 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
299
330
  return;
300
331
  }
301
332
  if (key.escape) {
302
- if (onBack !== undefined)
333
+ if (onEscape !== undefined)
334
+ onEscape(currentDraft());
335
+ else if (onBack !== undefined)
303
336
  onBack(currentDraft());
304
337
  else
305
338
  onCancel();
@@ -328,7 +361,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
328
361
  pasteFromClipboard();
329
362
  return;
330
363
  }
331
- if (inputFocused) {
364
+ if (onInputRow()) {
332
365
  if (key.upArrow) {
333
366
  moveFocus(-1);
334
367
  return;
@@ -352,17 +385,28 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
352
385
  points.splice(at, 1);
353
386
  const next = points.join('');
354
387
  if (next === '')
355
- setAttached(null);
388
+ placeAttached(null);
356
389
  applyText(next, at);
357
390
  }
358
391
  return;
359
392
  }
360
393
  if (key.leftArrow) {
394
+ // Plain ← at the start of the answer switches questions; anywhere
395
+ // else (and modified arrows) stays a caret step.
396
+ if (isPlainArrow(key) && cursorRef.current === 0 && onBack !== undefined) {
397
+ onBack(currentDraft());
398
+ return;
399
+ }
361
400
  applyText(textRef.current, Math.max(0, cursorRef.current - 1));
362
401
  return;
363
402
  }
364
403
  if (key.rightArrow) {
365
- applyText(textRef.current, Math.min([...textRef.current].length, cursorRef.current + 1));
404
+ const length = [...textRef.current].length;
405
+ if (isPlainArrow(key) && cursorRef.current >= length && onForward !== undefined) {
406
+ onForward(currentDraft());
407
+ return;
408
+ }
409
+ applyText(textRef.current, Math.min(length, cursorRef.current + 1));
366
410
  return;
367
411
  }
368
412
  if (key.home) {
@@ -393,20 +437,23 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
393
437
  moveFocus(1);
394
438
  return;
395
439
  }
440
+ if (key.leftArrow && isPlainArrow(key)) {
441
+ if (onBack !== undefined)
442
+ onBack(currentDraft());
443
+ return;
444
+ }
445
+ if (key.rightArrow && isPlainArrow(key)) {
446
+ if (onForward !== undefined)
447
+ onForward(currentDraft());
448
+ return;
449
+ }
396
450
  if (key.tab && !hideCustomInput) {
397
- setFocusIndex(options.length);
451
+ placeFocus(options.length);
398
452
  setError(null);
399
453
  return;
400
454
  }
401
455
  if (input === ' ' && multiSelect) {
402
- setChecked(previous => {
403
- const next = new Set(previous);
404
- if (next.has(focusIndex))
405
- next.delete(focusIndex);
406
- else
407
- next.add(focusIndex);
408
- return next;
409
- });
456
+ toggleCheckedAt(focusRef.current);
410
457
  return;
411
458
  }
412
459
  if (isPlainReturnInput(input, key)) {
@@ -424,7 +471,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
424
471
  if (!hideCustomInput && !key.ctrl && !key.meta && !key.super && input) {
425
472
  appendText(input);
426
473
  if (!multiSelect)
427
- setAttached(options[focusIndex]?.label ?? null);
474
+ placeAttached(options[focusRef.current]?.label ?? null);
428
475
  }
429
476
  });
430
477
  const remaining = total - answered;
@@ -443,7 +490,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
443
490
  const focusInputRow = () => {
444
491
  if (hideCustomInput)
445
492
  return;
446
- setFocusIndex(options.length);
493
+ placeFocus(options.length);
447
494
  setError(null);
448
495
  };
449
496
  /**
@@ -454,14 +501,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
454
501
  */
455
502
  const clickOption = (index) => {
456
503
  if (multiSelect) {
457
- setChecked(previous => {
458
- const next = new Set(previous);
459
- if (next.has(index))
460
- next.delete(index);
461
- else
462
- next.add(index);
463
- return next;
464
- });
504
+ toggleCheckedAt(index);
465
505
  return;
466
506
  }
467
507
  const label = options[index]?.label;
@@ -475,9 +515,9 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
475
515
  const [headerHovered, setHeaderHovered] = React.useState(false);
476
516
  /** Mouse submit row hover (multi-select: clicking submits the checked set). */
477
517
  const [submitHovered, setSubmitHovered] = React.useState(false);
478
- const renderInputRow = () => (_jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, onClick: focusInputRow, onMouseEnter: () => setHoverIndex(options.length), onMouseLeave: () => setHoverIndex(current => (current === options.length ? -1 : current)), backgroundColor: hoverIndex === options.length && !inputFocused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : 'suggestion', children: PENCIL }) }), _jsxs(Box, { flexDirection: "row", marginLeft: 1, children: [_jsx(Text, { bold: inputFocused, color: inputFocused ? 'accent' : 'suggestion', children: t('question-custom-tab') }), attached !== null && (_jsx(Text, { color: "suggestion", children: t('question-attached-label', { label: attached }) })), _jsx(Text, { dimColor: true, children: "\uFF1A" }), customText === '' && !inputFocused ? (_jsx(Text, { ref: caretRef, dimColor: true, children: t('question-direct-input') })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: textPoints.slice(0, customCursor).join('') }), inputFocused
518
+ const renderInputRow = () => (_jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, onClick: focusInputRow, onMouseEnter: () => setHoverIndex(options.length), onMouseLeave: () => setHoverIndex(current => (current === options.length ? -1 : current)), backgroundColor: hoverIndex === options.length && !inputFocused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : 'suggestion', children: PENCIL }) }), _jsxs(Box, { flexDirection: "row", marginLeft: 1, children: [_jsx(Text, { bold: inputFocused, color: inputFocused ? 'accent' : 'suggestion', children: t('question-custom-tab') }), attached !== null && (_jsx(Text, { color: "suggestion", children: t('question-attached-label', { label: attached }) })), _jsx(Text, { dimColor: true, children: "\uFF1A" }), customText === '' && !inputFocused ? (_jsxs(_Fragment, { children: [_jsx(Text, { ref: caretRef, children: ' ' }), _jsx(Text, { dimColor: true, children: t('question-direct-input') })] })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: textPoints.slice(0, customCursor).join('') }), inputFocused
479
519
  ? _jsx(Text, { ref: caretRef, inverse: true, children: cursorChar })
480
- : _jsx(Text, { ref: caretRef, color: "suggestion", children: "\u258F" }), _jsx(Text, { wrap: "wrap", children: textPoints.slice(inputFocused ? customCursor + 1 : customCursor).join('') })] }))] })] }));
520
+ : _jsx(Text, { ref: caretRef, children: "\u258F" }), _jsx(Text, { wrap: "wrap", children: textPoints.slice(inputFocused ? customCursor + 1 : customCursor).join('') })] }))] })] }));
481
521
  const renderOptions = () => (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [options.slice(optionWindow.start, optionWindow.end).map((option, index) => {
482
522
  const absoluteIndex = optionWindow.start + index;
483
523
  const focused = absoluteIndex === focusIndex;
@@ -498,10 +538,11 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
498
538
  const hintParts = inputFocused
499
539
  ? [
500
540
  t('question-hint-type'),
501
- t('question-hint-paste'),
541
+ t('question-hint-paste', { key: comboDisplay(primaryComboString('paste')) }),
502
542
  t('question-hint-enter'),
503
543
  ...(options.length > 0 ? [t('question-hint-back')] : []),
504
544
  onBack === undefined ? t('question-hint-esc') : t('question-hint-previous'),
545
+ ...(onBack !== undefined || onForward !== undefined ? [t('question-hint-switch-input')] : []),
505
546
  ...(onBack === undefined ? [] : [t('question-hint-cancel')]),
506
547
  ...(multiSelect && checked.size > 0 ? [t('question-hint-selected', { n: checked.size })] : []),
507
548
  t('question-fold-hint', { combo: foldCombo }),
@@ -509,9 +550,10 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
509
550
  : [
510
551
  t('question-hint-select'),
511
552
  ...(multiSelect ? [t('question-hint-multi')] : []),
512
- ...(hideCustomInput ? [] : [t('question-hint-paste'), t('question-hint-attach')]),
553
+ ...(hideCustomInput ? [] : [t('question-hint-paste', { key: comboDisplay(primaryComboString('paste')) }), t('question-hint-attach')]),
513
554
  t('question-hint-enter'),
514
555
  onBack === undefined ? t('question-hint-esc') : t('question-hint-previous'),
556
+ ...(onBack !== undefined || onForward !== undefined ? [t('question-hint-switch')] : []),
515
557
  ...(onBack === undefined ? [] : [t('question-hint-cancel')]),
516
558
  ...(multiSelect && checked.size > 0 ? [t('question-hint-selected', { n: checked.size })] : []),
517
559
  t('question-fold-hint', { combo: foldCombo }),
@@ -1 +1 @@
1
- {"version":3,"file":"PlanReviewPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/PlanReviewPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAIvE,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAa5E,MAAM,MAAM,oBAAoB,GAAG;IACjC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;IAC7B;;;OAGG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;CAC9D,CAAA;AAED,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,qBAAqB,GACtB,EAAE,oBAAoB,GAAG,KAAK,CAAC,SAAS,CAmZxC"}
1
+ {"version":3,"file":"PlanReviewPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/PlanReviewPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAIvE,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAa5E,MAAM,MAAM,oBAAoB,GAAG;IACjC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;IAC7B;;;OAGG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;CAC9D,CAAA;AAED,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,qBAAqB,GACtB,EAAE,oBAAoB,GAAG,KAAK,CAAC,SAAS,CA4ZxC"}
@@ -33,7 +33,7 @@ import { Divider } from '../design-system/Divider.js';
33
33
  import { Markdown } from '../Markdown.js';
34
34
  import { POINTER } from '../../terminal-utils/figures.js';
35
35
  import { isPlainReturnInput } from '../../utils/modifiers.js';
36
- import { actionMatches } from '../../utils/keymap.js';
36
+ import { actionMatches, comboDisplay, primaryComboString } from '../../utils/keymap.js';
37
37
  import { flattenPasteInline } from '../../dsh-adapter/sanitize.js';
38
38
  import { readClipboard } from '../../utils/clipboard.js';
39
39
  const PENCIL = '✎';
@@ -345,7 +345,7 @@ export function PlanReviewPanel({ question, onAnswer, onCancel, readClipboardOve
345
345
  const focused = index === focusIndex;
346
346
  const isApprove = option.label === approveLabel;
347
347
  return (_jsxs(Box, { flexDirection: "row", marginTop: focused ? 1 : 0, onClick: () => clickOption(index), onMouseEnter: () => setHoverIndex(index), onMouseLeave: () => setHoverIndex(current => (current === index ? -1 : current)), backgroundColor: hoverIndex === index && !focused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'accent' : undefined, bold: focused, children: focused ? POINTER : ' ' }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [_jsxs(Text, { bold: focused, color: focused || isApprove ? 'accent' : undefined, wrap: "wrap", children: [index + 1, ". ", option.label] }), option.description !== undefined && (_jsx(Text, { dimColor: true, wrap: "wrap", children: option.description }))] })] }, option.label));
348
- }), _jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, onClick: focusFeedbackRow, onMouseEnter: () => setHoverIndex(options.length), onMouseLeave: () => setHoverIndex(current => (current === options.length ? -1 : current)), backgroundColor: hoverIndex === options.length && !inputFocused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : 'suggestion', children: PENCIL }) }), _jsx(Box, { flexDirection: "row", marginLeft: 1, children: feedback === '' && !inputFocused ? (_jsx(Text, { ref: caretRef, dimColor: true, children: t('plan-review-feedback-placeholder') })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: feedbackPoints.slice(0, cursor).join('') }), inputFocused
348
+ }), _jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, onClick: focusFeedbackRow, onMouseEnter: () => setHoverIndex(options.length), onMouseLeave: () => setHoverIndex(current => (current === options.length ? -1 : current)), backgroundColor: hoverIndex === options.length && !inputFocused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : 'suggestion', children: PENCIL }) }), _jsx(Box, { flexDirection: "row", marginLeft: 1, children: feedback === '' && !inputFocused ? (_jsxs(_Fragment, { children: [_jsx(Text, { ref: caretRef, children: ' ' }), _jsx(Text, { dimColor: true, children: t('plan-review-feedback-placeholder') })] })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: feedbackPoints.slice(0, cursor).join('') }), inputFocused
349
349
  ? _jsx(Text, { ref: caretRef, inverse: true, children: cursorChar })
350
- : _jsx(Text, { ref: caretRef, color: "suggestion", children: "\u258F" }), _jsx(Text, { wrap: "wrap", children: feedbackPoints.slice(inputFocused ? cursor + 1 : cursor).join('') })] })) })] })] }), error !== null && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "error", children: error }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: t('plan-review-hint') }) })] }));
350
+ : _jsx(Text, { ref: caretRef, children: "\u258F" }), _jsx(Text, { wrap: "wrap", children: feedbackPoints.slice(inputFocused ? cursor + 1 : cursor).join('') })] })) })] })] }), error !== null && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "error", children: error }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: t('plan-review-hint', { paste: comboDisplay(primaryComboString('paste')) }) }) })] }));
351
351
  }
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import type { ClickEvent } from '../../ink/events/click-event.js';
3
+ import type { ForeignSessionRow as ForeignSessionSummary } from '../../adapter/ports/channel-session.js';
4
+ /**
5
+ * One conversation of another agent in a source tab: its title, and a facts
6
+ * line with when it last moved and where it ran.
7
+ *
8
+ * It looks like a DSH session row on purpose — the same two lines, the same
9
+ * `❯`, green selection and blue hover (see SessionListRow) — so the tabs read
10
+ * as one screen. It is its own component rather than a shared core so the DSH
11
+ * row stays untouched; the handful of lines below are the whole overlap.
12
+ *
13
+ * Deliberately NO import status. Selecting a row imports it on the spot (or
14
+ * opens the copy an earlier selection made), so "imported or not" is a detail
15
+ * of the selection, not a fact the user has to read before choosing; showing it
16
+ * would also invite a sync the feature does not do.
17
+ *
18
+ * The working directory rides on the facts line here, unlike the DSH row: the
19
+ * rail groups by directory, but a search spans every group of the source and
20
+ * "which project was this" is the question a foreign title answers worst.
21
+ */
22
+ export declare function ForeignSessionRow({ session, width, focused, home, now, onClick, }: {
23
+ session: ForeignSessionSummary;
24
+ /** Columns available to the row. */
25
+ width: number;
26
+ focused: boolean;
27
+ /** Home directory, for collapsing the path to `~`. */
28
+ home: string;
29
+ /** Epoch ms used for every relative time in this render pass. */
30
+ now: number;
31
+ /** Mouse click: import and open (same path as Enter). */
32
+ onClick?(event: ClickEvent): void;
33
+ }): React.ReactNode;
34
+ //# sourceMappingURL=ForeignSessionRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForeignSessionRow.d.ts","sourceRoot":"","sources":["../../../../src/components/sessions/ForeignSessionRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAEvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAGjE,OAAO,KAAK,EAAE,iBAAiB,IAAI,qBAAqB,EAAE,MAAM,wCAAwC,CAAA;AAExG;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,KAAK,EACL,OAAO,EACP,IAAI,EACJ,GAAG,EACH,OAAO,GACR,EAAE;IACD,OAAO,EAAE,qBAAqB,CAAA;IAC9B,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAA;IACZ,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAA;IACX,yDAAyD;IACzD,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CAClC,GAAG,KAAK,CAAC,SAAS,CAmClB"}
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Box, Text } from '../../ui.js';
4
+ import { useTooltip } from '../Tooltip.js';
5
+ import { formatAbsolute, formatProject, formatWhen, truncateWidth } from '../../sessions/format.js';
6
+ /**
7
+ * One conversation of another agent in a source tab: its title, and a facts
8
+ * line with when it last moved and where it ran.
9
+ *
10
+ * It looks like a DSH session row on purpose — the same two lines, the same
11
+ * `❯`, green selection and blue hover (see SessionListRow) — so the tabs read
12
+ * as one screen. It is its own component rather than a shared core so the DSH
13
+ * row stays untouched; the handful of lines below are the whole overlap.
14
+ *
15
+ * Deliberately NO import status. Selecting a row imports it on the spot (or
16
+ * opens the copy an earlier selection made), so "imported or not" is a detail
17
+ * of the selection, not a fact the user has to read before choosing; showing it
18
+ * would also invite a sync the feature does not do.
19
+ *
20
+ * The working directory rides on the facts line here, unlike the DSH row: the
21
+ * rail groups by directory, but a search spans every group of the source and
22
+ * "which project was this" is the question a foreign title answers worst.
23
+ */
24
+ export function ForeignSessionRow({ session, width, focused, home, now, onClick, }) {
25
+ const [hovered, setHovered] = useState(false);
26
+ // Two cells for the focus marker.
27
+ const body = Math.max(8, width - 2);
28
+ const shownTitle = truncateWidth(session.title, Math.max(4, body - 2));
29
+ const titleTooltip = useTooltip(() => {
30
+ const parts = [];
31
+ if (shownTitle !== session.title)
32
+ parts.push(session.title);
33
+ parts.push(formatAbsolute(session.updatedAt));
34
+ if (session.cwd !== '')
35
+ parts.push(session.cwd);
36
+ return parts.join('\n');
37
+ });
38
+ const facts = [formatWhen(session.updatedAt, now), formatProject(session.cwd, home)];
39
+ return (_jsxs(Box, { flexDirection: "column", flexShrink: 0, onClick: onClick, onMouseEnter: onClick === undefined ? undefined : () => setHovered(true), onMouseLeave: onClick === undefined ? undefined : () => setHovered(false),
40
+ // Hover is the blue prompt and never marks the focused row; selection is
41
+ // the green foreground below, as on the DSH row.
42
+ backgroundColor: hovered && !focused ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { children: [_jsx(Text, { color: focused ? 'success' : 'subtle', children: focused ? '❯ ' : ' ' }), _jsx(Box, { ...titleTooltip, children: _jsx(Text, { color: focused ? 'success' : undefined, bold: focused, children: shownTitle }) })] }), _jsx(Text, { color: focused ? 'success' : undefined, dimColor: !focused, children: ` ${truncateWidth(facts.join(' · '), body)}` })] }));
43
+ }
@@ -0,0 +1,52 @@
1
+ import React from 'react';
2
+ import type { ClickEvent } from '../../ink/events/click-event.js';
3
+ /** One tab of the session screen's source strip. */
4
+ export interface SourceTab {
5
+ readonly id: string;
6
+ readonly label: string;
7
+ }
8
+ /** Which tabs the strip draws and which fold into the `+N` cell. */
9
+ export interface SourceTabsLayout {
10
+ readonly shown: readonly SourceTab[];
11
+ readonly hidden: readonly SourceTab[];
12
+ }
13
+ /**
14
+ * Display width of a strip: its cells, the `│` after the leading DSH tab when
15
+ * anything follows it, and the `+N` cell when tabs are folded.
16
+ * @param shown - Tabs drawn in full; the first is the DSH tab when present.
17
+ * @param hidden - How many tabs fold into `+N`.
18
+ * @param leadId - Id of the tab the separator follows.
19
+ * @returns Terminal cells the strip occupies.
20
+ */
21
+ export declare function sourceTabsWidth(shown: readonly SourceTab[], hidden: number, leadId: string): number;
22
+ /**
23
+ * Fit the strip into `budget` cells.
24
+ *
25
+ * Tabs fold from the END (the strip is sorted by recency, so the oldest source
26
+ * goes first) into one `+N` cell. The active tab never folds — a strip that
27
+ * hid the tab you are on could not tell you where you are — and the leading
28
+ * tab is the last to go after it.
29
+ * @param tabs - Every tab, leading tab first.
30
+ * @param active - Id of the active tab.
31
+ * @param budget - Cells available to the strip.
32
+ * @returns The tabs to draw and the tabs behind `+N`.
33
+ */
34
+ export declare function layoutSourceTabs(tabs: readonly SourceTab[], active: string, budget: number): SourceTabsLayout;
35
+ /**
36
+ * The source strip in the session screen's header: `DSH │ Claude Code Codex`.
37
+ *
38
+ * The active tab is a reverse block in the remember colour; the others are dim
39
+ * until the pointer is over them. Every click stops propagation, because the
40
+ * screen's root closes open menus on click and a tab click is not a click on
41
+ * the background.
42
+ */
43
+ export declare function SourceTabs({ layout, active, leadId, onSelect, onOverflow, }: {
44
+ layout: SourceTabsLayout;
45
+ active: string;
46
+ /** Id of the tab the `│` separator follows. */
47
+ leadId: string;
48
+ onSelect(id: string): void;
49
+ /** Click on `+N`: open the list of folded tabs at the pointer. */
50
+ onOverflow(event: ClickEvent): void;
51
+ }): React.ReactNode;
52
+ //# sourceMappingURL=SourceTabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SourceTabs.d.ts","sourceRoot":"","sources":["../../../../src/components/sessions/SourceTabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAEvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAGjE,oDAAoD;AACpD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IACpC,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAA;CACtC;AAKD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKnG;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAW7G;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,MAAM,EACN,MAAM,EACN,QAAQ,EACR,UAAU,GACX,EAAE;IACD,MAAM,EAAE,gBAAgB,CAAA;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,kEAAkE;IAClE,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CACpC,GAAG,KAAK,CAAC,SAAS,CA8BlB"}
@@ -0,0 +1,70 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { useState } from 'react';
3
+ import { Box, Text } from '../../ui.js';
4
+ import { stringWidth } from '../../ink/stringWidth.js';
5
+ /** A tab cell is its label with one column of padding on each side. */
6
+ const cellWidth = (label) => stringWidth(label) + 2;
7
+ /**
8
+ * Display width of a strip: its cells, the `│` after the leading DSH tab when
9
+ * anything follows it, and the `+N` cell when tabs are folded.
10
+ * @param shown - Tabs drawn in full; the first is the DSH tab when present.
11
+ * @param hidden - How many tabs fold into `+N`.
12
+ * @param leadId - Id of the tab the separator follows.
13
+ * @returns Terminal cells the strip occupies.
14
+ */
15
+ export function sourceTabsWidth(shown, hidden, leadId) {
16
+ let width = shown.reduce((sum, tab) => sum + cellWidth(tab.label), 0);
17
+ if (hidden > 0)
18
+ width += cellWidth(`+${hidden}`);
19
+ if (shown[0]?.id === leadId && (shown.length > 1 || hidden > 0))
20
+ width += 1;
21
+ return width;
22
+ }
23
+ /**
24
+ * Fit the strip into `budget` cells.
25
+ *
26
+ * Tabs fold from the END (the strip is sorted by recency, so the oldest source
27
+ * goes first) into one `+N` cell. The active tab never folds — a strip that
28
+ * hid the tab you are on could not tell you where you are — and the leading
29
+ * tab is the last to go after it.
30
+ * @param tabs - Every tab, leading tab first.
31
+ * @param active - Id of the active tab.
32
+ * @param budget - Cells available to the strip.
33
+ * @returns The tabs to draw and the tabs behind `+N`.
34
+ */
35
+ export function layoutSourceTabs(tabs, active, budget) {
36
+ const leadId = tabs[0]?.id ?? '';
37
+ for (let keep = tabs.length; keep >= 0; keep--) {
38
+ const shown = tabs.filter((tab, index) => index < keep || tab.id === active);
39
+ const hidden = tabs.filter(tab => !shown.includes(tab));
40
+ if (sourceTabsWidth(shown, hidden.length, leadId) <= budget)
41
+ return { shown, hidden };
42
+ }
43
+ // Not even the active tab and `+N` fit: draw them anyway and let the header
44
+ // clip, since a missing active tab is worse than a clipped one.
45
+ const shown = tabs.filter(tab => tab.id === active);
46
+ return { shown, hidden: tabs.filter(tab => tab.id !== active) };
47
+ }
48
+ /**
49
+ * The source strip in the session screen's header: `DSH │ Claude Code Codex`.
50
+ *
51
+ * The active tab is a reverse block in the remember colour; the others are dim
52
+ * until the pointer is over them. Every click stops propagation, because the
53
+ * screen's root closes open menus on click and a tab click is not a click on
54
+ * the background.
55
+ */
56
+ export function SourceTabs({ layout, active, leadId, onSelect, onOverflow, }) {
57
+ return (_jsxs(Box, { flexShrink: 0, height: 1, overflow: "hidden", children: [layout.shown.map((tab, index) => (_jsxs(React.Fragment, { children: [_jsx(SourceTabCell, { label: tab.label, active: tab.id === active, onClick: (event) => {
58
+ event.stopImmediatePropagation();
59
+ onSelect(tab.id);
60
+ } }), index === 0 && tab.id === leadId && (layout.shown.length > 1 || layout.hidden.length > 0) && (_jsx(Text, { dimColor: true, children: '│' }))] }, tab.id))), layout.hidden.length > 0 && (_jsx(SourceTabCell, { label: `+${layout.hidden.length}`, active: false, onClick: (event) => {
61
+ event.stopImmediatePropagation();
62
+ onOverflow(event);
63
+ } }))] }));
64
+ }
65
+ function SourceTabCell({ label, active, onClick, }) {
66
+ const [hovered, setHovered] = useState(false);
67
+ return (_jsx(Box, { flexShrink: 0, onClick: onClick, onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), children: active
68
+ ? _jsx(Text, { color: "remember", bold: true, inverse: true, children: ` ${label} ` })
69
+ : _jsx(Text, { dimColor: !hovered, children: ` ${label} ` }) }));
70
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * 开屏的两个彩蛋——都只改**文字**,字体轮换、鲸鱼动画、窄终端阶梯一律照旧:
3
+ *
4
+ * ① 节日换词:本地日期命中整天窗口时,把下排词换成 `HAPPINESS` / `MERRY` /
5
+ * `NEW YEAR`(上排仍是 `DEEPSEEK`)。字距由 `withTagline` 按新词重解,
6
+ * 所以换词不会把两行搞成不等宽。
7
+ * ② 小概率求 star:每次 mount 掷一次(默认 1/20),命中就把底部欢迎语换成
8
+ * 一句带仓库链接的话。链接走 `createHyperlink`,不支持 OSC 8 的终端自动
9
+ * 退化成纯文本 URL;命中概率与终端能力都是可注入的测试缝。
10
+ */
11
+ import type { UsageStats } from '../usageStats.js';
12
+ /** 一个节日彩蛋:当天要用的上下两排词。 */
13
+ export interface SplashEgg {
14
+ /** 稳定 id(回归按 id 命中)。 */
15
+ readonly id: string;
16
+ /** 上排词。 */
17
+ readonly top: string;
18
+ /** 下排词。 */
19
+ readonly bottom: string;
20
+ }
21
+ /**
22
+ * 当天是不是彩蛋日。
23
+ * @param now - 注入的当前时间(测试缝;生产用 `new Date()`)。
24
+ * @returns 命中的彩蛋(含当天要用的词对);没命中返回 `null`(照常画 `HARNESS`)。
25
+ */
26
+ export declare function pickSplashEgg(now?: Date): SplashEgg | null;
27
+ /** 求 star 标语指向的仓库。 */
28
+ export declare const SPLASH_STAR_URL = "https://github.com/ccch1mneyyy/dsh-TUI";
29
+ /** 求 star 彩蛋的三行结构(标题 / 数字 / 求星)。 */
30
+ export interface SplashStarLine {
31
+ /** 标题行:替换平时的欢迎语(本次会话 star 过后换成"捡到星星"版)。 */
32
+ readonly title: string;
33
+ /** 数字行:本机实测累计值。 */
34
+ readonly stats: string;
35
+ /**
36
+ * 求星行(`Star` 上是 OSC 8 链接),已拼好;**终端不支持超链接时为
37
+ * `null`**——那行会退化成裸 URL,长 30+ 列会把整块撑破,宁可不显示。
38
+ */
39
+ readonly ask: string | null;
40
+ /** 整块里**最宽一行**的可见宽度:居中缩进必须按它算。 */
41
+ readonly width: number;
42
+ }
43
+ /**
44
+ * 组装求 star 彩蛋。文案走 i18n 字典(中英齐全),`{{hours}}`/`{{launches}}`
45
+ * 换成本机**实测**的累计值,`{{key}}` 换成生效中的快捷键显示。
46
+ * @param options - `usage` 是本机累计用量;`supportsHyperlinks` 是终端能力的测试缝;
47
+ * `keyHint` 是快捷键显示(如 `Alt+S`);`caught` 表示本次会话已经 star 过。
48
+ * @returns 三行文案与最宽行可见宽度。
49
+ */
50
+ export declare function splashStarLine(options: {
51
+ usage: UsageStats;
52
+ supportsHyperlinks?: boolean;
53
+ keyHint?: string;
54
+ caught?: boolean;
55
+ }): SplashStarLine;
56
+ //# sourceMappingURL=splashEggs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splashEggs.d.ts","sourceRoot":"","sources":["../../../src/components/splashEggs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD,yBAAyB;AACzB,MAAM,WAAW,SAAS;IACxB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,WAAW;IACX,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,WAAW;IACX,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAsBD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,GAAE,IAAiB,GAAG,SAAS,GAAG,IAAI,CAItE;AAED,sBAAsB;AACtB,eAAO,MAAM,eAAe,2CAA2C,CAAA;AAKvE,oCAAoC;AACpC,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,mBAAmB;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,kCAAkC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAKD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,KAAK,EAAE,UAAU,CAAA;IACjB,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,GAAG,cAAc,CAsBjB"}