@deepseek-harness-tui/dsh-tui 0.11.1 → 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 (427) hide show
  1. package/README.md +50 -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 +39 -17
  7. package/cordis.yml +3 -2
  8. package/lib/settings.json +1272 -0
  9. package/lib/types/adapter/channel/ui-policy.d.ts +9 -2
  10. package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
  11. package/lib/types/adapter/channel/ui-policy.js +13 -0
  12. package/lib/types/adapter/kernel/replay.d.ts.map +1 -1
  13. package/lib/types/adapter/kernel/replay.js +2 -0
  14. package/lib/types/adapter/ports/channel-display.d.ts +12 -0
  15. package/lib/types/adapter/ports/channel-display.d.ts.map +1 -1
  16. package/lib/types/adapter/ports/channel-session.d.ts +38 -0
  17. package/lib/types/adapter/ports/channel-session.d.ts.map +1 -1
  18. package/lib/types/adapter/ports/channel-settings.d.ts +12 -0
  19. package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
  20. package/lib/types/adapter/ports/channel-ui.d.ts +46 -4
  21. package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
  22. package/lib/types/adapter/ports/channel-view.d.ts +43 -0
  23. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
  24. package/lib/types/commands.d.ts.map +1 -1
  25. package/lib/types/commands.js +2 -0
  26. package/lib/types/components/BalanceReportRow.d.ts +10 -2
  27. package/lib/types/components/BalanceReportRow.d.ts.map +1 -1
  28. package/lib/types/components/BalanceReportRow.js +18 -4
  29. package/lib/types/components/CompactionStatusRow.d.ts +24 -0
  30. package/lib/types/components/CompactionStatusRow.d.ts.map +1 -0
  31. package/lib/types/components/CompactionStatusRow.js +72 -0
  32. package/lib/types/components/GoalTodoPanel.js +2 -2
  33. package/lib/types/components/HelpMenu.d.ts +2 -2
  34. package/lib/types/components/HelpMenu.d.ts.map +1 -1
  35. package/lib/types/components/HelpMenu.js +5 -4
  36. package/lib/types/components/InlineMathParagraph.d.ts +22 -0
  37. package/lib/types/components/InlineMathParagraph.d.ts.map +1 -0
  38. package/lib/types/components/InlineMathParagraph.js +178 -0
  39. package/lib/types/components/LogoV2.d.ts +41 -3
  40. package/lib/types/components/LogoV2.d.ts.map +1 -1
  41. package/lib/types/components/LogoV2.js +148 -24
  42. package/lib/types/components/Markdown.d.ts +10 -3
  43. package/lib/types/components/Markdown.d.ts.map +1 -1
  44. package/lib/types/components/Markdown.js +47 -14
  45. package/lib/types/components/MathBlock.d.ts +13 -0
  46. package/lib/types/components/MathBlock.d.ts.map +1 -0
  47. package/lib/types/components/MathBlock.js +136 -0
  48. package/lib/types/components/MessageList.d.ts +10 -1
  49. package/lib/types/components/MessageList.d.ts.map +1 -1
  50. package/lib/types/components/MessageList.js +13 -4
  51. package/lib/types/components/MigratePicker.d.ts +30 -0
  52. package/lib/types/components/MigratePicker.d.ts.map +1 -0
  53. package/lib/types/components/MigratePicker.js +38 -0
  54. package/lib/types/components/PromptInput.d.ts +17 -0
  55. package/lib/types/components/PromptInput.d.ts.map +1 -1
  56. package/lib/types/components/PromptInput.js +48 -7
  57. package/lib/types/components/SplitDiffView.d.ts.map +1 -1
  58. package/lib/types/components/SplitDiffView.js +2 -1
  59. package/lib/types/components/StarPrompt.d.ts +53 -0
  60. package/lib/types/components/StarPrompt.d.ts.map +1 -0
  61. package/lib/types/components/StarPrompt.js +281 -0
  62. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  63. package/lib/types/components/StreamingMarkdown.js +20 -3
  64. package/lib/types/components/TimelineRail.d.ts.map +1 -1
  65. package/lib/types/components/TimelineRail.js +9 -1
  66. package/lib/types/components/Whale.d.ts +17 -8
  67. package/lib/types/components/Whale.d.ts.map +1 -1
  68. package/lib/types/components/Whale.js +25 -15
  69. package/lib/types/components/WhaleGirl.d.ts +29 -0
  70. package/lib/types/components/WhaleGirl.d.ts.map +1 -0
  71. package/lib/types/components/WhaleGirl.js +32 -0
  72. package/lib/types/components/WorkingSpinner.d.ts +4 -1
  73. package/lib/types/components/WorkingSpinner.d.ts.map +1 -1
  74. package/lib/types/components/WorkingSpinner.js +2 -2
  75. package/lib/types/components/bigfont.d.ts +47 -18
  76. package/lib/types/components/bigfont.d.ts.map +1 -1
  77. package/lib/types/components/bigfont.js +55 -40
  78. package/lib/types/components/design-system/ThemeProvider.d.ts +6 -0
  79. package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
  80. package/lib/types/components/design-system/ThemeProvider.js +40 -1
  81. package/lib/types/components/maidPortrait.d.ts +44 -0
  82. package/lib/types/components/maidPortrait.d.ts.map +1 -0
  83. package/lib/types/components/maidPortrait.js +178 -0
  84. package/lib/types/components/mathPreview.d.ts +25 -0
  85. package/lib/types/components/mathPreview.d.ts.map +1 -0
  86. package/lib/types/components/mathPreview.js +48 -0
  87. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  88. package/lib/types/components/messages/AssistantThinkingMessage.js +2 -1
  89. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  90. package/lib/types/components/messages/AssistantToolUseMessage.js +3 -2
  91. package/lib/types/components/messages/TranscriptImages.d.ts.map +1 -1
  92. package/lib/types/components/messages/TranscriptImages.js +11 -1
  93. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +14 -2
  94. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
  95. package/lib/types/components/questions/AskUserQuestionPanel.js +80 -38
  96. package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
  97. package/lib/types/components/questions/PlanReviewPanel.js +3 -3
  98. package/lib/types/components/sessions/ForeignSessionRow.d.ts +34 -0
  99. package/lib/types/components/sessions/ForeignSessionRow.d.ts.map +1 -0
  100. package/lib/types/components/sessions/ForeignSessionRow.js +43 -0
  101. package/lib/types/components/sessions/SourceTabs.d.ts +52 -0
  102. package/lib/types/components/sessions/SourceTabs.d.ts.map +1 -0
  103. package/lib/types/components/sessions/SourceTabs.js +70 -0
  104. package/lib/types/components/splashEggs.d.ts +56 -0
  105. package/lib/types/components/splashEggs.d.ts.map +1 -0
  106. package/lib/types/components/splashEggs.js +67 -0
  107. package/lib/types/components/splashFonts.d.ts +119 -0
  108. package/lib/types/components/splashFonts.d.ts.map +1 -0
  109. package/lib/types/components/splashFonts.js +267 -0
  110. package/lib/types/components/splashLayout.d.ts +41 -0
  111. package/lib/types/components/splashLayout.d.ts.map +1 -0
  112. package/lib/types/components/splashLayout.js +40 -0
  113. package/lib/types/components/whaleGirlSprite.d.ts +17 -0
  114. package/lib/types/components/whaleGirlSprite.d.ts.map +1 -0
  115. package/lib/types/components/whaleGirlSprite.js +47 -0
  116. package/lib/types/deepseekPricing.d.ts +74 -0
  117. package/lib/types/deepseekPricing.d.ts.map +1 -1
  118. package/lib/types/deepseekPricing.js +110 -11
  119. package/lib/types/dsh-adapter/channel/action-readiness.d.ts +1 -1
  120. package/lib/types/dsh-adapter/channel/action-readiness.d.ts.map +1 -1
  121. package/lib/types/dsh-adapter/channel/action-readiness.js +6 -1
  122. package/lib/types/dsh-adapter/channel/background-action.d.ts +1 -0
  123. package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -1
  124. package/lib/types/dsh-adapter/channel/background-action.js +1 -0
  125. package/lib/types/dsh-adapter/channel/binding-events.d.ts +8 -9
  126. package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
  127. package/lib/types/dsh-adapter/channel/binding-events.js +69 -21
  128. package/lib/types/dsh-adapter/channel/compaction.d.ts +2 -1
  129. package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
  130. package/lib/types/dsh-adapter/channel/compaction.js +35 -2
  131. package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -1
  132. package/lib/types/dsh-adapter/channel/local-actions.js +6 -1
  133. package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -1
  134. package/lib/types/dsh-adapter/channel/model-switch.js +5 -1
  135. package/lib/types/dsh-adapter/channel/paths.d.ts.map +1 -1
  136. package/lib/types/dsh-adapter/channel/paths.js +7 -1
  137. package/lib/types/dsh-adapter/channel/preferences.d.ts +1 -1
  138. package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -1
  139. package/lib/types/dsh-adapter/channel/preferences.js +16 -0
  140. package/lib/types/dsh-adapter/channel/projection.d.ts +1 -2
  141. package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
  142. package/lib/types/dsh-adapter/channel/projection.js +127 -17
  143. package/lib/types/dsh-adapter/channel/question-record.d.ts +76 -0
  144. package/lib/types/dsh-adapter/channel/question-record.d.ts.map +1 -0
  145. package/lib/types/dsh-adapter/channel/question-record.js +107 -0
  146. package/lib/types/dsh-adapter/channel/session-lineage.d.ts +42 -0
  147. package/lib/types/dsh-adapter/channel/session-lineage.d.ts.map +1 -0
  148. package/lib/types/dsh-adapter/channel/session-lineage.js +51 -0
  149. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +2 -0
  150. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -1
  151. package/lib/types/dsh-adapter/channel/session-live-adoption.js +9 -3
  152. package/lib/types/dsh-adapter/channel/session-metadata.d.ts +2 -1
  153. package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
  154. package/lib/types/dsh-adapter/channel/session-metadata.js +39 -7
  155. package/lib/types/dsh-adapter/channel/session-reset.d.ts +1 -1
  156. package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -1
  157. package/lib/types/dsh-adapter/channel/session-reset.js +7 -0
  158. package/lib/types/dsh-adapter/channel/session-resume.d.ts +1 -0
  159. package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
  160. package/lib/types/dsh-adapter/channel/session-resume.js +4 -2
  161. package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
  162. package/lib/types/dsh-adapter/channel/settings-host.js +8 -0
  163. package/lib/types/dsh-adapter/channel/state.d.ts +14 -1
  164. package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
  165. package/lib/types/dsh-adapter/channel/state.js +6 -1
  166. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +30 -35
  167. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
  168. package/lib/types/dsh-adapter/channel/subagent-projection.js +138 -4
  169. package/lib/types/dsh-adapter/channel/types.d.ts +1 -1
  170. package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -1
  171. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  172. package/lib/types/dsh-adapter/channel.js +19 -4
  173. package/lib/types/dsh-adapter/compat/messages.d.ts +6 -0
  174. package/lib/types/dsh-adapter/compat/messages.d.ts.map +1 -1
  175. package/lib/types/dsh-adapter/compat/messages.js +9 -0
  176. package/lib/types/dsh-adapter/contract.d.ts +5 -5
  177. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  178. package/lib/types/dsh-adapter/contract.js +8 -6
  179. package/lib/types/dsh-adapter/index.d.ts +36 -1
  180. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  181. package/lib/types/dsh-adapter/index.js +22 -6
  182. package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts +3 -0
  183. package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts.map +1 -0
  184. package/lib/types/dsh-adapter/migrate/adapters/claude-code.js +131 -0
  185. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.d.ts +17 -0
  186. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.d.ts.map +1 -0
  187. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.js +329 -0
  188. package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts +3 -0
  189. package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts.map +1 -0
  190. package/lib/types/dsh-adapter/migrate/adapters/codex.js +102 -0
  191. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.d.ts +16 -0
  192. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.d.ts.map +1 -0
  193. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.js +289 -0
  194. package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts +3 -0
  195. package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts.map +1 -0
  196. package/lib/types/dsh-adapter/migrate/adapters/grok-build.js +117 -0
  197. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.d.ts +13 -0
  198. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.d.ts.map +1 -0
  199. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.js +178 -0
  200. package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts +3 -0
  201. package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts.map +1 -0
  202. package/lib/types/dsh-adapter/migrate/adapters/omp.js +133 -0
  203. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.d.ts +60 -0
  204. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.d.ts.map +1 -0
  205. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.js +178 -0
  206. package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts +8 -0
  207. package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts.map +1 -0
  208. package/lib/types/dsh-adapter/migrate/adapters/scan.js +40 -0
  209. package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts +3 -0
  210. package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts.map +1 -0
  211. package/lib/types/dsh-adapter/migrate/adapters/zcode.js +93 -0
  212. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.d.ts +9 -0
  213. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.d.ts.map +1 -0
  214. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.js +89 -0
  215. package/lib/types/dsh-adapter/migrate/bin-path.d.ts +6 -0
  216. package/lib/types/dsh-adapter/migrate/bin-path.d.ts.map +1 -0
  217. package/lib/types/dsh-adapter/migrate/bin-path.js +30 -0
  218. package/lib/types/dsh-adapter/migrate/browse.d.ts +42 -0
  219. package/lib/types/dsh-adapter/migrate/browse.d.ts.map +1 -0
  220. package/lib/types/dsh-adapter/migrate/browse.js +90 -0
  221. package/lib/types/dsh-adapter/migrate/cli.d.ts +9 -0
  222. package/lib/types/dsh-adapter/migrate/cli.d.ts.map +1 -0
  223. package/lib/types/dsh-adapter/migrate/cli.js +106 -0
  224. package/lib/types/dsh-adapter/migrate/import-one.d.ts +89 -0
  225. package/lib/types/dsh-adapter/migrate/import-one.d.ts.map +1 -0
  226. package/lib/types/dsh-adapter/migrate/import-one.js +133 -0
  227. package/lib/types/dsh-adapter/migrate/index.d.ts +35 -0
  228. package/lib/types/dsh-adapter/migrate/index.d.ts.map +1 -0
  229. package/lib/types/dsh-adapter/migrate/index.js +107 -0
  230. package/lib/types/dsh-adapter/migrate/parse/injection.d.ts +40 -0
  231. package/lib/types/dsh-adapter/migrate/parse/injection.d.ts.map +1 -0
  232. package/lib/types/dsh-adapter/migrate/parse/injection.js +127 -0
  233. package/lib/types/dsh-adapter/migrate/parse/jsonl.d.ts +28 -0
  234. package/lib/types/dsh-adapter/migrate/parse/jsonl.d.ts.map +1 -0
  235. package/lib/types/dsh-adapter/migrate/parse/jsonl.js +40 -0
  236. package/lib/types/dsh-adapter/migrate/parse/role-turns.d.ts +28 -0
  237. package/lib/types/dsh-adapter/migrate/parse/role-turns.d.ts.map +1 -0
  238. package/lib/types/dsh-adapter/migrate/parse/role-turns.js +50 -0
  239. package/lib/types/dsh-adapter/migrate/parse/title.d.ts +18 -0
  240. package/lib/types/dsh-adapter/migrate/parse/title.d.ts.map +1 -0
  241. package/lib/types/dsh-adapter/migrate/parse/title.js +29 -0
  242. package/lib/types/dsh-adapter/migrate/parse/tools.d.ts +62 -0
  243. package/lib/types/dsh-adapter/migrate/parse/tools.d.ts.map +1 -0
  244. package/lib/types/dsh-adapter/migrate/parse/tools.js +110 -0
  245. package/lib/types/dsh-adapter/migrate/picker.d.ts +64 -0
  246. package/lib/types/dsh-adapter/migrate/picker.d.ts.map +1 -0
  247. package/lib/types/dsh-adapter/migrate/picker.js +86 -0
  248. package/lib/types/dsh-adapter/migrate/recent-agents.d.ts +40 -0
  249. package/lib/types/dsh-adapter/migrate/recent-agents.d.ts.map +1 -0
  250. package/lib/types/dsh-adapter/migrate/recent-agents.js +100 -0
  251. package/lib/types/dsh-adapter/migrate/sessionize.d.ts +39 -0
  252. package/lib/types/dsh-adapter/migrate/sessionize.d.ts.map +1 -0
  253. package/lib/types/dsh-adapter/migrate/sessionize.js +271 -0
  254. package/lib/types/dsh-adapter/migrate/types.d.ts +176 -0
  255. package/lib/types/dsh-adapter/migrate/types.d.ts.map +1 -0
  256. package/lib/types/dsh-adapter/migrate/types.js +11 -0
  257. package/lib/types/dsh-adapter/migrate/uuid.d.ts +7 -0
  258. package/lib/types/dsh-adapter/migrate/uuid.d.ts.map +1 -0
  259. package/lib/types/dsh-adapter/migrate/uuid.js +25 -0
  260. package/lib/types/dsh-adapter/plugin.d.ts +4 -2
  261. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  262. package/lib/types/dsh-adapter/plugin.js +143 -364
  263. package/lib/types/dsh-adapter/providerWizard.d.ts +17 -0
  264. package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -1
  265. package/lib/types/dsh-adapter/providerWizard.js +254 -66
  266. package/lib/types/dsh-adapter/questions.d.ts +22 -15
  267. package/lib/types/dsh-adapter/questions.d.ts.map +1 -1
  268. package/lib/types/dsh-adapter/questions.js +47 -45
  269. package/lib/types/dsh-adapter/sessions/digest.d.ts +11 -6
  270. package/lib/types/dsh-adapter/sessions/digest.d.ts.map +1 -1
  271. package/lib/types/dsh-adapter/sessions/digest.js +20 -13
  272. package/lib/types/dsh-adapter/sessions/frames.d.ts +3 -1
  273. package/lib/types/dsh-adapter/sessions/frames.d.ts.map +1 -1
  274. package/lib/types/dsh-adapter/sessions/frames.js +5 -4
  275. package/lib/types/dsh-adapter/sessions/list.d.ts +6 -1
  276. package/lib/types/dsh-adapter/sessions/list.d.ts.map +1 -1
  277. package/lib/types/dsh-adapter/sessions/list.js +188 -164
  278. package/lib/types/dsh-adapter/sessions/recovery.d.ts +16 -0
  279. package/lib/types/dsh-adapter/sessions/recovery.d.ts.map +1 -0
  280. package/lib/types/dsh-adapter/sessions/recovery.js +108 -0
  281. package/lib/types/dsh-adapter/sessions/snapshot.d.ts +7 -0
  282. package/lib/types/dsh-adapter/sessions/snapshot.d.ts.map +1 -0
  283. package/lib/types/dsh-adapter/sessions/snapshot.js +90 -0
  284. package/lib/types/dsh-adapter/sessions/store.d.ts +10 -4
  285. package/lib/types/dsh-adapter/sessions/store.d.ts.map +1 -1
  286. package/lib/types/dsh-adapter/sessions/store.js +62 -25
  287. package/lib/types/dsh-adapter/sideQuestion.d.ts +41 -2
  288. package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -1
  289. package/lib/types/dsh-adapter/sideQuestion.js +98 -2
  290. package/lib/types/dsh-adapter/subagents.d.ts +28 -3
  291. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
  292. package/lib/types/dsh-adapter/subagents.js +77 -2
  293. package/lib/types/herdr.d.ts +2 -0
  294. package/lib/types/herdr.d.ts.map +1 -1
  295. package/lib/types/herdr.js +9 -3
  296. package/lib/types/i18n.d.ts +424 -42
  297. package/lib/types/i18n.d.ts.map +1 -1
  298. package/lib/types/i18n.js +145 -20
  299. package/lib/types/ink/components/App.d.ts +2 -2
  300. package/lib/types/ink/components/App.d.ts.map +1 -1
  301. package/lib/types/ink/components/App.js +5 -1
  302. package/lib/types/ink/components/Image.d.ts +14 -1
  303. package/lib/types/ink/components/Image.d.ts.map +1 -1
  304. package/lib/types/ink/components/Image.js +2 -2
  305. package/lib/types/ink/events/input-event.js +3 -3
  306. package/lib/types/ink/hooks/use-terminal-images.d.ts +12 -0
  307. package/lib/types/ink/hooks/use-terminal-images.d.ts.map +1 -1
  308. package/lib/types/ink/hooks/use-terminal-images.js +13 -0
  309. package/lib/types/ink/ink.d.ts +6 -0
  310. package/lib/types/ink/ink.d.ts.map +1 -1
  311. package/lib/types/ink/ink.js +16 -1
  312. package/lib/types/ink/kitty-graphics.d.ts +44 -3
  313. package/lib/types/ink/kitty-graphics.d.ts.map +1 -1
  314. package/lib/types/ink/kitty-graphics.js +184 -23
  315. package/lib/types/ink/output.d.ts +24 -2
  316. package/lib/types/ink/output.d.ts.map +1 -1
  317. package/lib/types/ink/output.js +83 -5
  318. package/lib/types/ink/parse-keypress.d.ts +26 -1
  319. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  320. package/lib/types/ink/parse-keypress.js +156 -13
  321. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  322. package/lib/types/ink/render-node-to-output.js +8 -1
  323. package/lib/types/ink/screen.d.ts +24 -0
  324. package/lib/types/ink/screen.d.ts.map +1 -1
  325. package/lib/types/ink/screen.js +89 -0
  326. package/lib/types/ink/selection.d.ts +40 -18
  327. package/lib/types/ink/selection.d.ts.map +1 -1
  328. package/lib/types/ink/selection.js +142 -30
  329. package/lib/types/ink/sixel-codec.d.ts +12 -1
  330. package/lib/types/ink/sixel-codec.d.ts.map +1 -1
  331. package/lib/types/ink/sixel-codec.js +29 -5
  332. package/lib/types/ink/sixel-graphics.d.ts.map +1 -1
  333. package/lib/types/ink/sixel-graphics.js +5 -3
  334. package/lib/types/ink/styles.d.ts +9 -0
  335. package/lib/types/ink/styles.d.ts.map +1 -1
  336. package/lib/types/ink/terminal-image.d.ts +8 -0
  337. package/lib/types/ink/terminal-image.d.ts.map +1 -1
  338. package/lib/types/ink/terminal-querier.d.ts +7 -1
  339. package/lib/types/ink/terminal-querier.d.ts.map +1 -1
  340. package/lib/types/ink/terminal-querier.js +12 -2
  341. package/lib/types/ink/timeline-rail.d.ts +5 -0
  342. package/lib/types/ink/timeline-rail.d.ts.map +1 -1
  343. package/lib/types/math/inline-layout.d.ts +29 -0
  344. package/lib/types/math/inline-layout.d.ts.map +1 -0
  345. package/lib/types/math/inline-layout.js +106 -0
  346. package/lib/types/math/layout.d.ts +58 -0
  347. package/lib/types/math/layout.d.ts.map +1 -0
  348. package/lib/types/math/layout.js +59 -0
  349. package/lib/types/math/renderer.d.ts +64 -0
  350. package/lib/types/math/renderer.d.ts.map +1 -0
  351. package/lib/types/math/renderer.js +256 -0
  352. package/lib/types/screens/Chat.d.ts +14 -1
  353. package/lib/types/screens/Chat.d.ts.map +1 -1
  354. package/lib/types/screens/Chat.js +606 -53
  355. package/lib/types/screens/SessionSupervisor.d.ts +2 -1
  356. package/lib/types/screens/SessionSupervisor.d.ts.map +1 -1
  357. package/lib/types/screens/SessionSupervisor.js +156 -19
  358. package/lib/types/screens/Settings.d.ts.map +1 -1
  359. package/lib/types/screens/Settings.js +49 -11
  360. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  361. package/lib/types/screens/StatusLine.js +45 -15
  362. package/lib/types/screens/chatOverlay.d.ts +5 -0
  363. package/lib/types/screens/chatOverlay.d.ts.map +1 -1
  364. package/lib/types/screens/chatOverlay.js +1 -0
  365. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.d.ts +47 -0
  366. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.d.ts.map +1 -0
  367. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.js +65 -0
  368. package/lib/types/screens/sessionSupervisor/model.d.ts +12 -0
  369. package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -1
  370. package/lib/types/screens/sessionSupervisor/model.js +26 -0
  371. package/lib/types/screens/sessionSupervisor/useForeignSessions.d.ts +107 -0
  372. package/lib/types/screens/sessionSupervisor/useForeignSessions.d.ts.map +1 -0
  373. package/lib/types/screens/sessionSupervisor/useForeignSessions.js +312 -0
  374. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts +4 -1
  375. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -1
  376. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +97 -14
  377. package/lib/types/sessionHistory.d.ts +2 -2
  378. package/lib/types/sessionHistory.d.ts.map +1 -1
  379. package/lib/types/sessionHistory.js +31 -5
  380. package/lib/types/settings/definitions.d.ts +681 -0
  381. package/lib/types/settings/definitions.d.ts.map +1 -0
  382. package/lib/types/settings/definitions.js +511 -0
  383. package/lib/types/starAction.d.ts +44 -0
  384. package/lib/types/starAction.d.ts.map +1 -0
  385. package/lib/types/starAction.js +52 -0
  386. package/lib/types/terminal-utils/latex.d.ts +10 -0
  387. package/lib/types/terminal-utils/latex.d.ts.map +1 -0
  388. package/lib/types/terminal-utils/latex.js +1417 -0
  389. package/lib/types/terminal-utils/markdown.d.ts +3 -1
  390. package/lib/types/terminal-utils/markdown.d.ts.map +1 -1
  391. package/lib/types/terminal-utils/markdown.js +26 -1
  392. package/lib/types/terminal-utils/math.d.ts +66 -0
  393. package/lib/types/terminal-utils/math.d.ts.map +1 -0
  394. package/lib/types/terminal-utils/math.js +337 -0
  395. package/lib/types/tips.d.ts.map +1 -1
  396. package/lib/types/tips.js +6 -0
  397. package/lib/types/tuiDisplayPrefs.d.ts +67 -0
  398. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
  399. package/lib/types/tuiDisplayPrefs.js +59 -0
  400. package/lib/types/ui.d.ts +1 -1
  401. package/lib/types/ui.d.ts.map +1 -1
  402. package/lib/types/ui.js +1 -1
  403. package/lib/types/usageStats.d.ts +98 -0
  404. package/lib/types/usageStats.d.ts.map +1 -0
  405. package/lib/types/usageStats.js +169 -0
  406. package/lib/types/utils/bmp.d.ts +17 -0
  407. package/lib/types/utils/bmp.d.ts.map +1 -0
  408. package/lib/types/utils/bmp.js +154 -0
  409. package/lib/types/utils/clipboard.d.ts +14 -2
  410. package/lib/types/utils/clipboard.d.ts.map +1 -1
  411. package/lib/types/utils/clipboard.js +143 -8
  412. package/lib/types/utils/fold-long-lines.d.ts.map +1 -1
  413. package/lib/types/utils/fold-long-lines.js +2 -1
  414. package/lib/types/utils/keymap.d.ts +4 -1
  415. package/lib/types/utils/keymap.d.ts.map +1 -1
  416. package/lib/types/utils/keymap.js +8 -0
  417. package/lib/types/utils/modifiers.d.ts +4 -3
  418. package/lib/types/utils/modifiers.d.ts.map +1 -1
  419. package/lib/types/utils/modifiers.js +4 -3
  420. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/LICENSE +202 -0
  421. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/NOTICE +20 -0
  422. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/index.d.ts +16 -0
  423. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/bundled-packages.json +4 -0
  424. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/index.mjs +20 -0
  425. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/index.mjs.LEGAL.txt +35 -0
  426. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/package.json +29 -0
  427. package/package.json +111 -97
@@ -14,6 +14,7 @@ import { foldLongLines } from '../../utils/fold-long-lines.js';
14
14
  import { getLang, t } from '../../i18n.js';
15
15
  import { revealLinesOf, snapReveal } from '../smoothReveal.js';
16
16
  import { useRevealVersion } from '../../hooks/useRevealVersion.js';
17
+ import { primaryComboString } from '../../utils/keymap.js';
17
18
  /** Tool display names localize through the `tool-name-*` dictionary family
18
19
  * (i18n.ts): DSH emits lowercase tool ids (`bash`), display names resolve
19
20
  * per language — proper nouns (Bash, PowerShell) stay identical in zh.
@@ -191,7 +192,7 @@ function capLines(lines, max, verbose) {
191
192
  return lines;
192
193
  return [
193
194
  ...lines.slice(0, max),
194
- { ...dim(t('lines-folded-expand', { n: lines.length - max })), revealOnHover: true },
195
+ { ...dim(t('lines-folded-expand', { n: lines.length - max, key: primaryComboString('transcript') })), revealOnHover: true },
195
196
  ];
196
197
  }
197
198
  /** Long-line clip for the body rows (utils/fold-long-lines.ts): the line cap
@@ -330,7 +331,7 @@ function HeaderTitle({ name, title, isTerminal, folded, displayArgs, argsLanguag
330
331
  return (_jsxs(_Fragment, { children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }), displayArgs !== '' && (_jsxs(Box, { flexWrap: "nowrap", ...headerTooltip, children: [_jsx(Text, { children: "(" }), _jsx(SyntaxText, { text: clipHeaderArgs(displayArgs), sourceText: displayArgs, language: argsLanguage }), _jsx(Text, { children: ")" })] }))] }));
331
332
  }
332
333
  if (isTerminal) {
333
- return (_jsxs(_Fragment, { children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }), _jsx(Box, { flexWrap: "nowrap", ...headerTooltip, children: folded === undefined ? (_jsxs(Text, { children: ["(", title, ")"] })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: ["(", folded.first, ")"] }), folded.hiddenLines > 0 && (_jsx(Text, { dimColor: true, children: ` ${t('lines-folded-expand', { n: folded.hiddenLines })}` }))] })) })] }));
334
+ return (_jsxs(_Fragment, { children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }), _jsx(Box, { flexWrap: "nowrap", ...headerTooltip, children: folded === undefined ? (_jsxs(Text, { children: ["(", title, ")"] })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: ["(", folded.first, ")"] }), folded.hiddenLines > 0 && (_jsx(Text, { dimColor: true, children: ` ${t('lines-folded-expand', { n: folded.hiddenLines, key: primaryComboString('transcript') })}` }))] })) })] }));
334
335
  }
335
336
  const trimmed = title.trim();
336
337
  if (trimmed === '') {
@@ -1 +1 @@
1
- {"version":3,"file":"TranscriptImages.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/TranscriptImages.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAEtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AAS7E,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,gFAAgB,CAAA;AAEpD;wEACwE;AACxE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAGnE;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,MAAU,EACV,SAAS,EACT,gBAAwB,GACzB,EAAE;IACD,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;IACrD;iDAC6C;IAC7C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CACpC,GAAG,KAAK,CAAC,SAAS,CA6BlB;AA0FD,yEAAyE;AACzE,wBAAgB,iCAAiC,IAAI,IAAI,CAGxD"}
1
+ {"version":3,"file":"TranscriptImages.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/TranscriptImages.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAEtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AAW7E,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,gFAAgB,CAAA;AAEpD;wEACwE;AACxE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAGnE;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,MAAU,EACV,SAAS,EACT,gBAAwB,GACzB,EAAE;IACD,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;IACrD;iDAC6C;IAC7C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CACpC,GAAG,KAAK,CAAC,SAAS,CA6BlB;AAqGD,yEAAyE;AACzE,wBAAgB,iCAAiC,IAAI,IAAI,CAGxD"}
@@ -5,6 +5,8 @@ import { TERMINAL_IMAGE_PREVIEW_MAX_EDGE, TERMINAL_IMAGE_PREVIEW_MAX_BYTES } fro
5
5
  import { makeDecodeTier } from './transcriptImageDecode.js';
6
6
  import { cleanRenderText } from '../../dsh-adapter/sanitize.js';
7
7
  import { getLang, subscribeLang, t } from '../../i18n.js';
8
+ import { useTerminalBackground } from '../design-system/ThemeProvider.js';
9
+ import { getImageBacking, subscribeImageBacking } from '../../tuiDisplayPrefs.js';
8
10
  const thumbnailTier = makeDecodeTier(384, 24);
9
11
  // One modal at a time: current + previous suffices for instant reopen.
10
12
  const fullTier = makeDecodeTier(TERMINAL_IMAGE_PREVIEW_MAX_EDGE, 2, TERMINAL_IMAGE_PREVIEW_MAX_BYTES / 4);
@@ -42,6 +44,14 @@ function TranscriptImagePreview({ image, width, height, graphicsAvailable, onPre
42
44
  setState({ kind: 'failed' }); });
43
45
  return () => { live = false; controller.abort(); };
44
46
  }, [image, graphicsAvailable]);
47
+ // What sits behind the raster follows `dsh-tui.imageBacking`: photos
48
+ // may float transparent like formulas (the wallpaper shows at
49
+ // anti-aliased edges and transparent corners — Sixel's binary alpha drops
50
+ // their softest pixels) or composite onto the terminal colour, which
51
+ // keeps soft edges smooth on any background.
52
+ const backing = React.useSyncExternalStore(subscribeImageBacking, getImageBacking);
53
+ const composited = backing === 'terminal';
54
+ const terminalBackground = useTerminalBackground();
45
55
  const label = transcriptImageLabel(image);
46
56
  const fallback = !graphicsAvailable
47
57
  ? t('transcript-image-ready', { name: label })
@@ -50,7 +60,7 @@ function TranscriptImagePreview({ image, width, height, graphicsAvailable, onPre
50
60
  : state.kind === 'loading'
51
61
  ? t('transcript-image-loading', { name: label })
52
62
  : t('transcript-image-ready', { name: label });
53
- const preview = (_jsx(Image, { presentation: "transcript", source: graphicsAvailable && state.kind === 'ready' ? state.source : undefined, width: width, height: height, alt: label, children: _jsx(Box, { width: width, height: height, alignItems: "center", justifyContent: "center", children: _jsxs(Text, { dimColor: true, wrap: "truncate", children: ["[", fallback, "]"] }) }) }));
63
+ const preview = (_jsx(Box, { backgroundColor: composited ? terminalBackground : undefined, children: _jsx(Image, { ...(composited ? {} : { transparent: true }), presentation: "transcript", source: graphicsAvailable && state.kind === 'ready' ? state.source : undefined, width: width, height: height, alt: label, children: _jsx(Box, { width: width, height: height, alignItems: "center", justifyContent: "center", children: _jsxs(Text, { dimColor: true, wrap: "truncate", children: ["[", fallback, "]"] }) }) }) }));
54
64
  if (onPreview === undefined)
55
65
  return preview;
56
66
  return (_jsx(Box, { onClick: event => {
@@ -64,8 +64,20 @@ export type AskUserQuestionPanelProps = {
64
64
  readonly onAnswer: (selection: QuestionSelection) => void;
65
65
  /** Esc on the first question / Ctrl+C — aborts the whole ask. */
66
66
  readonly onCancel: () => void;
67
- /** Esc on later questions — navigates to the previous question. */
67
+ /**
68
+ * Esc, when the host wants to decide back-vs-cancel from the live store.
69
+ * A same-batch → then Esc still runs on the panel mounted for question 1,
70
+ * whose `onBack` is absent; this callback sees that → already advanced.
71
+ */
72
+ readonly onEscape?: (draft: QuestionDraft) => void;
73
+ /** Esc / ← on later questions — navigates to the previous question. */
68
74
  readonly onBack?: (draft: QuestionDraft) => void;
75
+ /**
76
+ * → — navigates to the next question without submitting. On the free-text
77
+ * row this only fires when the caret is already at the end, so ←/→ keep
78
+ * editing the answer.
79
+ */
80
+ readonly onForward?: (draft: QuestionDraft) => void;
69
81
  /**
70
82
  * Test seam: clipboard reader for the Ctrl+V paste arm. Defaults to the
71
83
  * real cross-platform reader (PowerShell/pbpaste/wl-paste…); headless
@@ -89,5 +101,5 @@ export type AskUserQuestionPanelProps = {
89
101
  * pointer, so an unclickable row would just eat a line. */
90
102
  readonly fullscreen?: boolean;
91
103
  };
92
- export declare function AskUserQuestionPanel({ question, position, total, answered, initialDraft, onAnswer, onCancel, onBack, readClipboardOverride, collapsed, onExpand, onToggleFold, fullscreen, }: AskUserQuestionPanelProps): React.ReactNode;
104
+ export declare function AskUserQuestionPanel({ question, position, total, answered, initialDraft, onAnswer, onCancel, onEscape, onBack, onForward, readClipboardOverride, collapsed, onExpand, onToggleFold, fullscreen, }: AskUserQuestionPanelProps): React.ReactNode;
93
105
  //# sourceMappingURL=AskUserQuestionPanel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AskUserQuestionPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/AskUserQuestionPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAMtF,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAkB5E,MAAM,MAAM,yBAAyB,GAAG;IACtC,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,WAAW,CAAC,EAAE,OAAO,CAAA;QAC9B;;oEAE4D;QAC5D,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;QAClC;;qEAE6D;QAC7D,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;QAC5C;0EACkE;QAClE,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAA;IACrC,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;IAC7B,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAChD;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;IAC7D;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IAClC;;gEAE4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAC9B,CAAA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,qBAAqB,EACrB,SAAiB,EACjB,QAAQ,EACR,YAAY,EACZ,UAAkB,GACnB,EAAE,yBAAyB,GAAG,KAAK,CAAC,SAAS,CAsmB7C"}
1
+ {"version":3,"file":"AskUserQuestionPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/AskUserQuestionPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAMtF,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAuB5E,MAAM,MAAM,yBAAyB,GAAG;IACtC,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,WAAW,CAAC,EAAE,OAAO,CAAA;QAC9B;;oEAE4D;QAC5D,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;QAClC;;qEAE6D;QAC7D,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;QAC5C;0EACkE;QAClE,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAA;IACrC,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAClD,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAChD;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IACnD;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;IAC7D;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IAClC;;gEAE4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAC9B,CAAA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,SAAS,EACT,qBAAqB,EACrB,SAAiB,EACjB,QAAQ,EACR,YAAY,EACZ,UAAkB,GACnB,EAAE,yBAAyB,GAAG,KAAK,CAAC,SAAS,CA2pB7C"}
@@ -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"}