@deepseek-harness-tui/dsh-tui 0.10.2 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. package/README.md +175 -123
  2. package/bin/dsh-tui.js +748 -22
  3. package/cordis.patch.yml +42 -13
  4. package/cordis.yml +5 -2
  5. package/lib/types/activityPrefs.d.ts +24 -0
  6. package/lib/types/activityPrefs.d.ts.map +1 -1
  7. package/lib/types/activityPrefs.js +50 -1
  8. package/lib/types/adapter/channel/session-projection.d.ts.map +1 -1
  9. package/lib/types/adapter/channel/session-projection.js +2 -0
  10. package/lib/types/adapter/channel/state.d.ts.map +1 -1
  11. package/lib/types/adapter/channel/state.js +3 -1
  12. package/lib/types/adapter/channel/ui-policy.d.ts +4 -1
  13. package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
  14. package/lib/types/adapter/channel/ui-policy.js +6 -2
  15. package/lib/types/adapter/kernel/host-facade.d.ts.map +1 -1
  16. package/lib/types/adapter/kernel/host-facade.js +1 -0
  17. package/lib/types/adapter/kernel/replay.d.ts.map +1 -1
  18. package/lib/types/adapter/kernel/replay.js +3 -0
  19. package/lib/types/adapter/kernel/runtime.d.ts.map +1 -1
  20. package/lib/types/adapter/kernel/runtime.js +2 -0
  21. package/lib/types/adapter/kernel/slices/workspace.d.ts.map +1 -1
  22. package/lib/types/adapter/kernel/slices/workspace.js +1 -0
  23. package/lib/types/adapter/ports/channel-ui.d.ts +29 -5
  24. package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
  25. package/lib/types/adapter/ports/channel-view.d.ts +66 -12
  26. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
  27. package/lib/types/adapter/ports/channel-workspace.d.ts +23 -0
  28. package/lib/types/adapter/ports/channel-workspace.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/adapter/ports/workspace.d.ts +2 -0
  32. package/lib/types/adapter/ports/workspace.d.ts.map +1 -1
  33. package/lib/types/adapter/upstream/workspace-driver.d.ts.map +1 -1
  34. package/lib/types/adapter/upstream/workspace-driver.js +10 -2
  35. package/lib/types/commands.d.ts.map +1 -1
  36. package/lib/types/commands.js +1 -0
  37. package/lib/types/components/ActivityLine.d.ts +7 -2
  38. package/lib/types/components/ActivityLine.d.ts.map +1 -1
  39. package/lib/types/components/ActivityLine.js +0 -8
  40. package/lib/types/components/ContextBarView.d.ts +15 -7
  41. package/lib/types/components/ContextBarView.d.ts.map +1 -1
  42. package/lib/types/components/ContextBarView.js +26 -22
  43. package/lib/types/components/ImagePreviewOverlay.d.ts.map +1 -1
  44. package/lib/types/components/ImagePreviewOverlay.js +11 -5
  45. package/lib/types/components/Markdown.d.ts +11 -1
  46. package/lib/types/components/Markdown.d.ts.map +1 -1
  47. package/lib/types/components/Markdown.js +20 -2
  48. package/lib/types/components/MermaidDiagram.d.ts +13 -0
  49. package/lib/types/components/MermaidDiagram.d.ts.map +1 -0
  50. package/lib/types/components/MermaidDiagram.js +61 -0
  51. package/lib/types/components/MessageList.d.ts +26 -1
  52. package/lib/types/components/MessageList.d.ts.map +1 -1
  53. package/lib/types/components/MessageList.js +74 -8
  54. package/lib/types/components/PageMargin.d.ts +1 -1
  55. package/lib/types/components/PromptInput.d.ts +37 -1
  56. package/lib/types/components/PromptInput.d.ts.map +1 -1
  57. package/lib/types/components/PromptInput.js +291 -30
  58. package/lib/types/components/ScrollbarGutter.d.ts +20 -5
  59. package/lib/types/components/ScrollbarGutter.d.ts.map +1 -1
  60. package/lib/types/components/ScrollbarGutter.js +88 -10
  61. package/lib/types/components/SplitDiffView.d.ts.map +1 -1
  62. package/lib/types/components/SplitDiffView.js +2 -1
  63. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  64. package/lib/types/components/StreamingMarkdown.js +30 -28
  65. package/lib/types/components/SubagentCard.d.ts.map +1 -1
  66. package/lib/types/components/SubagentCard.js +12 -6
  67. package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
  68. package/lib/types/components/SubagentDetailScene.js +8 -3
  69. package/lib/types/components/Tooltip.d.ts.map +1 -1
  70. package/lib/types/components/Tooltip.js +45 -7
  71. package/lib/types/components/design-system/HintLine.d.ts +1 -2
  72. package/lib/types/components/design-system/HintLine.d.ts.map +1 -1
  73. package/lib/types/components/design-system/HintLine.js +1 -2
  74. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -1
  75. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  76. package/lib/types/components/messages/AssistantThinkingMessage.js +2 -1
  77. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +2 -2
  78. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  79. package/lib/types/components/messages/AssistantToolUseMessage.js +30 -26
  80. package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -1
  81. package/lib/types/components/messages/UserPromptMessage.js +5 -7
  82. package/lib/types/components/messages/useImageInspection.d.ts.map +1 -1
  83. package/lib/types/components/messages/useImageInspection.js +19 -9
  84. package/lib/types/components/promptDraftCache.d.ts +102 -0
  85. package/lib/types/components/promptDraftCache.d.ts.map +1 -0
  86. package/lib/types/components/promptDraftCache.js +76 -0
  87. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +17 -1
  88. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
  89. package/lib/types/components/questions/AskUserQuestionPanel.js +40 -7
  90. package/lib/types/components/questions/QuestionMinimizedBar.d.ts +12 -0
  91. package/lib/types/components/questions/QuestionMinimizedBar.d.ts.map +1 -0
  92. package/lib/types/components/questions/QuestionMinimizedBar.js +43 -0
  93. package/lib/types/components/sessions/SessionListRow.d.ts +23 -1
  94. package/lib/types/components/sessions/SessionListRow.d.ts.map +1 -1
  95. package/lib/types/components/sessions/SessionListRow.js +52 -5
  96. package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts +49 -0
  97. package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts.map +1 -0
  98. package/lib/types/components/workspaces/HomeWorkspaceRow.js +50 -0
  99. package/lib/types/dsh-adapter/activity-store.d.ts +221 -0
  100. package/lib/types/dsh-adapter/activity-store.d.ts.map +1 -0
  101. package/lib/types/dsh-adapter/activity-store.js +359 -0
  102. package/lib/types/dsh-adapter/bundled-presets.d.ts +10 -0
  103. package/lib/types/dsh-adapter/bundled-presets.d.ts.map +1 -0
  104. package/lib/types/dsh-adapter/bundled-presets.js +80 -0
  105. package/lib/types/dsh-adapter/channel/action-readiness.d.ts +1 -1
  106. package/lib/types/dsh-adapter/channel/action-readiness.d.ts.map +1 -1
  107. package/lib/types/dsh-adapter/channel/action-readiness.js +3 -0
  108. package/lib/types/dsh-adapter/channel/agent-view-projection.d.ts +1 -1
  109. package/lib/types/dsh-adapter/channel/agent-view-projection.d.ts.map +1 -1
  110. package/lib/types/dsh-adapter/channel/agent-view-projection.js +19 -2
  111. package/lib/types/dsh-adapter/channel/background-action.d.ts +1 -1
  112. package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -1
  113. package/lib/types/dsh-adapter/channel/background-action.js +53 -29
  114. package/lib/types/dsh-adapter/channel/binding-events.d.ts +8 -6
  115. package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
  116. package/lib/types/dsh-adapter/channel/binding-events.js +5 -4
  117. package/lib/types/dsh-adapter/channel/binding.d.ts +19 -2
  118. package/lib/types/dsh-adapter/channel/binding.d.ts.map +1 -1
  119. package/lib/types/dsh-adapter/channel/binding.js +78 -18
  120. package/lib/types/dsh-adapter/channel/compaction.d.ts +0 -1
  121. package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
  122. package/lib/types/dsh-adapter/channel/compaction.js +0 -2
  123. package/lib/types/dsh-adapter/channel/composer-images.d.ts +5 -0
  124. package/lib/types/dsh-adapter/channel/composer-images.d.ts.map +1 -1
  125. package/lib/types/dsh-adapter/channel/composer-images.js +105 -6
  126. package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts +8 -0
  127. package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts.map +1 -1
  128. package/lib/types/dsh-adapter/channel/context-bookkeeping.js +3 -2
  129. package/lib/types/dsh-adapter/channel/ide-selection.d.ts +58 -0
  130. package/lib/types/dsh-adapter/channel/ide-selection.d.ts.map +1 -0
  131. package/lib/types/dsh-adapter/channel/ide-selection.js +226 -0
  132. package/lib/types/dsh-adapter/channel/input-delivery.d.ts +6 -1
  133. package/lib/types/dsh-adapter/channel/input-delivery.d.ts.map +1 -1
  134. package/lib/types/dsh-adapter/channel/input-delivery.js +9 -1
  135. package/lib/types/dsh-adapter/channel/local-actions.d.ts +3 -19
  136. package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -1
  137. package/lib/types/dsh-adapter/channel/local-actions.js +2 -1
  138. package/lib/types/dsh-adapter/channel/model-actions.d.ts +4 -1
  139. package/lib/types/dsh-adapter/channel/model-actions.d.ts.map +1 -1
  140. package/lib/types/dsh-adapter/channel/model-actions.js +82 -6
  141. package/lib/types/dsh-adapter/channel/model-switch.d.ts +1 -2
  142. package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -1
  143. package/lib/types/dsh-adapter/channel/model-switch.js +49 -31
  144. package/lib/types/dsh-adapter/channel/projection.d.ts +4 -0
  145. package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
  146. package/lib/types/dsh-adapter/channel/projection.js +29 -19
  147. package/lib/types/dsh-adapter/channel/reports.d.ts.map +1 -1
  148. package/lib/types/dsh-adapter/channel/reports.js +4 -12
  149. package/lib/types/dsh-adapter/channel/session-adoption.d.ts +1 -1
  150. package/lib/types/dsh-adapter/channel/session-adoption.d.ts.map +1 -1
  151. package/lib/types/dsh-adapter/channel/session-adoption.js +1 -0
  152. package/lib/types/dsh-adapter/channel/session-fork.d.ts.map +1 -1
  153. package/lib/types/dsh-adapter/channel/session-fork.js +26 -2
  154. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +4 -1
  155. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -1
  156. package/lib/types/dsh-adapter/channel/session-live-adoption.js +2 -0
  157. package/lib/types/dsh-adapter/channel/session-metadata.d.ts +10 -0
  158. package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
  159. package/lib/types/dsh-adapter/channel/session-metadata.js +6 -4
  160. package/lib/types/dsh-adapter/channel/session-reset.d.ts +1 -1
  161. package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -1
  162. package/lib/types/dsh-adapter/channel/session-reset.js +0 -1
  163. package/lib/types/dsh-adapter/channel/session-resume.d.ts +12 -3
  164. package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
  165. package/lib/types/dsh-adapter/channel/session-resume.js +292 -94
  166. package/lib/types/dsh-adapter/channel/session-rewind.d.ts.map +1 -1
  167. package/lib/types/dsh-adapter/channel/session-rewind.js +34 -16
  168. package/lib/types/dsh-adapter/channel/session-tree-actions.d.ts.map +1 -1
  169. package/lib/types/dsh-adapter/channel/session-tree-actions.js +19 -3
  170. package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
  171. package/lib/types/dsh-adapter/channel/settings-host.js +4 -3
  172. package/lib/types/dsh-adapter/channel/state.d.ts +6 -1
  173. package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
  174. package/lib/types/dsh-adapter/channel/state.js +3 -3
  175. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +21 -1
  176. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
  177. package/lib/types/dsh-adapter/channel/subagent-projection.js +173 -6
  178. package/lib/types/dsh-adapter/channel/transcript.d.ts.map +1 -1
  179. package/lib/types/dsh-adapter/channel/transcript.js +6 -12
  180. package/lib/types/dsh-adapter/channel/types.d.ts +6 -1
  181. package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -1
  182. package/lib/types/dsh-adapter/channel/workspace-actions.d.ts +4 -1
  183. package/lib/types/dsh-adapter/channel/workspace-actions.d.ts.map +1 -1
  184. package/lib/types/dsh-adapter/channel/workspace-actions.js +41 -1
  185. package/lib/types/dsh-adapter/channel.d.ts +1 -1
  186. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  187. package/lib/types/dsh-adapter/channel.js +82 -20
  188. package/lib/types/dsh-adapter/compat/index.d.ts +1 -1
  189. package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -1
  190. package/lib/types/dsh-adapter/compat/index.js +1 -1
  191. package/lib/types/dsh-adapter/compat/messages.d.ts +15 -0
  192. package/lib/types/dsh-adapter/compat/messages.d.ts.map +1 -0
  193. package/lib/types/dsh-adapter/compat/messages.js +15 -0
  194. package/lib/types/dsh-adapter/compat/sessionLog.d.ts +18 -0
  195. package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -1
  196. package/lib/types/dsh-adapter/compat/sessionLog.js +18 -3
  197. package/lib/types/dsh-adapter/compat/settings.d.ts +35 -0
  198. package/lib/types/dsh-adapter/compat/settings.d.ts.map +1 -0
  199. package/lib/types/dsh-adapter/compat/settings.js +57 -0
  200. package/lib/types/dsh-adapter/compat/shell.d.ts +25 -0
  201. package/lib/types/dsh-adapter/compat/shell.d.ts.map +1 -0
  202. package/lib/types/dsh-adapter/compat/shell.js +11 -0
  203. package/lib/types/dsh-adapter/contract.d.ts +5 -4
  204. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  205. package/lib/types/dsh-adapter/contract.js +17 -6
  206. package/lib/types/dsh-adapter/ide-channel.d.ts +224 -0
  207. package/lib/types/dsh-adapter/ide-channel.d.ts.map +1 -0
  208. package/lib/types/dsh-adapter/ide-channel.js +556 -0
  209. package/lib/types/dsh-adapter/index.d.ts +18 -3
  210. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  211. package/lib/types/dsh-adapter/index.js +32 -5
  212. package/lib/types/dsh-adapter/plugin.d.ts +4 -1
  213. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  214. package/lib/types/dsh-adapter/plugin.js +197 -49
  215. package/lib/types/dsh-adapter/preset-resolution.d.ts +8 -0
  216. package/lib/types/dsh-adapter/preset-resolution.d.ts.map +1 -1
  217. package/lib/types/dsh-adapter/preset-resolution.js +10 -0
  218. package/lib/types/dsh-adapter/session-mount-heartbeat.d.ts +53 -0
  219. package/lib/types/dsh-adapter/session-mount-heartbeat.d.ts.map +1 -0
  220. package/lib/types/dsh-adapter/session-mount-heartbeat.js +100 -0
  221. package/lib/types/dsh-adapter/sessionTree.d.ts.map +1 -1
  222. package/lib/types/dsh-adapter/sessionTree.js +3 -2
  223. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
  224. package/lib/types/dsh-adapter/settings-sections.js +7 -4
  225. package/lib/types/dsh-adapter/subagents.d.ts +16 -3
  226. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
  227. package/lib/types/dsh-adapter/subagents.js +92 -29
  228. package/lib/types/dsh-adapter/workspaces.d.ts +46 -3
  229. package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -1
  230. package/lib/types/dsh-adapter/workspaces.js +116 -0
  231. package/lib/types/effortPrefs.d.ts +15 -3
  232. package/lib/types/effortPrefs.d.ts.map +1 -1
  233. package/lib/types/effortPrefs.js +37 -3
  234. package/lib/types/history.d.ts +13 -1
  235. package/lib/types/history.d.ts.map +1 -1
  236. package/lib/types/history.js +15 -2
  237. package/lib/types/homePrefs.d.ts +15 -0
  238. package/lib/types/homePrefs.d.ts.map +1 -0
  239. package/lib/types/homePrefs.js +53 -0
  240. package/lib/types/i18n.d.ts +347 -297
  241. package/lib/types/i18n.d.ts.map +1 -1
  242. package/lib/types/i18n.js +133 -85
  243. package/lib/types/ink/colorize.d.ts +10 -0
  244. package/lib/types/ink/colorize.d.ts.map +1 -1
  245. package/lib/types/ink/colorize.js +21 -0
  246. package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
  247. package/lib/types/ink/components/ScrollBox.js +12 -1
  248. package/lib/types/ink/dom.d.ts +1 -0
  249. package/lib/types/ink/dom.d.ts.map +1 -1
  250. package/lib/types/ink/hooks/use-copy-on-select.d.ts +5 -1
  251. package/lib/types/ink/hooks/use-copy-on-select.d.ts.map +1 -1
  252. package/lib/types/ink/hooks/use-copy-on-select.js +15 -1
  253. package/lib/types/ink/ink.d.ts.map +1 -1
  254. package/lib/types/ink/ink.js +36 -1
  255. package/lib/types/ink/log-update.d.ts.map +1 -1
  256. package/lib/types/ink/log-update.js +19 -1
  257. package/lib/types/ink/output.d.ts +10 -1
  258. package/lib/types/ink/output.d.ts.map +1 -1
  259. package/lib/types/ink/output.js +109 -17
  260. package/lib/types/ink/render-border.d.ts +6 -1
  261. package/lib/types/ink/render-border.d.ts.map +1 -1
  262. package/lib/types/ink/render-border.js +25 -9
  263. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  264. package/lib/types/ink/render-node-to-output.js +48 -6
  265. package/lib/types/ink/renderer.d.ts +6 -0
  266. package/lib/types/ink/renderer.d.ts.map +1 -1
  267. package/lib/types/ink/renderer.js +2 -1
  268. package/lib/types/ink/selection.d.ts +88 -0
  269. package/lib/types/ink/selection.d.ts.map +1 -1
  270. package/lib/types/ink/selection.js +164 -0
  271. package/lib/types/ink/sixel-graphics.d.ts +19 -1
  272. package/lib/types/ink/sixel-graphics.d.ts.map +1 -1
  273. package/lib/types/ink/sixel-graphics.js +124 -12
  274. package/lib/types/ink/terminal-image.d.ts +18 -1
  275. package/lib/types/ink/terminal-image.d.ts.map +1 -1
  276. package/lib/types/ink/terminal.d.ts +17 -0
  277. package/lib/types/ink/terminal.d.ts.map +1 -1
  278. package/lib/types/ink/terminal.js +20 -1
  279. package/lib/types/screens/Chat.d.ts +20 -1
  280. package/lib/types/screens/Chat.d.ts.map +1 -1
  281. package/lib/types/screens/Chat.js +296 -76
  282. package/lib/types/screens/SessionSupervisor.d.ts +84 -0
  283. package/lib/types/screens/SessionSupervisor.d.ts.map +1 -0
  284. package/lib/types/screens/SessionSupervisor.js +350 -0
  285. package/lib/types/screens/SessionTree.js +2 -2
  286. package/lib/types/screens/Settings.d.ts.map +1 -1
  287. package/lib/types/screens/Settings.js +32 -9
  288. package/lib/types/screens/StatusLine.d.ts +18 -1
  289. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  290. package/lib/types/screens/StatusLine.js +38 -19
  291. package/lib/types/screens/StatusMetrics.d.ts +79 -22
  292. package/lib/types/screens/StatusMetrics.d.ts.map +1 -1
  293. package/lib/types/screens/StatusMetrics.js +153 -88
  294. package/lib/types/screens/sessionSupervisor/model.d.ts +83 -0
  295. package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -0
  296. package/lib/types/screens/sessionSupervisor/model.js +69 -0
  297. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts +120 -0
  298. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -0
  299. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +593 -0
  300. package/lib/types/sessionMounts.d.ts +272 -0
  301. package/lib/types/sessionMounts.d.ts.map +1 -0
  302. package/lib/types/sessionMounts.js +706 -0
  303. package/lib/types/sessions/format.d.ts.map +1 -1
  304. package/lib/types/sessions/format.js +4 -1
  305. package/lib/types/sessions/resumeFailure.d.ts +38 -0
  306. package/lib/types/sessions/resumeFailure.d.ts.map +1 -0
  307. package/lib/types/sessions/resumeFailure.js +58 -0
  308. package/lib/types/terminal-utils/mermaid.d.ts +44 -0
  309. package/lib/types/terminal-utils/mermaid.d.ts.map +1 -0
  310. package/lib/types/terminal-utils/mermaid.js +83 -0
  311. package/lib/types/tips.d.ts.map +1 -1
  312. package/lib/types/tips.js +175 -19
  313. package/lib/types/tuiDisplayPrefs.d.ts +7 -9
  314. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
  315. package/lib/types/tuiDisplayPrefs.js +31 -28
  316. package/lib/types/update.d.ts +61 -0
  317. package/lib/types/update.d.ts.map +1 -1
  318. package/lib/types/update.js +194 -0
  319. package/lib/types/utils/fold-long-lines.d.ts +1 -1
  320. package/lib/types/utils/fold-long-lines.js +1 -1
  321. package/lib/types/utils/imageResize.d.ts +90 -0
  322. package/lib/types/utils/imageResize.d.ts.map +1 -0
  323. package/lib/types/utils/imageResize.js +272 -0
  324. package/lib/types/utils/keymap.d.ts +5 -1
  325. package/lib/types/utils/keymap.d.ts.map +1 -1
  326. package/lib/types/utils/keymap.js +23 -0
  327. package/lib/types/working-activity.d.ts +10 -9
  328. package/lib/types/working-activity.d.ts.map +1 -1
  329. package/lib/types/working-activity.js +17 -10
  330. package/lib/types/workspaces.d.ts +2 -1
  331. package/lib/types/workspaces.d.ts.map +1 -1
  332. package/lib/types/workspaces.js +1 -1
  333. package/node_modules/@deepseek-harness-tui/dsh-auth/package.json +10 -10
  334. package/package.json +126 -105
  335. package/presets/liangshen/.dsh-tui-managed.json +1 -1
  336. package/presets/liangshen/agent.cordis.yml +15 -0
  337. package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +0 -19
  338. package/lib/types/components/design-system/KeyboardShortcutHint.d.ts.map +0 -1
  339. package/lib/types/components/design-system/KeyboardShortcutHint.js +0 -14
  340. package/lib/types/dsh-adapter/channel/activity.d.ts +0 -20
  341. package/lib/types/dsh-adapter/channel/activity.d.ts.map +0 -1
  342. package/lib/types/dsh-adapter/channel/activity.js +0 -113
  343. package/lib/types/screens/AgentView.d.ts +0 -23
  344. package/lib/types/screens/AgentView.d.ts.map +0 -1
  345. package/lib/types/screens/AgentView.js +0 -546
  346. package/lib/types/screens/SessionBrowser.d.ts +0 -42
  347. package/lib/types/screens/SessionBrowser.d.ts.map +0 -1
  348. package/lib/types/screens/SessionBrowser.js +0 -911
  349. package/lib/types/terminal-utils/terminal.d.ts +0 -18
  350. package/lib/types/terminal-utils/terminal.d.ts.map +0 -1
  351. package/lib/types/terminal-utils/terminal.js +0 -96
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import type { ClickEvent } from '../../ink/events/click-event.js';
3
3
  import type { ContextMenuEvent } from '../../ink/events/context-menu-event.js';
4
4
  import type { SessionSummary } from '../../dsh-adapter/sessions/index.js';
5
+ import type { AgentViewStatus } from '../../adapter/ports/channel-view.js';
5
6
  /**
6
7
  * One session in the browser's list: a title line and a metadata line.
7
8
  *
@@ -15,7 +16,7 @@ import type { SessionSummary } from '../../dsh-adapter/sessions/index.js';
15
16
  * stay exactly two lines at every terminal width, and a row that wraps
16
17
  * destroys the alignment that lets the eye scan a list at all.
17
18
  */
18
- export declare function SessionListRow({ session, width, depth, focused, pinned, now, onClick, onContextMenu, onTogglePin, }: {
19
+ export declare function SessionListRow({ session, width, depth, focused, pinned, now, onClick, onContextMenu, onTogglePin, liveStatus, current, occupiedPid, spinner, }: {
19
20
  session: SessionSummary;
20
21
  /** Columns available to the row, indentation included. */
21
22
  width: number;
@@ -32,5 +33,26 @@ export declare function SessionListRow({ session, width, depth, focused, pinned,
32
33
  onContextMenu?(event: ContextMenuEvent): void;
33
34
  /** 点击行内 ★/☆(fullscreen):切换固定状态,不冒泡成"打开会话"。 */
34
35
  onTogglePin?(): void;
36
+ /**
37
+ * Live status of an agent THIS terminal is running, when there is one.
38
+ * `working` animates instead of holding a static glyph, so a busy session
39
+ * is legible at a glance — the same vocabulary the session overview uses,
40
+ * which is what lets the two surfaces read as one feature.
41
+ */
42
+ liveStatus?: AgentViewStatus;
43
+ /** True when this is the session the terminal is attached to. */
44
+ current?: boolean;
45
+ /**
46
+ * The pid of ANOTHER TUI terminal holding this session, when one does. The
47
+ * row turns red and says so: the session stays visible but cannot be
48
+ * entered, which is the honest presentation of a claim this process must
49
+ * not break. Undefined means free, or already ours.
50
+ */
51
+ occupiedPid?: number;
52
+ /** Shared animation clock for the working glyph. */
53
+ spinner?: {
54
+ frame: number;
55
+ time: number;
56
+ };
35
57
  }): React.ReactNode;
36
58
  //# sourceMappingURL=SessionListRow.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SessionListRow.d.ts","sourceRoot":"","sources":["../../../../src/components/sessions/SessionListRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAGvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AAU9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAA;AAEzE;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,KAAK,EACL,KAAK,EACL,OAAO,EACP,MAAM,EACN,GAAG,EACH,OAAO,EACP,aAAa,EACb,WAAW,GACZ,EAAE;IACD,OAAO,EAAE,cAAc,CAAA;IACvB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAA;IACb,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,sEAAsE;IACtE,MAAM,EAAE,OAAO,CAAA;IACf,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAA;IACX,4CAA4C;IAC5C,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IACjC,gDAAgD;IAChD,aAAa,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC7C,8CAA8C;IAC9C,WAAW,CAAC,IAAI,IAAI,CAAA;CACrB,GAAG,KAAK,CAAC,SAAS,CA8ElB"}
1
+ {"version":3,"file":"SessionListRow.d.ts","sourceRoot":"","sources":["../../../../src/components/sessions/SessionListRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAGvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AAY9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAA;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAA;AA0B1E;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,KAAK,EACL,KAAK,EACL,OAAO,EACP,MAAM,EACN,GAAG,EACH,OAAO,EACP,aAAa,EACb,WAAW,EACX,UAAU,EACV,OAAO,EACP,WAAW,EACX,OAAO,GACR,EAAE;IACD,OAAO,EAAE,cAAc,CAAA;IACvB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAA;IACb,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,sEAAsE;IACtE,MAAM,EAAE,OAAO,CAAA;IACf,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAA;IACX,4CAA4C;IAC5C,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IACjC,gDAAgD;IAChD,aAAa,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC7C,8CAA8C;IAC9C,WAAW,CAAC,IAAI,IAAI,CAAA;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,oDAAoD;IACpD,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAC1C,GAAG,KAAK,CAAC,SAAS,CA6HlB"}
@@ -3,7 +3,31 @@ import { useState } from 'react';
3
3
  import { Box, Text } from '../../ui.js';
4
4
  import { t } from '../../i18n.js';
5
5
  import { useTooltip } from '../Tooltip.js';
6
+ import { SpinnerGlyph } from '../Spinner/SpinnerGlyph.js';
7
+ import { stringWidth } from '../../ink/stringWidth.js';
6
8
  import { formatAbsolute, formatBytes, formatWhen, kindMark, titleColor, truncateWidth, } from '../../sessions/format.js';
9
+ /**
10
+ * State presentation for a session this terminal is running: one glyph and one
11
+ * theme colour per status, matching the session overview's own vocabulary so
12
+ * the same session never looks like two different things on two screens.
13
+ * `stopped` is the "not running here" spelling and draws dim.
14
+ */
15
+ const LIVE_STATUS_GLYPH = {
16
+ 'needs-input': '✻',
17
+ working: '✽',
18
+ completed: '✓',
19
+ failed: '✕',
20
+ idle: '∙',
21
+ stopped: '∙',
22
+ };
23
+ const LIVE_STATUS_COLOR = {
24
+ 'needs-input': 'warning',
25
+ working: 'suggestion',
26
+ completed: 'success',
27
+ failed: 'error',
28
+ idle: undefined,
29
+ stopped: undefined,
30
+ };
7
31
  /**
8
32
  * One session in the browser's list: a title line and a metadata line.
9
33
  *
@@ -17,7 +41,7 @@ import { formatAbsolute, formatBytes, formatWhen, kindMark, titleColor, truncate
17
41
  * stay exactly two lines at every terminal width, and a row that wraps
18
42
  * destroys the alignment that lets the eye scan a list at all.
19
43
  */
20
- export function SessionListRow({ session, width, depth, focused, pinned, now, onClick, onContextMenu, onTogglePin, }) {
44
+ export function SessionListRow({ session, width, depth, focused, pinned, now, onClick, onContextMenu, onTogglePin, liveStatus, current, occupiedPid, spinner, }) {
21
45
  const indent = depth * 2;
22
46
  // Two cells for the focus marker, plus the indent for a nested run.
23
47
  const body = Math.max(8, width - 2 - indent);
@@ -30,10 +54,28 @@ export function SessionListRow({ session, width, depth, focused, pinned, now, on
30
54
  // and never the working directory, so that pair is always new information
31
55
  // for telling look-alike sessions apart.
32
56
  const titleText = session.label ?? session.title.text;
33
- const titleBudget = body - 2 - (mark === undefined ? 0 : 2);
34
- const shownTitle = truncateWidth(titleText, titleBudget);
57
+ /**
58
+ * The state cell holds EXACTLY two columns on every row, occupied or not,
59
+ * for the same reason the pin slot does: a column that appears only when a
60
+ * session is busy would shift every title on screen each time one starts or
61
+ * stops working.
62
+ */
63
+ const occupied = occupiedPid !== undefined;
64
+ const stateGlyph = occupied ? '⊘' : LIVE_STATUS_GLYPH[liveStatus ?? 'stopped'];
65
+ const stateColor = occupied
66
+ ? 'error'
67
+ : liveStatus === undefined
68
+ ? undefined
69
+ : LIVE_STATUS_COLOR[liveStatus];
70
+ const occupiedText = occupied ? ` ${t('supervisor-occupied-badge', { pid: occupiedPid })}` : '';
71
+ const currentText = current === true ? ` ${t('supervisor-current')}` : '';
72
+ const titleBudget = body - 2 - (mark === undefined ? 0 : 2) - 2
73
+ - stringWidth(occupiedText) - stringWidth(currentText);
74
+ const shownTitle = truncateWidth(titleText, Math.max(4, titleBudget));
35
75
  const titleTooltip = useTooltip(() => {
36
76
  const parts = [];
77
+ if (occupied)
78
+ parts.push(t('session-mount-occupied-short', { pid: occupiedPid }));
37
79
  if (shownTitle !== titleText)
38
80
  parts.push(titleText);
39
81
  parts.push(formatAbsolute(session.updatedAt));
@@ -52,10 +94,15 @@ export function SessionListRow({ session, width, depth, focused, pinned, now, on
52
94
  if (session.childCount > 0 && depth === 0) {
53
95
  facts.push(t('session-children', { n: session.childCount }));
54
96
  }
55
- return (_jsxs(Box, { flexDirection: "column", flexShrink: 0, onClick: onClick, onContextMenu: onContextMenu, onMouseEnter: onClick !== undefined || onContextMenu !== undefined ? () => setHovered(true) : undefined, onMouseLeave: onClick !== undefined || onContextMenu !== undefined ? () => setHovered(false) : undefined, backgroundColor: focused || hovered ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { children: [_jsx(Text, { color: focused ? 'suggestion' : 'subtle', children: `${' '.repeat(indent)}${focused ? '❯ ' : ' '}` }), _jsx(Box, { ...pinTooltip, onClick: onTogglePin === undefined ? undefined : (event) => {
97
+ return (_jsxs(Box, { flexDirection: "column", flexShrink: 0, onClick: onClick, onContextMenu: onContextMenu, onMouseEnter: onClick !== undefined || onContextMenu !== undefined ? () => setHovered(true) : undefined, onMouseLeave: onClick !== undefined || onContextMenu !== undefined ? () => setHovered(false) : undefined,
98
+ // Hover is the BLUE prompt — pointer feedback and nothing else. Selection
99
+ // is green and never blue: a row the keyboard cursor is on must not look
100
+ // like a row the mouse happens to be over, so the two never share a
101
+ // background and a selected row keeps its own colour while hovered.
102
+ backgroundColor: hovered && !focused ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { children: [_jsx(Text, { color: focused ? 'success' : 'subtle', children: `${' '.repeat(indent)}${focused ? '❯ ' : ' '}` }), _jsx(Box, { ...pinTooltip, onClick: onTogglePin === undefined ? undefined : (event) => {
56
103
  // The star is a control on the row, not the row: a click here
57
104
  // toggles the pin and must never fall through to resume.
58
105
  event.stopImmediatePropagation();
59
106
  onTogglePin();
60
- }, children: _jsx(Text, { color: pinned ? 'remember' : undefined, dimColor: !pinned, children: pinned ? '★ ' : '☆ ' }) }), mark !== undefined && _jsx(Text, { color: mark.color, children: `${mark.glyph} ` }), _jsx(Box, { ...titleTooltip, children: _jsx(Text, { color: titleColor(session.title.source, focused), bold: focused, children: shownTitle }) })] }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: `${' '.repeat(indent + 2)}${truncateWidth(facts.join(' · '), body)}` }) })] }));
107
+ }, children: _jsx(Text, { color: pinned ? 'remember' : undefined, dimColor: !pinned, children: pinned ? '★ ' : '☆ ' }) }), _jsx(Box, { children: liveStatus === 'working' && !occupied && spinner !== undefined ? (_jsx(SpinnerGlyph, { frame: spinner.frame, messageColor: "suggestion", reducedMotion: false, time: spinner.time })) : (_jsx(Text, { color: stateColor, dimColor: liveStatus === undefined && !occupied, children: `${stateGlyph} ` })) }), mark !== undefined && _jsx(Text, { color: mark.color, children: `${mark.glyph} ` }), _jsx(Box, { ...titleTooltip, children: _jsx(Text, { color: occupied ? 'error' : titleColor(session.title.source, focused), bold: focused, children: shownTitle }) }), occupiedText !== '' && _jsx(Text, { color: "error", children: occupiedText }), currentText !== '' && _jsx(Text, { color: "success", children: currentText })] }), _jsx(Box, { children: _jsx(Text, { color: focused ? 'success' : undefined, dimColor: !focused, children: `${' '.repeat(indent + 2)}${truncateWidth(facts.join(' · '), body)}` }) })] }));
61
108
  }
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import type { ClickEvent } from '../../ink/events/click-event.js';
3
+ import type { ContextMenuEvent } from '../../ink/events/context-menu-event.js';
4
+ /**
5
+ * One workspace in the home screen's left rail.
6
+ *
7
+ * Two lines, like every other navigable row in this app: the name line is what
8
+ * the user named it, the detail line is where it actually is and how much is in
9
+ * it. The path is not decoration — two workspaces can carry the same basename
10
+ * (`.../a/work` and `.../b/work`), and the ledger allows duplicate titles, so
11
+ * the path is the only thing that tells them apart.
12
+ *
13
+ * Widths are resolved here rather than left to flexbox for the same reason the
14
+ * session rows resolve them: a row must be exactly two lines at every terminal
15
+ * width, and a wrapped row destroys the alignment a list is scanned by.
16
+ */
17
+ export declare function HomeWorkspaceRow({ title, path, home, sessionCount, present, selected, focused, width, onSelect, onMenu, }: {
18
+ title: string;
19
+ /** Canonical directory path recorded in the ledger. */
20
+ path: string;
21
+ /** Home directory, for collapsing the path to `~`. */
22
+ home: string;
23
+ sessionCount: number;
24
+ /** False when the recorded directory no longer exists. */
25
+ present: boolean;
26
+ /** Whether this workspace's sessions are the ones on the right. */
27
+ selected: boolean;
28
+ /** Keyboard cursor. */
29
+ focused: boolean;
30
+ /** Columns available to the row. */
31
+ width: number;
32
+ /** Left click: show this workspace's sessions (same path as Enter). */
33
+ onSelect?(event: ClickEvent): void;
34
+ /** Right click: open the workspace action menu. */
35
+ onMenu?(event: ContextMenuEvent): void;
36
+ }): React.ReactNode;
37
+ /**
38
+ * The `+` row that opens the directory picker.
39
+ *
40
+ * Deliberately the FIRST row of the rail and always clickable: adding a
41
+ * workspace is the rail's only creation action, and a control that is only
42
+ * reachable by keyboard is a control most users never find in a terminal.
43
+ */
44
+ export declare function HomeAddWorkspaceRow({ focused, width, onOpen, }: {
45
+ focused: boolean;
46
+ width: number;
47
+ onOpen?(event: ClickEvent): void;
48
+ }): React.ReactNode;
49
+ //# sourceMappingURL=HomeWorkspaceRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HomeWorkspaceRow.d.ts","sourceRoot":"","sources":["../../../../src/components/workspaces/HomeWorkspaceRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAGvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AAG9E;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,OAAO,EACP,KAAK,EACL,QAAQ,EACR,MAAM,GACP,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAA;IACZ,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAA;IAChB,mEAAmE;IACnE,QAAQ,EAAE,OAAO,CAAA;IACjB,uBAAuB;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,uEAAuE;IACvE,QAAQ,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IAClC,mDAAmD;IACnD,MAAM,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAA;CACvC,GAAG,KAAK,CAAC,SAAS,CAuClB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,OAAO,EACP,KAAK,EACL,MAAM,GACP,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CACjC,GAAG,KAAK,CAAC,SAAS,CAoBlB"}
@@ -0,0 +1,50 @@
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 { t } from '../../i18n.js';
5
+ import { formatProject, spreadRow, truncateWidth } from '../../sessions/format.js';
6
+ /**
7
+ * One workspace in the home screen's left rail.
8
+ *
9
+ * Two lines, like every other navigable row in this app: the name line is what
10
+ * the user named it, the detail line is where it actually is and how much is in
11
+ * it. The path is not decoration — two workspaces can carry the same basename
12
+ * (`.../a/work` and `.../b/work`), and the ledger allows duplicate titles, so
13
+ * the path is the only thing that tells them apart.
14
+ *
15
+ * Widths are resolved here rather than left to flexbox for the same reason the
16
+ * session rows resolve them: a row must be exactly two lines at every terminal
17
+ * width, and a wrapped row destroys the alignment a list is scanned by.
18
+ */
19
+ export function HomeWorkspaceRow({ title, path, home, sessionCount, present, selected, focused, width, onSelect, onMenu, }) {
20
+ const [hovered, setHovered] = useState(false);
21
+ const body = Math.max(8, width - 4);
22
+ // The presence marker leads the badge on purpose: `spreadRow` may truncate
23
+ // the right-hand segment, and "this directory is gone" is the one fact that
24
+ // must never be the part that gets cut (the session count is also visible in
25
+ // the pane, the missing directory is not).
26
+ const count = t('home-sessions-count', { n: sessionCount });
27
+ const badge = present ? count : `${t('home-workspace-missing')} · ${count}`;
28
+ const heading = spreadRow(`${selected ? '▣' : '▢'} ${title}`, `${selected ? '✓ ' : ''}${badge}`, body);
29
+ const detail = formatProject(path, home);
30
+ // The cursor (green) outranks the selection ring (green); both outrank the
31
+ // idle colour. Blue is not part of this ladder at all — see the background.
32
+ const headingColor = (focused || selected) ? 'success' : present ? 'text' : 'inactive';
33
+ return (_jsxs(Box, { flexDirection: "column", flexShrink: 0, paddingX: 1, onClick: onSelect, onContextMenu: onMenu, onMouseEnter: onSelect === undefined && onMenu === undefined ? undefined : () => setHovered(true), onMouseLeave: onSelect === undefined && onMenu === undefined ? undefined : () => setHovered(false),
34
+ // Hover is the BLUE prompt — pointer feedback and nothing else, so it
35
+ // never marks the focused or the selected row. Selection itself is green
36
+ // in the text, which is why this row draws no box while selected.
37
+ backgroundColor: hovered && !focused ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { height: 1, flexShrink: 0, overflow: "hidden", children: [_jsx(Text, { color: focused ? 'success' : 'subtle', children: focused ? '❯ ' : ' ' }), _jsx(Text, { color: headingColor, bold: focused || selected, children: heading.left }), _jsx(Text, { dimColor: !focused, children: `${' '.repeat(heading.gap)}${heading.right}` })] }), _jsx(Text, { color: (focused || selected) ? 'success' : undefined, dimColor: !(focused || selected), wrap: "truncate-end", children: ` ${truncateWidth(detail, body - 2)}` })] }));
38
+ }
39
+ /**
40
+ * The `+` row that opens the directory picker.
41
+ *
42
+ * Deliberately the FIRST row of the rail and always clickable: adding a
43
+ * workspace is the rail's only creation action, and a control that is only
44
+ * reachable by keyboard is a control most users never find in a terminal.
45
+ */
46
+ export function HomeAddWorkspaceRow({ focused, width, onOpen, }) {
47
+ const [hovered, setHovered] = useState(false);
48
+ const body = Math.max(8, width - 4);
49
+ return (_jsxs(Box, { flexDirection: "column", flexShrink: 0, paddingX: 1, onClick: onOpen, onMouseEnter: onOpen === undefined ? undefined : () => setHovered(true), onMouseLeave: onOpen === undefined ? undefined : () => setHovered(false), backgroundColor: focused || hovered ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { height: 1, flexShrink: 0, overflow: "hidden", children: [_jsx(Text, { color: focused ? 'suggestion' : 'subtle', children: focused ? '❯ ' : ' ' }), _jsx(Text, { color: "remember", bold: true, children: `+ ${t('home-add-workspace')}` })] }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: ` ${truncateWidth(t('home-add-hint'), body - 2)}` })] }));
50
+ }
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Session-scoped activity snapshots for the working-status line.
3
+ *
4
+ * The line's *semantics* belong to the `dsh-working-activity` plugin: it folds
5
+ * durable session events and live model frames into a **session projection**
6
+ * (`workingActivity`) that any client can read — the browser reads it, and so
7
+ * does this TUI. Consuming the projection is what removes the second tracker
8
+ * this app used to run: one semantic owner, and a value that arrives already
9
+ * scoped to a session, so a background session can no longer overwrite the line
10
+ * of the session on screen.
11
+ *
12
+ * Two properties of the transport shape this module:
13
+ *
14
+ * 1. **It is event-driven.** A value changes when a committed event folds, never
15
+ * on its own. `updatedAt` is the timestamp of the last folded event (session
16
+ * time, so it survives a restart) and `live` says whether `line` counts
17
+ * elapsed time. A renderer that wants the counter to move must derive it from
18
+ * `turnStartedAt` / `phaseStartedAt` instead of re-rendering `line`.
19
+ * 2. **The value is host data, not plugin API.** The shape below is a local
20
+ * structural copy of the plugin's wire value, the same discipline the channel
21
+ * port already applies to the activity state: this app must not import the
22
+ * plugin's internals to display a line.
23
+ * @module dsh-tui/dsh-adapter/activity-store
24
+ */
25
+ import type { Context } from '@deepseek-ai/cordis';
26
+ /** The projection key the activity plugin publishes. */
27
+ export declare const ACTIVITY_PROJECTION_KEY = "workingActivity";
28
+ /** Phases the plugin's line can be in (`idle` renders nothing). */
29
+ export type ActivityPhase = 'idle' | 'waiting' | 'thinking' | 'tool' | 'done';
30
+ /**
31
+ * One session's activity value, as the plugin publishes it.
32
+ *
33
+ * Structural copy of `dsh-working-activity`'s `WorkingActivityView`.
34
+ */
35
+ export interface ActivityView {
36
+ readonly phase: ActivityPhase;
37
+ /** The line as the host rendered it at `updatedAt`. */
38
+ readonly line: string;
39
+ /** Whether `line` counts elapsed time (a renderer ticks it from the stamps). */
40
+ readonly live: boolean;
41
+ /** Tool action verb, when the line describes a running tool. */
42
+ readonly label?: string;
43
+ /** Tool detail fragment (path / command / pattern), when there is one. */
44
+ readonly detail?: string;
45
+ /** The playful phrase or `⏵` self-narration currently shown, when any. */
46
+ readonly phrase?: string;
47
+ /** Tools completed in the current turn. */
48
+ readonly toolCount: number;
49
+ /** Wall clock the current phase began. */
50
+ readonly phaseStartedAt: number;
51
+ /** Wall clock the current turn began (0 when no turn has started). */
52
+ readonly turnStartedAt: number;
53
+ /** Timestamp of the last folded event — the value's freshness signal. */
54
+ readonly updatedAt: number;
55
+ /** Language the line was rendered in. */
56
+ readonly lang: 'zh' | 'en';
57
+ }
58
+ /** The slice of the host projection registry this module uses. */
59
+ export interface ProjectionRegistryLike {
60
+ onChanged(listener: (session: {
61
+ readonly id: unknown;
62
+ }, key: string, value: unknown, seq: number) => void): () => void;
63
+ snapshot(session: unknown, keys?: readonly string[]): {
64
+ readonly values: Record<string, unknown>;
65
+ };
66
+ }
67
+ /**
68
+ * Narrow one projection value: anything that is not an activity view is
69
+ * dropped rather than rendered half-formed.
70
+ * @param value - Raw projection value.
71
+ * @returns the value as an activity view, or `undefined`.
72
+ */
73
+ export declare function asActivityView(value: unknown): ActivityView | undefined;
74
+ /**
75
+ * The latest activity value for the session on screen, with a subscription
76
+ * for renderers.
77
+ *
78
+ * The store is effectively single-current: binding a session ({@link
79
+ * ActivityStore.seed}) names the session the UI is showing, and every other
80
+ * id is dropped — values, session objects and read-failure counts alike. A
81
+ * registry-less store (the UI's fallback, test rigs) has no current session
82
+ * and keeps today's accept-all behavior.
83
+ */
84
+ export declare class ActivityStore {
85
+ private readonly values;
86
+ /** Session objects seen for each id, so a live value can be re-read. */
87
+ private readonly sessions;
88
+ /** Consecutive failed reads per session id; reset by a successful read. */
89
+ private readonly readFailures;
90
+ /** Sessions already warned about (see {@link noteReadFailure}): once each. */
91
+ private readonly warned;
92
+ private readonly listeners;
93
+ /** The session the UI is showing (the last {@link seed}); the only id kept. */
94
+ private currentId;
95
+ /** Host registry, remembered so a bind can read a baseline on demand. */
96
+ private registry;
97
+ /** Warn sink (see {@link noteReadFailure}); injected by the composition root. */
98
+ private readonly warn;
99
+ constructor(warn?: (message: string) => void);
100
+ /** Remember the host registry (see {@link seed} and {@link refreshLive}). */
101
+ attachRegistry(registry: ProjectionRegistryLike): void;
102
+ /**
103
+ * Seed one session from the registry's current snapshot and make it the
104
+ * current one.
105
+ *
106
+ * A value only *arrives* when it changes, so a session opened after its last
107
+ * change — a resume, or a window reattached to a running agent — would show
108
+ * nothing until the next event without this read. The bind also defines the
109
+ * session on screen: every other id is pruned, so a later event — or the
110
+ * tick — for a session the user switched away from can no longer fill this
111
+ * store or keep a timer armed.
112
+ * @param session - Session being bound.
113
+ */
114
+ seed(session: unknown): void;
115
+ /**
116
+ * Note the session object behind an id, so a live value can be re-read.
117
+ * Dropped for any id other than the current one (see {@link seed}). */
118
+ remember(sessionId: string, session: unknown): void;
119
+ /**
120
+ * Re-read the current session's value while it is still counting time.
121
+ *
122
+ * The host renders the value when it is *read*, so this is what makes the
123
+ * elapsed seconds advance between committed events — with the host's own copy
124
+ * and language, since nothing is re-rendered here. A value that has settled
125
+ * (`live` false: idle, or a finished turn) is deliberately skipped: its text
126
+ * cannot change on its own. Only the current session can be live (see
127
+ * {@link seed}), so the tick never polls a session the user left.
128
+ */
129
+ refreshLive(): void;
130
+ /** Whether the current session's value is still counting time (see {@link refreshLive}). */
131
+ hasLive(): boolean;
132
+ /** The current value for one session, stable between updates. */
133
+ get(sessionId: string | undefined): ActivityView | undefined;
134
+ /**
135
+ * Record one projection value. Dropped for any id other than the current
136
+ * one (see {@link seed}).
137
+ * @param sessionId - Session the value belongs to.
138
+ * @param view - The published value.
139
+ */
140
+ update(sessionId: string, view: ActivityView): void;
141
+ /** Forget one session (disposed, or left behind by a reset). */
142
+ clear(sessionId: string): void;
143
+ /** A read succeeded: this session's consecutive-failure count restarts. */
144
+ noteReadSuccess(sessionId: string): void;
145
+ /**
146
+ * A read failed. The failure is reported to the warn sink ONCE per session
147
+ * (the sink is the composition root's logger — this module stays free of
148
+ * cordis types), and after {@link MAX_READ_FAILURES} consecutive failures
149
+ * the value is cleared so the tick disarms instead of polling a registry
150
+ * that will never answer.
151
+ * @param sessionId - Session whose read failed.
152
+ * @param detail - What the failed read threw.
153
+ */
154
+ noteReadFailure(sessionId: string, detail: string): void;
155
+ /** Drop every id that is not the current one; emit when a value went. */
156
+ private pruneToCurrent;
157
+ /** Subscribe to value changes; returns the unsubscribe function. */
158
+ subscribe(listener: () => void): () => void;
159
+ private emit;
160
+ }
161
+ /**
162
+ * The change-feed listener for one store.
163
+ *
164
+ * Only this plugin's key is read, and only values that narrow to an activity
165
+ * view are accepted: the feed is host-wide, so every other unit's change and
166
+ * every malformed value must be dropped here rather than inside a renderer.
167
+ * @param store - Store to fill.
168
+ * @returns the listener to hand to `ProjectionRegistry.onChanged`.
169
+ */
170
+ export declare function createActivityFeed(store: ActivityStore): (session: {
171
+ readonly id: unknown;
172
+ }, key: string, value: unknown) => void;
173
+ /** How often a value that is still counting time is re-read from the host. */
174
+ export declare const LIVE_TICK_MS = 500;
175
+ /**
176
+ * Wire one store to the host's projection registry.
177
+ *
178
+ * Registration is deferred through `inject` because the plugin that *publishes*
179
+ * the unit is mounted alongside this one: the registry may not exist yet, and
180
+ * the unit may not be registered until later still. Both absences are normal —
181
+ * a composition without the activity plugin simply never fills the store, and
182
+ * the line falls back to whatever else the UI has.
183
+ *
184
+ * The feed is event-driven, so a value only lands when a committed event folds;
185
+ * its elapsed text would therefore freeze for the length of a long tool. The
186
+ * host renders a value when it is READ, so a timer re-reads the live ones: the
187
+ * seconds advance, the copy and language stay the plugin's, and a settled value
188
+ * (idle, or a finished turn) stops the timer instead of being polled forever.
189
+ * @param ctx - Host context of the composition root.
190
+ * @param store - Store to fill.
191
+ */
192
+ export declare function attachActivityProjection(ctx: Context, store: ActivityStore): void;
193
+ /**
194
+ * Create the composition root's activity store and wire it to the host.
195
+ * @param ctx - Host context of the composition root.
196
+ * @param enabled - Whether the working line is shown at all (cordis.yml
197
+ * `activity`; a static, config-time switch — the runtime `/activity` command
198
+ * only changes the preset). With the line off, nothing attaches: no feed,
199
+ * no registry, and therefore no 500ms tick for a line nobody renders.
200
+ * @returns the store the UI reads from.
201
+ */
202
+ export declare function createActivityStore(ctx: Context, enabled: boolean): ActivityStore;
203
+ /**
204
+ * Read one session's activity value in a component.
205
+ * @param store - Store to read.
206
+ * @param sessionId - Session the UI is showing.
207
+ * @returns the current value, or `undefined` when there is none.
208
+ */
209
+ export declare function useActivity(store: ActivityStore, sessionId: string | undefined): ActivityView | undefined;
210
+ /**
211
+ * Seed one session's value from the registry's current snapshot.
212
+ *
213
+ * A value only *arrives* when it changes, so a session opened after its last
214
+ * change — a resume, or a window reattached to a running agent — would show
215
+ * nothing until the next event without this read.
216
+ * @param registry - Host projection registry.
217
+ * @param store - Store to fill.
218
+ * @param session - Session to read.
219
+ */
220
+ export declare function seedActivity(registry: ProjectionRegistryLike | undefined, store: ActivityStore, session: unknown): void;
221
+ //# sourceMappingURL=activity-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-store.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/activity-store.ts"],"names":[],"mappings":"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"}