@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
@@ -10,6 +10,90 @@ import { Service } from '@deepseek-ai/cordis';
10
10
  import { activationFiber, bindCallerEffect, compositionRoot, concreteService, requirePluginCaller } from './host-access.js';
11
11
  import { assertCapabilityShadowPolicy, } from '../adapter/kernel/runtime.js';
12
12
  import { adapterRuntimeFor } from '../adapter/kernel/runtime-context.js';
13
+ /**
14
+ * Enumerate the durable workspace registry, in its own display order.
15
+ *
16
+ * The sidebar needs the *registry* (every workspace the user ever registered,
17
+ * including ones with no sessions yet), not the session-derived grouping the
18
+ * `/resume` browser builds. Order, ids and titles come from the ledger;
19
+ * `sessionCount` is filled in by the caller (the adapter holds no session
20
+ * index), and `present` is derived here.
21
+ */
22
+ export async function listRegistryWorkspaces(runtime) {
23
+ if (runtime === undefined)
24
+ return [];
25
+ const registry = workspaceRegistry(runtime);
26
+ if (registry === undefined)
27
+ return [];
28
+ const out = [];
29
+ for (const workspace of registry.list()) {
30
+ let present = true;
31
+ try {
32
+ present = (await workspace.status?.()) !== 'missing-dir';
33
+ }
34
+ catch {
35
+ // An unreadable status is not evidence of absence.
36
+ present = true;
37
+ }
38
+ out.push({
39
+ id: String(workspace.id),
40
+ path: workspace.path,
41
+ title: workspace.title,
42
+ present,
43
+ sessionCount: 0,
44
+ });
45
+ }
46
+ return out;
47
+ }
48
+ /**
49
+ * Remove a workspace registration by path. Sessions and the directory survive:
50
+ * only the ledger entry goes away, so the sessions reappear as ungrouped.
51
+ *
52
+ * @returns True when a record was removed, false when no record owned `cwd`
53
+ * (or the ledger is unmounted).
54
+ */
55
+ export async function removeRegistryWorkspace(runtime, cwd, owner) {
56
+ if (runtime === undefined)
57
+ return false;
58
+ const registry = workspaceRegistry(runtime);
59
+ if (registry === undefined)
60
+ return false;
61
+ const workspace = registry.list().find(candidate => sameCwd(candidate.path, cwd));
62
+ if (workspace === undefined)
63
+ return false;
64
+ // The durable ledger is host-owned: a plugin may only drop a registration
65
+ // for a cwd one of ITS OWN providers still vouches for. `owner === undefined`
66
+ // is the host facade's own call (the sidebar's remove action).
67
+ if (owner !== undefined && !ownsWorkspace(runtime, owner, cwd)) {
68
+ throw new Error('workspace is not owned by the calling activation');
69
+ }
70
+ return registry.delete(workspace.id);
71
+ }
72
+ /**
73
+ * Whether a calling activation's own providers still vouch for `cwd`.
74
+ *
75
+ * This is the same evidence `renameWorkspace` accepts, and the only ownership
76
+ * fact the local ledger records 鈥?the registry entry itself carries no creator.
77
+ * A provider `describe()` that returns a target means the cwd belongs to that
78
+ * provider's scheme, so the activation behind it is the one entitled to mutate
79
+ * the registration.
80
+ * @param runtime - The workspace service.
81
+ * @param owner - Live activation fiber of the caller.
82
+ * @param cwd - Directory to test.
83
+ * @returns True when one of the caller's providers owns `cwd`.
84
+ */
85
+ function ownsWorkspace(runtime, owner, cwd) {
86
+ for (const provider of providersFor(workspaceStateFor(runtime), owner)) {
87
+ try {
88
+ if (provider.describe(cwd) !== undefined)
89
+ return true;
90
+ }
91
+ catch {
92
+ // A provider that throws on describe vouches for nothing.
93
+ }
94
+ }
95
+ return false;
96
+ }
13
97
  export const name = 'dsh-tui-workspaces';
14
98
  /** Bound every provider promise so one plugin cannot park workspace flows. */
15
99
  export const WORKSPACE_PROVIDER_TIMEOUT_MS = 2000;
@@ -53,6 +137,11 @@ export class TuiWorkspaceRuntime extends Service {
53
137
  assertCapabilityShadowPolicy('host.workspaces.rename', state.runtime.mode, state.runtime.slices);
54
138
  return renameWorkspace(runtime, cwd, title, undefined);
55
139
  },
140
+ remove: (cwd) => {
141
+ assertCapabilityShadowPolicy('host.workspaces.remove', state.runtime.mode, state.runtime.slices);
142
+ return removeRegistryWorkspace(runtime, cwd);
143
+ },
144
+ listRegistry: () => listRegistryWorkspaces(runtime),
56
145
  commands: () => workspaceCommands(runtime, undefined),
57
146
  runCommand: (name, input, cwd, signal) => {
58
147
  assertCapabilityShadowPolicy('host.workspaces.runCommand', state.runtime.mode, state.runtime.slices);
@@ -107,6 +196,27 @@ export class TuiWorkspaceRuntime extends Service {
107
196
  const owner = workspaceCaller(this, 'tuiWorkspaces.rename');
108
197
  return renameWorkspace(this, cwd, title, owner);
109
198
  }
199
+ /**
200
+ * Drop a workspace registration; the directory and session logs survive.
201
+ *
202
+ * Plugin-facing, and therefore bound by the SAME rule as {@link rename}: a
203
+ * live calling activation is required, and the target must be a cwd one of
204
+ * that activation's own providers vouches for. Without both, a plugin that
205
+ * never owned the workspace 鈥?including one whose fiber was already disposed
206
+ * and whose caller context is a retained handle 鈥?could delete a host
207
+ * registration. Shadow policy alone is not caller authentication.
208
+ */
209
+ async remove(cwd) {
210
+ assertCapabilityShadowPolicy('host.workspaces.remove', workspaceStateFor(this).runtime.mode, workspaceStateFor(this).runtime.slices);
211
+ const owner = workspaceCaller(this, 'tuiWorkspaces.remove');
212
+ return removeRegistryWorkspace(this, cwd, owner);
213
+ }
214
+ /** The durable ledger's own listing, in its own order. */
215
+ async listRegistry() {
216
+ assertCapabilityShadowPolicy('host.workspaces.list', workspaceStateFor(this).runtime.mode, workspaceStateFor(this).runtime.slices);
217
+ workspaceCaller(this, 'tuiWorkspaces.listRegistry');
218
+ return listRegistryWorkspaces(this);
219
+ }
110
220
  commands() {
111
221
  assertCapabilityShadowPolicy('host.workspaces.commands', workspaceStateFor(this).runtime.mode, workspaceStateFor(this).runtime.slices);
112
222
  const owner = workspaceCaller(this, 'tuiWorkspaces.commands');
@@ -376,6 +486,12 @@ export function createLocalWorkspaceRuntime() {
376
486
  async rename() {
377
487
  throw new Error('workspace registry is unavailable');
378
488
  },
489
+ async remove() {
490
+ return false;
491
+ },
492
+ async listRegistry() {
493
+ return [];
494
+ },
379
495
  commands() {
380
496
  return [];
381
497
  },
@@ -3,9 +3,9 @@
3
3
  * `/effort` (slider or `/effort <id>`; `/effort status` reports the current
4
4
  * level) — note Shift+Tab cycles session modes (default/plan/full), not
5
5
  * effort levels. The choice lands here so the next boot starts on it. The
6
- * file is best-effort: a missing/corrupt file or a level the current adapter
7
- * does not offer just falls back to the provider default — the first
8
- * request/header event always re-asserts the truth on the status line.
6
+ * file is best-effort; a level the current route's tier list does not offer
7
+ * falls back to the nearest LOWER tier (nearestLowerEffort, never up) with a
8
+ * loud notice — a missing/corrupt file falls back to the provider default.
9
9
  */
10
10
  /**
11
11
  * The persisted reasoning-effort id, or undefined when unset or invalid.
@@ -26,6 +26,18 @@ export declare function readEffortPref(dir?: string): string | undefined;
26
26
  * @returns The winning level id, or undefined for the adapter default.
27
27
  */
28
28
  export declare function resolveEffortDefault(settingsDefault: string | undefined, configured: string | undefined, persisted: string | undefined): string | undefined;
29
+ /**
30
+ * Resolve a preferred effort tier against a route's available tiers when the
31
+ * exact tier is absent: pick the NEAREST LOWER standard tier that the route
32
+ * offers (max→high, high→low, …). Only-down, never-up — a user who prefers
33
+ * `low` on a route without it must not be pushed to `high`. Unknown tier ids
34
+ * (custom route tiers outside the standard order) never participate: an
35
+ * unknown preference yields undefined, an unknown candidate is skipped.
36
+ * @param preferred - The preferred tier id (exact match short-circuits).
37
+ * @param available - Tier ids the current route offers.
38
+ * @returns The tier id to apply, or undefined to keep the model default.
39
+ */
40
+ export declare function nearestLowerEffort(preferred: string, available: readonly string[]): string | undefined;
29
41
  /**
30
42
  * Persist the chosen reasoning-effort id (best effort).
31
43
  * @param effort - Adapter-owned effort id to persist.
@@ -1 +1 @@
1
- {"version":3,"file":"effortPrefs.d.ts","sourceRoot":"","sources":["../../src/effortPrefs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAkB,GAAG,MAAM,GAAG,SAAS,CAS1E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,GAAG,SAAS,CAEpB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAkB,GAAG,OAAO,CAQhF"}
1
+ {"version":3,"file":"effortPrefs.d.ts","sourceRoot":"","sources":["../../src/effortPrefs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAkB,GAAG,MAAM,GAAG,SAAS,CAS1E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,GAAG,SAAS,CAEpB;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAgBtG;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAkB,GAAG,OAAO,CAQhF"}
@@ -3,9 +3,9 @@
3
3
  * `/effort` (slider or `/effort <id>`; `/effort status` reports the current
4
4
  * level) — note Shift+Tab cycles session modes (default/plan/full), not
5
5
  * effort levels. The choice lands here so the next boot starts on it. The
6
- * file is best-effort: a missing/corrupt file or a level the current adapter
7
- * does not offer just falls back to the provider default — the first
8
- * request/header event always re-asserts the truth on the status line.
6
+ * file is best-effort; a level the current route's tier list does not offer
7
+ * falls back to the nearest LOWER tier (nearestLowerEffort, never up) with a
8
+ * loud notice — a missing/corrupt file falls back to the provider default.
9
9
  */
10
10
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
11
11
  import { join } from 'node:path';
@@ -43,6 +43,40 @@ export function readEffortPref(dir = PREFS_DIR) {
43
43
  export function resolveEffortDefault(settingsDefault, configured, persisted) {
44
44
  return settingsDefault ?? configured ?? persisted;
45
45
  }
46
+ /** Standard effort-tier order, weakest to strongest. */
47
+ const EFFORT_TIER_ORDER = ['off', 'low', 'medium', 'high', 'max'];
48
+ /**
49
+ * Resolve a preferred effort tier against a route's available tiers when the
50
+ * exact tier is absent: pick the NEAREST LOWER standard tier that the route
51
+ * offers (max→high, high→low, …). Only-down, never-up — a user who prefers
52
+ * `low` on a route without it must not be pushed to `high`. Unknown tier ids
53
+ * (custom route tiers outside the standard order) never participate: an
54
+ * unknown preference yields undefined, an unknown candidate is skipped.
55
+ * @param preferred - The preferred tier id (exact match short-circuits).
56
+ * @param available - Tier ids the current route offers.
57
+ * @returns The tier id to apply, or undefined to keep the model default.
58
+ */
59
+ export function nearestLowerEffort(preferred, available) {
60
+ if (preferred === '' || available.length === 0)
61
+ return undefined;
62
+ if (available.includes(preferred))
63
+ return preferred;
64
+ const preferredRank = EFFORT_TIER_ORDER.indexOf(preferred);
65
+ if (preferredRank <= 0)
66
+ return undefined; // unknown id, or 'off' has nothing lower
67
+ let result;
68
+ let resultRank = -1;
69
+ for (const candidate of available) {
70
+ const rank = EFFORT_TIER_ORDER.indexOf(candidate);
71
+ if (rank < 0 || rank >= preferredRank)
72
+ continue;
73
+ if (rank > resultRank) {
74
+ result = candidate;
75
+ resultRank = rank;
76
+ }
77
+ }
78
+ return result;
79
+ }
46
80
  /**
47
81
  * Persist the chosen reasoning-effort id (best effort).
48
82
  * @param effort - Adapter-owned effort id to persist.
@@ -4,9 +4,14 @@ export type HistoryEntry = {
4
4
  /** Unix ms timestamp. */
5
5
  ts: number;
6
6
  };
7
+ /**
8
+ * Entry cap for the persisted history. `↑`/`↓` and the Ctrl+R overlay read
9
+ * the same file, so both depths come from this one number.
10
+ */
11
+ export declare const HISTORY_LIMIT = 200;
7
12
  /**
8
13
  * Append an input to the persisted history, deduping the immediately
9
- * previous entry and capping the file at 200 entries.
14
+ * previous entry and capping the file at `HISTORY_LIMIT` entries.
10
15
  * @param text - Input to persist; blank inputs are ignored.
11
16
  * @returns Resolves once this entry is persisted; callers on the input path
12
17
  * intentionally discard it because persistence is best-effort.
@@ -17,6 +22,13 @@ export declare function appendHistory(text: string): Promise<void>;
17
22
  * @returns The persisted entries in reverse-chronological order.
18
23
  */
19
24
  export declare function loadHistory(): HistoryEntry[];
25
+ /**
26
+ * Read the persisted history in the order the composer walks it: oldest
27
+ * first, so `↑` reaches the newest entry first (the list tail) exactly as it
28
+ * does for the entries this process pushed itself.
29
+ * @returns The persisted entries in chronological order.
30
+ */
31
+ export declare function loadHistoryOldestFirst(): HistoryEntry[];
20
32
  /**
21
33
  * Stable id for a history entry (keeps React keys distinct across identical texts).
22
34
  * @param entry - The history entry to hash.
@@ -1 +1 @@
1
- {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/history.ts"],"names":[],"mappings":"AAWA,yCAAyC;AACzC,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAA;CACX,CAAA;AAyHD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,YAAY,EAAE,CAE5C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,SAAI,GAAG,MAAM,CAErE"}
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/history.ts"],"names":[],"mappings":"AAWA,yCAAyC;AACzC,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAA;CACX,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,MAAM,CAAA;AAuHhC;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,YAAY,EAAE,CAE5C;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,YAAY,EAAE,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,SAAI,GAAG,MAAM,CAErE"}
@@ -7,7 +7,11 @@ import { DATA_DIR } from './utils/paths.js';
7
7
  const HISTORY_DIR = DATA_DIR;
8
8
  const HISTORY_FILE = join(HISTORY_DIR, 'history.jsonl');
9
9
  const HISTORY_LOCK = `${HISTORY_FILE}.lock`;
10
- const HISTORY_LIMIT = 200;
10
+ /**
11
+ * Entry cap for the persisted history. `↑`/`↓` and the Ctrl+R overlay read
12
+ * the same file, so both depths come from this one number.
13
+ */
14
+ export const HISTORY_LIMIT = 200;
11
15
  const LOCK_RETRY_LIMIT = 500;
12
16
  const LOCK_RETRY_DELAY_MS = 5;
13
17
  const STALE_LOCK_MS = 30_000;
@@ -131,7 +135,7 @@ async function persistEntry(trimmed) {
131
135
  let appendChain = Promise.resolve();
132
136
  /**
133
137
  * Append an input to the persisted history, deduping the immediately
134
- * previous entry and capping the file at 200 entries.
138
+ * previous entry and capping the file at `HISTORY_LIMIT` entries.
135
139
  * @param text - Input to persist; blank inputs are ignored.
136
140
  * @returns Resolves once this entry is persisted; callers on the input path
137
141
  * intentionally discard it because persistence is best-effort.
@@ -153,6 +157,15 @@ export function appendHistory(text) {
153
157
  export function loadHistory() {
154
158
  return loadRaw().reverse();
155
159
  }
160
+ /**
161
+ * Read the persisted history in the order the composer walks it: oldest
162
+ * first, so `↑` reaches the newest entry first (the list tail) exactly as it
163
+ * does for the entries this process pushed itself.
164
+ * @returns The persisted entries in chronological order.
165
+ */
166
+ export function loadHistoryOldestFirst() {
167
+ return loadRaw();
168
+ }
156
169
  /**
157
170
  * Stable id for a history entry (keeps React keys distinct across identical texts).
158
171
  * @param entry - The history entry to hash.
@@ -0,0 +1,15 @@
1
+ interface HomePrefs {
2
+ /** True once the workspace home has been shown as the landing screen. */
3
+ seen?: boolean;
4
+ }
5
+ /** Read the persisted landing preference; an unreadable file reads as unset. */
6
+ export declare function readHomePrefs(): HomePrefs;
7
+ /**
8
+ * Record that the workspace home has been shown.
9
+ *
10
+ * @returns True when the preference was durably written; false when the data
11
+ * directory is not writable (the caller stays silent — see the module note).
12
+ */
13
+ export declare function markHomeSeen(): boolean;
14
+ export {};
15
+ //# sourceMappingURL=homePrefs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"homePrefs.d.ts","sourceRoot":"","sources":["../../src/homePrefs.ts"],"names":[],"mappings":"AA0BA,UAAU,SAAS;IACjB,yEAAyE;IACzE,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,gFAAgF;AAChF,wBAAgB,aAAa,IAAI,SAAS,CASzC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAQtC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Landing-screen preference for the TUI's workspace home screen.
3
+ *
4
+ * A one-key preference under `~/.dsh-tui/home.json`, deliberately NOT a cordis
5
+ * config value: "has this installation shown the user the workspace home on a
6
+ * fresh launch yet" is per-machine UI state, like the lang and tray
7
+ * preferences next to it — not a deployment choice a cordis.yml row should own.
8
+ *
9
+ * The rule it enables is one-shot: the FIRST ordinary launch (no explicit
10
+ * `--resume`, no workspace target) lands on the workspace home instead of a
11
+ * blank conversation, because that is the launch where "which project am I
12
+ * working on" has no answer yet. After that the chat screen is the landing
13
+ * surface again, and the home screen stays reachable as a screen.
14
+ *
15
+ * A preference file that cannot be read or written is never fatal: the worst
16
+ * outcome is one extra home screen, or a chat screen where the home was
17
+ * expected. Both are recoverable with a single keypress.
18
+ *
19
+ * @module @deepseek-harness-tui/dsh-tui/homePrefs
20
+ */
21
+ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
22
+ import { join } from 'node:path';
23
+ import { DATA_DIR } from './utils/paths.js';
24
+ const PREFS_FILE = join(DATA_DIR, 'home.json');
25
+ /** Read the persisted landing preference; an unreadable file reads as unset. */
26
+ export function readHomePrefs() {
27
+ try {
28
+ const parsed = JSON.parse(readFileSync(PREFS_FILE, 'utf8'));
29
+ if (typeof parsed !== 'object' || parsed === null)
30
+ return {};
31
+ const seen = parsed.seen;
32
+ return typeof seen === 'boolean' ? { seen } : {};
33
+ }
34
+ catch {
35
+ return {};
36
+ }
37
+ }
38
+ /**
39
+ * Record that the workspace home has been shown.
40
+ *
41
+ * @returns True when the preference was durably written; false when the data
42
+ * directory is not writable (the caller stays silent — see the module note).
43
+ */
44
+ export function markHomeSeen() {
45
+ try {
46
+ mkdirSync(DATA_DIR, { recursive: true });
47
+ writeFileSync(PREFS_FILE, `${JSON.stringify({ ...readHomePrefs(), seen: true }, null, 2)}\n`, 'utf8');
48
+ return true;
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }