@deepseek-harness-tui/dsh-tui 0.6.0 → 0.7.0

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 (379) hide show
  1. package/README.md +74 -21
  2. package/bin/dsh-tui.js +115 -25
  3. package/cordis.patch.yml +69 -17
  4. package/cordis.yml +50 -12
  5. package/lib/types/activityPrefs.d.ts +1 -1
  6. package/lib/types/activityPrefs.js +3 -3
  7. package/lib/types/cc/figures.d.ts +27 -20
  8. package/lib/types/cc/figures.d.ts.map +1 -1
  9. package/lib/types/cc/figures.js +43 -34
  10. package/lib/types/cc/format.d.ts +18 -9
  11. package/lib/types/cc/format.d.ts.map +1 -1
  12. package/lib/types/cc/format.js +26 -18
  13. package/lib/types/cc/markdown.d.ts +31 -16
  14. package/lib/types/cc/markdown.d.ts.map +1 -1
  15. package/lib/types/cc/markdown.js +283 -260
  16. package/lib/types/cc/terminal.d.ts +10 -7
  17. package/lib/types/cc/terminal.d.ts.map +1 -1
  18. package/lib/types/cc/terminal.js +62 -50
  19. package/lib/types/command-trees.d.ts +3 -0
  20. package/lib/types/command-trees.d.ts.map +1 -0
  21. package/lib/types/command-trees.js +4 -0
  22. package/lib/types/commands.d.ts +37 -1
  23. package/lib/types/commands.d.ts.map +1 -1
  24. package/lib/types/commands.js +68 -3
  25. package/lib/types/components/ActivityLine.d.ts +1 -1
  26. package/lib/types/components/ActivityLine.d.ts.map +1 -1
  27. package/lib/types/components/ActivityPicker.d.ts.map +1 -1
  28. package/lib/types/components/ActivityPicker.js +3 -4
  29. package/lib/types/components/BtwPanel.d.ts +16 -0
  30. package/lib/types/components/BtwPanel.d.ts.map +1 -0
  31. package/lib/types/components/BtwPanel.js +47 -0
  32. package/lib/types/components/CommandSuggestions.d.ts +4 -2
  33. package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
  34. package/lib/types/components/CommandSuggestions.js +2 -2
  35. package/lib/types/components/EffortSlider.d.ts +15 -0
  36. package/lib/types/components/EffortSlider.d.ts.map +1 -0
  37. package/lib/types/components/EffortSlider.js +17 -0
  38. package/lib/types/components/GoalTodoPanel.d.ts +1 -1
  39. package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
  40. package/lib/types/components/HelpMenu.d.ts +5 -2
  41. package/lib/types/components/HelpMenu.d.ts.map +1 -1
  42. package/lib/types/components/HelpMenu.js +8 -3
  43. package/lib/types/components/HistorySearchDialog.d.ts +1 -1
  44. package/lib/types/components/HistorySearchDialog.d.ts.map +1 -1
  45. package/lib/types/components/HistorySearchDialog.js +21 -10
  46. package/lib/types/components/InterruptedByUser.d.ts +2 -2
  47. package/lib/types/components/InterruptedByUser.d.ts.map +1 -1
  48. package/lib/types/components/InterruptedByUser.js +4 -3
  49. package/lib/types/components/LoadedContextPanel.d.ts +1 -1
  50. package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
  51. package/lib/types/components/LogoV2.d.ts.map +1 -1
  52. package/lib/types/components/LogoV2.js +2 -1
  53. package/lib/types/components/Markdown.d.ts +11 -11
  54. package/lib/types/components/Markdown.d.ts.map +1 -1
  55. package/lib/types/components/Markdown.js +63 -57
  56. package/lib/types/components/MarkdownTable.d.ts +1 -1
  57. package/lib/types/components/MarkdownTable.js +2 -2
  58. package/lib/types/components/MessageList.d.ts +10 -2
  59. package/lib/types/components/MessageList.d.ts.map +1 -1
  60. package/lib/types/components/MessageList.js +17 -10
  61. package/lib/types/components/ModelPicker.d.ts +4 -1
  62. package/lib/types/components/ModelPicker.d.ts.map +1 -1
  63. package/lib/types/components/ModelPicker.js +16 -4
  64. package/lib/types/components/OverlayAbove.d.ts +20 -0
  65. package/lib/types/components/OverlayAbove.d.ts.map +1 -0
  66. package/lib/types/components/OverlayAbove.js +18 -0
  67. package/lib/types/components/PresetPicker.d.ts +1 -1
  68. package/lib/types/components/PresetPicker.d.ts.map +1 -1
  69. package/lib/types/components/PresetPicker.js +2 -3
  70. package/lib/types/components/PromptInput.d.ts +5 -4
  71. package/lib/types/components/PromptInput.d.ts.map +1 -1
  72. package/lib/types/components/PromptInput.js +186 -39
  73. package/lib/types/components/ResumePicker.d.ts +15 -4
  74. package/lib/types/components/ResumePicker.d.ts.map +1 -1
  75. package/lib/types/components/ResumePicker.js +25 -9
  76. package/lib/types/components/RewindPicker.d.ts +1 -1
  77. package/lib/types/components/RewindPicker.d.ts.map +1 -1
  78. package/lib/types/components/RewindPicker.js +14 -5
  79. package/lib/types/components/SearchBox.d.ts +1 -1
  80. package/lib/types/components/SearchBox.js +1 -1
  81. package/lib/types/components/Spinner/GlimmerMessage.d.ts +1 -2
  82. package/lib/types/components/Spinner/GlimmerMessage.d.ts.map +1 -1
  83. package/lib/types/components/Spinner/GlimmerMessage.js +1 -2
  84. package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts +1 -1
  85. package/lib/types/components/Spinner/SpinnerAnimationRow.js +2 -2
  86. package/lib/types/components/Spinner/SpinnerGlyph.d.ts +1 -1
  87. package/lib/types/components/Spinner/SpinnerGlyph.js +1 -1
  88. package/lib/types/components/Spinner/spinnerUtils.d.ts +13 -18
  89. package/lib/types/components/Spinner/spinnerUtils.d.ts.map +1 -1
  90. package/lib/types/components/Spinner/spinnerUtils.js +67 -71
  91. package/lib/types/components/Spinner/useStalledAnimation.d.ts +1 -2
  92. package/lib/types/components/Spinner/useStalledAnimation.d.ts.map +1 -1
  93. package/lib/types/components/Spinner/useStalledAnimation.js +1 -2
  94. package/lib/types/components/StreamingMarkdown.d.ts +1 -1
  95. package/lib/types/components/StreamingMarkdown.js +1 -1
  96. package/lib/types/components/ThemePicker.d.ts +13 -9
  97. package/lib/types/components/ThemePicker.d.ts.map +1 -1
  98. package/lib/types/components/ThemePicker.js +21 -15
  99. package/lib/types/components/ThinkingToggle.d.ts +1 -1
  100. package/lib/types/components/ThinkingToggle.d.ts.map +1 -1
  101. package/lib/types/components/ThinkingToggle.js +8 -8
  102. package/lib/types/components/ToolUseLoader.d.ts +1 -1
  103. package/lib/types/components/ToolUseLoader.js +1 -1
  104. package/lib/types/components/WorkingSpinner.d.ts +2 -2
  105. package/lib/types/components/WorkingSpinner.js +2 -2
  106. package/lib/types/components/WorkspaceFlowPicker.d.ts +15 -0
  107. package/lib/types/components/WorkspaceFlowPicker.d.ts.map +1 -0
  108. package/lib/types/components/WorkspaceFlowPicker.js +19 -0
  109. package/lib/types/components/WorkspacePicker.d.ts +9 -0
  110. package/lib/types/components/WorkspacePicker.d.ts.map +1 -0
  111. package/lib/types/components/WorkspacePicker.js +13 -0
  112. package/lib/types/components/approvals/ApprovalPanel.d.ts +1 -1
  113. package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -1
  114. package/lib/types/components/approvals/ApprovalPanel.js +2 -1
  115. package/lib/types/components/design-system/Byline.d.ts +1 -1
  116. package/lib/types/components/design-system/Byline.js +1 -1
  117. package/lib/types/components/design-system/Divider.d.ts +1 -1
  118. package/lib/types/components/design-system/Divider.js +1 -1
  119. package/lib/types/components/design-system/HintLine.d.ts +12 -0
  120. package/lib/types/components/design-system/HintLine.d.ts.map +1 -0
  121. package/lib/types/components/design-system/HintLine.js +15 -0
  122. package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +1 -1
  123. package/lib/types/components/design-system/KeyboardShortcutHint.js +1 -1
  124. package/lib/types/components/design-system/ListItem.d.ts +2 -2
  125. package/lib/types/components/design-system/ListItem.d.ts.map +1 -1
  126. package/lib/types/components/design-system/ListItem.js +35 -3
  127. package/lib/types/components/design-system/LoadingState.d.ts +1 -2
  128. package/lib/types/components/design-system/LoadingState.d.ts.map +1 -1
  129. package/lib/types/components/design-system/LoadingState.js +1 -2
  130. package/lib/types/components/design-system/Pane.d.ts +2 -2
  131. package/lib/types/components/design-system/Pane.js +2 -2
  132. package/lib/types/components/design-system/ProgressBar.d.ts +1 -2
  133. package/lib/types/components/design-system/ProgressBar.d.ts.map +1 -1
  134. package/lib/types/components/design-system/ProgressBar.js +1 -2
  135. package/lib/types/components/design-system/StatusIcon.d.ts +2 -2
  136. package/lib/types/components/design-system/StatusIcon.js +2 -2
  137. package/lib/types/components/design-system/ThemeProvider.d.ts +1 -1
  138. package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
  139. package/lib/types/components/design-system/ThemeProvider.js +87 -26
  140. package/lib/types/components/design-system/ThemedBox.d.ts +1 -1
  141. package/lib/types/components/design-system/ThemedBox.js +1 -1
  142. package/lib/types/components/design-system/ThemedText.d.ts +2 -2
  143. package/lib/types/components/design-system/ThemedText.js +2 -2
  144. package/lib/types/components/listWindow.d.ts +26 -0
  145. package/lib/types/components/listWindow.d.ts.map +1 -0
  146. package/lib/types/components/listWindow.js +47 -0
  147. package/lib/types/components/messages/AssistantTextMessage.d.ts +1 -2
  148. package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -1
  149. package/lib/types/components/messages/AssistantTextMessage.js +1 -2
  150. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -2
  151. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  152. package/lib/types/components/messages/AssistantThinkingMessage.js +6 -6
  153. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +12 -4
  154. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  155. package/lib/types/components/messages/AssistantToolUseMessage.js +9 -5
  156. package/lib/types/components/messages/MessageMetadata.d.ts +1 -1
  157. package/lib/types/components/messages/MessageMetadata.js +1 -1
  158. package/lib/types/components/messages/UserPromptMessage.d.ts +1 -1
  159. package/lib/types/components/messages/UserPromptMessage.js +1 -1
  160. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +5 -1
  161. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
  162. package/lib/types/components/questions/AskUserQuestionPanel.js +11 -9
  163. package/lib/types/components/questions/PlanReviewPanel.d.ts +1 -1
  164. package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
  165. package/lib/types/components/questions/PlanReviewPanel.js +3 -2
  166. package/lib/types/components/trajectory/HotspotView.d.ts +14 -0
  167. package/lib/types/components/trajectory/HotspotView.d.ts.map +1 -0
  168. package/lib/types/components/trajectory/HotspotView.js +83 -0
  169. package/lib/types/components/trajectory/Inspector.d.ts +31 -0
  170. package/lib/types/components/trajectory/Inspector.d.ts.map +1 -0
  171. package/lib/types/components/trajectory/Inspector.js +67 -0
  172. package/lib/types/components/trajectory/Ledger.d.ts +20 -0
  173. package/lib/types/components/trajectory/Ledger.d.ts.map +1 -0
  174. package/lib/types/components/trajectory/Ledger.js +112 -0
  175. package/lib/types/components/trajectory/MiniWake.d.ts +24 -0
  176. package/lib/types/components/trajectory/MiniWake.d.ts.map +1 -0
  177. package/lib/types/components/trajectory/MiniWake.js +99 -0
  178. package/lib/types/components/trajectory/WaveBand.d.ts +33 -0
  179. package/lib/types/components/trajectory/WaveBand.d.ts.map +1 -0
  180. package/lib/types/components/trajectory/WaveBand.js +145 -0
  181. package/lib/types/customTheme.d.ts +6 -6
  182. package/lib/types/customTheme.d.ts.map +1 -1
  183. package/lib/types/customTheme.js +15 -12
  184. package/lib/types/dsh-adapter/approvals.d.ts.map +1 -0
  185. package/lib/types/{channel.d.ts → dsh-adapter/channel.d.ts} +184 -43
  186. package/lib/types/dsh-adapter/channel.d.ts.map +1 -0
  187. package/lib/types/{channel.js → dsh-adapter/channel.js} +972 -201
  188. package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -0
  189. package/lib/types/{childStderr.js → dsh-adapter/childStderr.js} +1 -1
  190. package/lib/types/dsh-adapter/command-trees.d.ts +27 -0
  191. package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -0
  192. package/lib/types/dsh-adapter/command-trees.js +42 -0
  193. package/lib/types/dsh-adapter/compat/index.d.ts +22 -0
  194. package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -0
  195. package/lib/types/{compat → dsh-adapter/compat}/index.js +7 -4
  196. package/lib/types/dsh-adapter/compat/sessionLog.d.ts +86 -0
  197. package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -0
  198. package/lib/types/dsh-adapter/compat/sessionLog.js +347 -0
  199. package/lib/types/dsh-adapter/contract.d.ts +20 -0
  200. package/lib/types/dsh-adapter/contract.d.ts.map +1 -0
  201. package/lib/types/dsh-adapter/contract.js +109 -0
  202. package/lib/types/dsh-adapter/index.d.ts +80 -0
  203. package/lib/types/dsh-adapter/index.d.ts.map +1 -0
  204. package/lib/types/dsh-adapter/index.js +45 -0
  205. package/lib/types/dsh-adapter/invariant.d.ts.map +1 -0
  206. package/lib/types/dsh-adapter/packaged-skills.d.ts.map +1 -0
  207. package/lib/types/{plugin.d.ts → dsh-adapter/plugin.d.ts} +17 -0
  208. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -0
  209. package/lib/types/{plugin.js → dsh-adapter/plugin.js} +280 -80
  210. package/lib/types/dsh-adapter/presets.d.ts.map +1 -0
  211. package/lib/types/dsh-adapter/providerWizard.d.ts +91 -0
  212. package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -0
  213. package/lib/types/dsh-adapter/providerWizard.js +332 -0
  214. package/lib/types/{questions.d.ts → dsh-adapter/questions.d.ts} +7 -2
  215. package/lib/types/dsh-adapter/questions.d.ts.map +1 -0
  216. package/lib/types/{questions.js → dsh-adapter/questions.js} +15 -7
  217. package/lib/types/dsh-adapter/sideQuestion.d.ts +38 -0
  218. package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -0
  219. package/lib/types/dsh-adapter/sideQuestion.js +69 -0
  220. package/lib/types/dsh-adapter/trajectory/aggregate.d.ts +46 -0
  221. package/lib/types/dsh-adapter/trajectory/aggregate.d.ts.map +1 -0
  222. package/lib/types/dsh-adapter/trajectory/aggregate.js +207 -0
  223. package/lib/types/dsh-adapter/trajectory/guards.d.ts +177 -0
  224. package/lib/types/dsh-adapter/trajectory/guards.d.ts.map +1 -0
  225. package/lib/types/dsh-adapter/trajectory/guards.js +235 -0
  226. package/lib/types/dsh-adapter/trajectory/index.d.ts +16 -0
  227. package/lib/types/dsh-adapter/trajectory/index.d.ts.map +1 -0
  228. package/lib/types/dsh-adapter/trajectory/index.js +15 -0
  229. package/lib/types/dsh-adapter/trajectory/inspect.d.ts +40 -0
  230. package/lib/types/dsh-adapter/trajectory/inspect.d.ts.map +1 -0
  231. package/lib/types/dsh-adapter/trajectory/inspect.js +160 -0
  232. package/lib/types/dsh-adapter/trajectory/projection.d.ts +128 -0
  233. package/lib/types/dsh-adapter/trajectory/projection.d.ts.map +1 -0
  234. package/lib/types/dsh-adapter/trajectory/projection.js +653 -0
  235. package/lib/types/dsh-adapter/trajectory/types.d.ts +232 -0
  236. package/lib/types/dsh-adapter/trajectory/types.d.ts.map +1 -0
  237. package/lib/types/dsh-adapter/trajectory/types.js +70 -0
  238. package/lib/types/dsh-adapter/trajectory/wave.d.ts +45 -0
  239. package/lib/types/dsh-adapter/trajectory/wave.d.ts.map +1 -0
  240. package/lib/types/dsh-adapter/trajectory/wave.js +210 -0
  241. package/lib/types/dsh-adapter/types.d.ts +23 -0
  242. package/lib/types/dsh-adapter/types.d.ts.map +1 -0
  243. package/lib/types/dsh-adapter/types.js +1 -0
  244. package/lib/types/dsh-adapter/workspace.d.ts +22 -0
  245. package/lib/types/dsh-adapter/workspace.d.ts.map +1 -0
  246. package/lib/types/dsh-adapter/workspace.js +16 -0
  247. package/lib/types/dsh-adapter/workspaces.d.ts +118 -0
  248. package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -0
  249. package/lib/types/dsh-adapter/workspaces.js +290 -0
  250. package/lib/types/effortPrefs.d.ts +1 -1
  251. package/lib/types/effortPrefs.js +3 -3
  252. package/lib/types/history.js +2 -2
  253. package/lib/types/hooks/useBlink.d.ts +1 -1
  254. package/lib/types/hooks/useBlink.js +1 -1
  255. package/lib/types/i18n.d.ts +977 -36
  256. package/lib/types/i18n.d.ts.map +1 -1
  257. package/lib/types/i18n.js +307 -30
  258. package/lib/types/index.d.ts +1 -69
  259. package/lib/types/index.d.ts.map +1 -1
  260. package/lib/types/index.js +3 -31
  261. package/lib/types/ink/components/App.d.ts.map +1 -1
  262. package/lib/types/ink/components/App.js +33 -19
  263. package/lib/types/ink/dom.d.ts +15 -0
  264. package/lib/types/ink/dom.d.ts.map +1 -1
  265. package/lib/types/ink/dom.js +32 -0
  266. package/lib/types/ink/hooks/use-input.d.ts.map +1 -1
  267. package/lib/types/ink/hooks/use-input.js +8 -0
  268. package/lib/types/ink/hooks/use-terminal-size.d.ts +1 -1
  269. package/lib/types/ink/hooks/use-terminal-size.js +1 -1
  270. package/lib/types/ink/ink.d.ts.map +1 -1
  271. package/lib/types/ink/ink.js +109 -28
  272. package/lib/types/ink/input-suppression.d.ts +20 -0
  273. package/lib/types/ink/input-suppression.d.ts.map +1 -0
  274. package/lib/types/ink/input-suppression.js +26 -0
  275. package/lib/types/ink/log-update.js +21 -6
  276. package/lib/types/ink/parse-keypress.d.ts +31 -0
  277. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  278. package/lib/types/ink/parse-keypress.js +442 -8
  279. package/lib/types/ink/terminal-querier.d.ts +5 -1
  280. package/lib/types/ink/terminal-querier.d.ts.map +1 -1
  281. package/lib/types/ink/terminal-querier.js +27 -3
  282. package/lib/types/ink/terminal.d.ts +18 -0
  283. package/lib/types/ink/terminal.d.ts.map +1 -1
  284. package/lib/types/ink/terminal.js +32 -4
  285. package/lib/types/ink/termio/csi.d.ts +10 -0
  286. package/lib/types/ink/termio/csi.d.ts.map +1 -1
  287. package/lib/types/ink/termio/csi.js +20 -0
  288. package/lib/types/ink/termio/tokenize.js +10 -0
  289. package/lib/types/modelPrefs.d.ts +1 -1
  290. package/lib/types/modelPrefs.js +3 -3
  291. package/lib/types/presetPrefs.d.ts +1 -1
  292. package/lib/types/presetPrefs.js +3 -3
  293. package/lib/types/screens/Chat.d.ts +20 -4
  294. package/lib/types/screens/Chat.d.ts.map +1 -1
  295. package/lib/types/screens/Chat.js +655 -55
  296. package/lib/types/screens/StatusLine.d.ts +17 -2
  297. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  298. package/lib/types/screens/StatusLine.js +12 -4
  299. package/lib/types/screens/TrajectoryScene.d.ts +16 -0
  300. package/lib/types/screens/TrajectoryScene.d.ts.map +1 -0
  301. package/lib/types/screens/TrajectoryScene.js +305 -0
  302. package/lib/types/sessionHistory.d.ts +9 -1
  303. package/lib/types/sessionHistory.d.ts.map +1 -1
  304. package/lib/types/sessionHistory.js +56 -16
  305. package/lib/types/sessionModes.d.ts +29 -0
  306. package/lib/types/sessionModes.d.ts.map +1 -0
  307. package/lib/types/sessionModes.js +45 -0
  308. package/lib/types/theme.d.ts +27 -3
  309. package/lib/types/theme.d.ts.map +1 -1
  310. package/lib/types/theme.js +48 -4
  311. package/lib/types/themePrefs.d.ts +3 -3
  312. package/lib/types/themePrefs.js +5 -5
  313. package/lib/types/trajectory/format.d.ts +100 -0
  314. package/lib/types/trajectory/format.d.ts.map +1 -0
  315. package/lib/types/trajectory/format.js +213 -0
  316. package/lib/types/trajectory/motion.d.ts +99 -0
  317. package/lib/types/trajectory/motion.d.ts.map +1 -0
  318. package/lib/types/trajectory/motion.js +143 -0
  319. package/lib/types/trajectory/query.d.ts +83 -0
  320. package/lib/types/trajectory/query.d.ts.map +1 -0
  321. package/lib/types/trajectory/query.js +187 -0
  322. package/lib/types/trajectoryPrefs.d.ts +36 -0
  323. package/lib/types/trajectoryPrefs.d.ts.map +1 -0
  324. package/lib/types/trajectoryPrefs.js +65 -0
  325. package/lib/types/update.d.ts +3 -3
  326. package/lib/types/update.d.ts.map +1 -1
  327. package/lib/types/update.js +18 -7
  328. package/lib/types/utils/clipboard.d.ts +101 -29
  329. package/lib/types/utils/clipboard.d.ts.map +1 -1
  330. package/lib/types/utils/clipboard.js +533 -55
  331. package/lib/types/utils/debug.d.ts +1 -1
  332. package/lib/types/utils/debug.js +2 -2
  333. package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
  334. package/lib/types/utils/execFileNoThrow.js +16 -6
  335. package/lib/types/utils/externalEditor.d.ts +115 -0
  336. package/lib/types/utils/externalEditor.d.ts.map +1 -0
  337. package/lib/types/utils/externalEditor.js +270 -0
  338. package/lib/types/utils/fullscreen.d.ts +2 -2
  339. package/lib/types/utils/fullscreen.js +3 -3
  340. package/lib/types/utils/loaded-context.d.ts +1 -1
  341. package/lib/types/utils/loaded-context.d.ts.map +1 -1
  342. package/lib/types/utils/modifiers.d.ts +24 -0
  343. package/lib/types/utils/modifiers.d.ts.map +1 -1
  344. package/lib/types/utils/modifiers.js +27 -0
  345. package/lib/types/utils/paths.d.ts +45 -0
  346. package/lib/types/utils/paths.d.ts.map +1 -0
  347. package/lib/types/utils/paths.js +69 -0
  348. package/lib/types/utils/shellQuote.d.ts +14 -0
  349. package/lib/types/utils/shellQuote.d.ts.map +1 -0
  350. package/lib/types/utils/shellQuote.js +39 -0
  351. package/lib/types/utils/workspaceRoot.d.ts +21 -0
  352. package/lib/types/utils/workspaceRoot.d.ts.map +1 -0
  353. package/lib/types/utils/workspaceRoot.js +47 -0
  354. package/lib/types/workspaces.d.ts +3 -0
  355. package/lib/types/workspaces.d.ts.map +1 -0
  356. package/lib/types/workspaces.js +4 -0
  357. package/package.json +26 -8
  358. package/lib/types/approvals.d.ts.map +0 -1
  359. package/lib/types/channel.d.ts.map +0 -1
  360. package/lib/types/childStderr.d.ts.map +0 -1
  361. package/lib/types/compat/index.d.ts +0 -20
  362. package/lib/types/compat/index.d.ts.map +0 -1
  363. package/lib/types/compat/sessionLog.d.ts +0 -40
  364. package/lib/types/compat/sessionLog.d.ts.map +0 -1
  365. package/lib/types/compat/sessionLog.js +0 -226
  366. package/lib/types/invariant.d.ts.map +0 -1
  367. package/lib/types/packaged-skills.d.ts.map +0 -1
  368. package/lib/types/plugin.d.ts.map +0 -1
  369. package/lib/types/presets.d.ts.map +0 -1
  370. package/lib/types/questions.d.ts.map +0 -1
  371. /package/lib/types/{approvals.d.ts → dsh-adapter/approvals.d.ts} +0 -0
  372. /package/lib/types/{approvals.js → dsh-adapter/approvals.js} +0 -0
  373. /package/lib/types/{childStderr.d.ts → dsh-adapter/childStderr.d.ts} +0 -0
  374. /package/lib/types/{invariant.d.ts → dsh-adapter/invariant.d.ts} +0 -0
  375. /package/lib/types/{invariant.js → dsh-adapter/invariant.js} +0 -0
  376. /package/lib/types/{packaged-skills.d.ts → dsh-adapter/packaged-skills.d.ts} +0 -0
  377. /package/lib/types/{packaged-skills.js → dsh-adapter/packaged-skills.js} +0 -0
  378. /package/lib/types/{presets.d.ts → dsh-adapter/presets.d.ts} +0 -0
  379. /package/lib/types/{presets.js → dsh-adapter/presets.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"childStderr.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/childStderr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAsDH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CA8BhF;AAED,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAChG;AAED,MAAM,WAAW,0BAA0B;IACzC,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,yFAAyF;IACzF,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,gCAAgC;IAChC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,iDAAiD;IACjD,OAAO,IAAI,IAAI,CAAA;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,0BAA+B,GACvC,mBAAmB,CA4CrB"}
@@ -26,7 +26,7 @@
26
26
  * dependency tree does that.
27
27
  */
28
28
  import childProcess from 'node:child_process';
29
- import { t } from './i18n.js';
29
+ import { t } from '../i18n.js';
30
30
  /** Strip ANSI escape sequences (CSI/OSC) so raw child output can't inject
31
31
  * cursor moves or colors into the notification area. */
32
32
  // eslint-disable-next-line no-control-regex -- intentional: matching terminal escape sequences
@@ -0,0 +1,27 @@
1
+ /** Provider-neutral subcommand completion registry for terminal front doors. */
2
+ import { Context, Service } from '@deepseek-ai/cordis';
3
+ import type { CommandCompletionNode, LocalizedDescriptions } from '../commands.js';
4
+ export interface TuiCommandTreeProvider {
5
+ /** Root command name without `/`. Must match the command registry entry. */
6
+ root: string;
7
+ /** Optional provider-owned translations for the root command row. */
8
+ descriptions?: LocalizedDescriptions;
9
+ /** Children for the full canonical path, including `root` at index zero. */
10
+ children(canonicalPath: readonly string[]): readonly CommandCompletionNode[];
11
+ }
12
+ declare module '@deepseek-ai/cordis' {
13
+ interface Context {
14
+ tuiCommandTrees: TuiCommandTreeRuntime;
15
+ }
16
+ }
17
+ export declare const name = "dsh-tui-command-trees";
18
+ /** Small host-only registry; command execution remains owned by dsh-commands. */
19
+ export declare class TuiCommandTreeRuntime extends Service {
20
+ private readonly providers;
21
+ constructor(ctx: Context);
22
+ register(provider: TuiCommandTreeProvider): () => void;
23
+ children(canonicalPath: readonly string[]): readonly CommandCompletionNode[];
24
+ descriptions(root: string): LocalizedDescriptions | undefined;
25
+ }
26
+ export default TuiCommandTreeRuntime;
27
+ //# sourceMappingURL=command-trees.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-trees.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/command-trees.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAElF,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,qBAAqB,EAAE,CAAA;CAC7E;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,eAAe,EAAE,qBAAqB,CAAA;KACvC;CACF;AAED,eAAO,MAAM,IAAI,0BAA0B,CAAA;AAE3C,iFAAiF;AACjF,qBAAa,qBAAsB,SAAQ,OAAO;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4C;gBAE1D,GAAG,EAAE,OAAO;IAIxB,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,IAAI;IAWtD,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,qBAAqB,EAAE;IAa5E,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;CAG9D;AAED,eAAe,qBAAqB,CAAA"}
@@ -0,0 +1,42 @@
1
+ /** Provider-neutral subcommand completion registry for terminal front doors. */
2
+ import { Service } from '@deepseek-ai/cordis';
3
+ export const name = 'dsh-tui-command-trees';
4
+ /** Small host-only registry; command execution remains owned by dsh-commands. */
5
+ export class TuiCommandTreeRuntime extends Service {
6
+ providers = new Map();
7
+ constructor(ctx) {
8
+ super(ctx, 'tuiCommandTrees');
9
+ }
10
+ register(provider) {
11
+ const root = provider.root.trim().toLowerCase();
12
+ if (!/^[a-z][a-z0-9_-]*$/u.test(root))
13
+ throw new TypeError(`invalid TUI command-tree root: ${provider.root}`);
14
+ if (this.providers.has(root))
15
+ throw new Error(`TUI command-tree root "${root}" is already registered`);
16
+ const normalized = { ...provider, root };
17
+ this.providers.set(root, normalized);
18
+ return () => {
19
+ if (this.providers.get(root) === normalized)
20
+ this.providers.delete(root);
21
+ };
22
+ }
23
+ children(canonicalPath) {
24
+ const root = canonicalPath[0]?.toLowerCase();
25
+ if (root === undefined)
26
+ return [];
27
+ const provider = this.providers.get(root);
28
+ if (provider === undefined)
29
+ return [];
30
+ try {
31
+ return provider.children(canonicalPath);
32
+ }
33
+ catch {
34
+ // Completion is optional UI metadata and must never block execution.
35
+ return [];
36
+ }
37
+ }
38
+ descriptions(root) {
39
+ return this.providers.get(root.trim().toLowerCase())?.descriptions;
40
+ }
41
+ }
42
+ export default TuiCommandTreeRuntime;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Compat boundary — every inelegant patch aimed at the harness core lives
3
+ * here, behind one import seam, so the render/interaction code stays clean.
4
+ *
5
+ * House rules for modules in this directory:
6
+ * - Each patch carries its own capability probe and self-disables or
7
+ * degrades to pre-patch behavior when upstream absorbs the quirk.
8
+ * - A patch must never throw into the caller: failure means "act as if the
9
+ * patch did not exist".
10
+ * - A patch states plainly which upstream change would retire it.
11
+ *
12
+ * Current residents:
13
+ * - sessionLog: tolerant title reads plus offline rename/delete helpers for
14
+ * persisted sessions that are not currently owned by a live Agent, and
15
+ * the resume-seam registration of vouched-for legacy event types into
16
+ * every reachable KNOWN_SESSION_EVENT_TYPES copy — retiring the day
17
+ * upstream's shared catalog adopts the types or ships a real
18
+ * registration API (issue #153).
19
+ * @module @deepseek-harness-tui/dsh-tui/compat
20
+ */
21
+ export { appendSessionTitle, deleteSessionLog, ensureLegacySessionEventTypes, LEGACY_SESSION_EVENT_TYPES, readSessionTitleFromLog, sessionsRoots, } from './sessionLog.js';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/compat/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,6BAA6B,EAC7B,0BAA0B,EAC1B,uBAAuB,EACvB,aAAa,GACd,MAAM,iBAAiB,CAAA"}
@@ -10,9 +10,12 @@
10
10
  * - A patch states plainly which upstream change would retire it.
11
11
  *
12
12
  * Current residents:
13
- * - sessionLog: marks third-party session-event types `ignorable` before
14
- * resume, retiring the day `session.append` exposes `ignorable` or the
15
- * types enter KNOWN_SESSION_EVENT_TYPES upstream.
13
+ * - sessionLog: tolerant title reads plus offline rename/delete helpers for
14
+ * persisted sessions that are not currently owned by a live Agent, and
15
+ * the resume-seam registration of vouched-for legacy event types into
16
+ * every reachable KNOWN_SESSION_EVENT_TYPES copy — retiring the day
17
+ * upstream's shared catalog adopts the types or ships a real
18
+ * registration API (issue #153).
16
19
  * @module @deepseek-harness-tui/dsh-tui/compat
17
20
  */
18
- export { prepareSessionForResume, readSessionTitleFromLog, repairSessionLogForResume } from './sessionLog.js';
21
+ export { appendSessionTitle, deleteSessionLog, ensureLegacySessionEventTypes, LEGACY_SESSION_EVENT_TYPES, readSessionTitleFromLog, sessionsRoots, } from './sessionLog.js';
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Legacy third-party session-event types the TUI vouches for as ephemeral
3
+ * UI frames — safe for the strict read path to accept and skip. Exported
4
+ * for the regression verifier; grow it only with proof the type was always
5
+ * inert (never load-bearing for session reconstruction).
6
+ */
7
+ export declare const LEGACY_SESSION_EVENT_TYPES: readonly string[];
8
+ /**
9
+ * Session-log storage roots, in priority order, mirroring the persistence
10
+ * backend's `root` resolution: cordis.patch.yml sets `DSH_TUI_SESSION_ROOT ?? dshHomePath(
11
+ * 'sessions')` where dshHomePath is `$DSH_HOME ?? ~/.dsh`; the unpatched
12
+ * cordis.yml base falls back to ~/.dsh-tui/sessions, kept here as the legacy
13
+ * last resort. Every candidate is scanned — the first hit wins, so an
14
+ * explicit DSH_TUI_SESSION_ROOT always outranks the defaults.
15
+ */
16
+ export declare function sessionsRoots(): string[];
17
+ /**
18
+ * Register every {@link LEGACY_SESSION_EVENT_TYPES} type as known in EVERY
19
+ * reachable KNOWN_SESSION_EVENT_TYPES copy, ahead of the strict read path
20
+ * (`agents.resume` seed validation, `persistence.load`). Idempotent; never
21
+ * throws.
22
+ *
23
+ * Why a walk instead of a single import: a runtime can load dsh-session
24
+ * more than once (CLI tree vs profile tree, version overlap during
25
+ * upgrades, pnpm peer-context splits), and the strict validator — which
26
+ * lives in the dsh-session-persistence package — consults only ITS OWN
27
+ * tree's copy. Registering through one import leaves the other trees'
28
+ * copies untouched. So from EACH base anchor (this module = the dsh-tui
29
+ * tree, the process entry point = the launcher/CLI tree) the walk
30
+ * registers the tree's own dsh-session AND steps one edge further:
31
+ * resolve the validator package from that same tree, then register the
32
+ * dsh-session copy the validator's entry resolves. A branch that cannot
33
+ * be resolved simply is not there; resolved module paths are deduped.
34
+ */
35
+ export declare function ensureLegacySessionEventTypes(): void;
36
+ /**
37
+ * Read a session's display title from its persisted log, tolerantly.
38
+ *
39
+ * Why not `persistence.load()`: the backend validates every event against
40
+ * KNOWN_SESSION_EVENT_TYPES and throws the WHOLE load when a third-party
41
+ * plugin wrote an unmarked unknown type. A picker label is
42
+ * read-only UI state: decoding frames directly here keeps titles working
43
+ * for logs the strict path refuses, now and for future plugin event types.
44
+ *
45
+ * Title precedence: the LAST `session/title` event wins (a /rename append
46
+ * overrides the first-prompt auto title), falling back to the first user
47
+ * message text. `hasUserMessage` drives the picker's launch-artifact filter.
48
+ * @param sessionId - Session whose log should be read.
49
+ * @returns The title info, or undefined when the log is absent/undecodable.
50
+ */
51
+ export declare function readSessionTitleFromLog(sessionId: string): {
52
+ title?: string;
53
+ hasUserMessage: boolean;
54
+ } | undefined;
55
+ /**
56
+ * Append a `session/title` event to a persisted session's log — the
57
+ * `/resume` picker rename for a NON-LIVE session (the live one goes through
58
+ * `session.append` in the channel). The backend flushes by appending zstd
59
+ * frames, so the new event lands as one more frame: existing bytes stay
60
+ * untouched (the frame-0 header invariant holds), and `last title wins` in
61
+ * {@link readSessionTitleFromLog} surfaces the new name. The seq continues
62
+ * the log's contiguity contract (seq = event count) by taking maxSeq + 1.
63
+ * The frame is APPEND-ONLY (O_APPEND), matching the backend's own flush
64
+ * discipline: this store is shared with dsh web (#24), and a
65
+ * read-concat-rewrite (tmp + rename) would silently drop a frame another
66
+ * writer lands between our read and replace. A single append never rewrites
67
+ * existing bytes, so concurrent frames all survive; the worst remaining
68
+ * race is a duplicate seq when the maxSeq read above passes another
69
+ * appender — benign next to lost frames, since last-title-wins keeps the
70
+ * rename semantics. Never throws.
71
+ * @param sessionId - Session to rename.
72
+ * @param title - New display title (already trimmed by the caller).
73
+ * @returns 'appended', or 'unavailable' when the log is absent/undecodable.
74
+ */
75
+ export declare function appendSessionTitle(sessionId: string, title: string): 'appended' | 'unavailable';
76
+ /**
77
+ * Delete a persisted session's log directory (`<root>/<workspace>/<id>/`),
78
+ * the `/resume` picker delete. The directory holds only session.jsonl.zstd
79
+ * today; removing it whole keeps future sidecar files from orphaning. The
80
+ * backend's list() materializes entries from these logs, so the session
81
+ * drops out of the picker on the next refresh. Never throws.
82
+ * @param sessionId - Session to delete (must not be the live session).
83
+ * @returns 'deleted', or 'unavailable' when the log is absent.
84
+ */
85
+ export declare function deleteSessionLog(sessionId: string): 'deleted' | 'unavailable';
86
+ //# sourceMappingURL=sessionLog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionLog.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/compat/sessionLog.ts"],"names":[],"mappings":"AAqDA;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAAwB,CAAA;AAKhF;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CASxC;AAkED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,6BAA6B,IAAI,IAAI,CAkCpD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAyBzD;AAyBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,aAAa,CAwB/F;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAwB7E"}
@@ -0,0 +1,347 @@
1
+ /**
2
+ * Session-log compatibility helpers.
3
+ *
4
+ * Title lookup tolerates event types unknown to the current harness. Offline
5
+ * rename and delete support the `/resume` picker when no live Agent owns the
6
+ * selected persisted session. The resume seam registers vouched-for legacy
7
+ * event types into every reachable KNOWN_SESSION_EVENT_TYPES copy so the
8
+ * strict read path stops rejecting whole sessions over them (issue #153).
9
+ *
10
+ * Registration background: plugins like dsh-working-activity (< the publish
11
+ * cut) appended `activity/status` through `session.append`, but rc.6's
12
+ * append exposes no `ignorable` flag and the type is absent from
13
+ * KNOWN_SESSION_EVENT_TYPES — so resume's seed validation rejects the WHOLE
14
+ * session ("unknown to this harness and not marked ignorable"). Upstream's
15
+ * catalog header defers a registration surface "until such a consumer
16
+ * exists"; the working-activity plugin became that consumer at #119 and
17
+ * registers its type at load. Logs written BEFORE that cut, resumed in a
18
+ * process where the plugin's registration never ran (plugin unmounted, or
19
+ * a bare cordis.yml), still hit the rejection — this module is the consumer
20
+ * for exactly that residue.
21
+ *
22
+ * Why registration and NOT rewriting the log to mark events `ignorable`
23
+ * (the #107 approach, restored then replaced after review): the store is
24
+ * shared with dsh web (#24) and possibly a second TUI instance (#153), and
25
+ * a whole-file tmp+rename swap (a) loses frames an already-open appender
26
+ * lands on the replaced inode, (b) drops the backend's 0600 artifact mode,
27
+ * (c) re-encodes frames without the writer's checksum flag, and (d) dies on
28
+ * torn tails the backend itself can recover. Registration touches nothing
29
+ * on disk and degrades to exactly the pre-patch behavior when no copy
30
+ * resolves.
31
+ *
32
+ * Whitelist discipline: ONLY `activity/status` — the type the plugin
33
+ * provably wrote as ephemeral UI frames. Anything else unknown stays
34
+ * unknown: upstream's fail-closed ("likely written by a newer harness") is
35
+ * a feature — silently skipping a REQUIRED future event would reconstruct
36
+ * a wrong session. Retires the day upstream's shared catalog adopts the
37
+ * type or ships a real registration API (the add() calls become no-ops).
38
+ *
39
+ * @module @deepseek-harness-tui/dsh-tui/compat/sessionLog
40
+ */
41
+ import { createRequire } from 'node:module';
42
+ import { appendFileSync, existsSync, readdirSync, readFileSync, realpathSync, rmSync, } from 'node:fs';
43
+ import { dirname, join, sep } from 'node:path';
44
+ import { zstdCompressSync, zstdDecompressSync } from 'node:zlib';
45
+ import { homeDir } from '../../utils/paths.js';
46
+ /**
47
+ * Legacy third-party session-event types the TUI vouches for as ephemeral
48
+ * UI frames — safe for the strict read path to accept and skip. Exported
49
+ * for the regression verifier; grow it only with proof the type was always
50
+ * inert (never load-bearing for session reconstruction).
51
+ */
52
+ export const LEGACY_SESSION_EVENT_TYPES = ['activity/status'];
53
+ /** Zstd frame magic number, little-endian (0xFD2FB528). */
54
+ const ZSTD_MAGIC = 0xfd2fb528;
55
+ /**
56
+ * Session-log storage roots, in priority order, mirroring the persistence
57
+ * backend's `root` resolution: cordis.patch.yml sets `DSH_TUI_SESSION_ROOT ?? dshHomePath(
58
+ * 'sessions')` where dshHomePath is `$DSH_HOME ?? ~/.dsh`; the unpatched
59
+ * cordis.yml base falls back to ~/.dsh-tui/sessions, kept here as the legacy
60
+ * last resort. Every candidate is scanned — the first hit wins, so an
61
+ * explicit DSH_TUI_SESSION_ROOT always outranks the defaults.
62
+ */
63
+ export function sessionsRoots() {
64
+ const home = homeDir();
65
+ const roots = [];
66
+ const override = process.env.DSH_TUI_SESSION_ROOT;
67
+ if (override !== undefined && override.trim().length > 0)
68
+ roots.push(override);
69
+ const dshHome = process.env.DSH_HOME;
70
+ roots.push(join(dshHome !== undefined && dshHome.trim().length > 0 ? dshHome : join(home, '.dsh'), 'sessions'));
71
+ roots.push(join(home, '.dsh-tui', 'sessions'));
72
+ return [...new Set(roots)];
73
+ }
74
+ /**
75
+ * Session ids reach path.join() below from picker/channel callers, and
76
+ * deleteSessionLog recursively removes the resolved parent directory — so
77
+ * an id must be a single safe path segment. Real ids are UUIDs or
78
+ * `session-<uuid>`; anything with separators, dots, or shell-y characters
79
+ * is rejected outright (treated as "no such session").
80
+ */
81
+ function isSafeSessionId(sessionId) {
82
+ return /^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(sessionId);
83
+ }
84
+ /**
85
+ * Locate a session's log by scanning workspace directories for the session
86
+ * id — deliberately NOT replicating the persistence plugin's workspace-key
87
+ * sanitization, so the helpers survive upstream key-scheme changes.
88
+ * @param sessionId - Session id (directory name under each workspace dir).
89
+ * @returns Absolute path of session.jsonl.zstd, or undefined when absent.
90
+ */
91
+ function findSessionLogFile(sessionId) {
92
+ if (!isSafeSessionId(sessionId))
93
+ return undefined;
94
+ for (const root of sessionsRoots()) {
95
+ let workspaces;
96
+ try {
97
+ workspaces = readdirSync(root);
98
+ }
99
+ catch {
100
+ continue;
101
+ }
102
+ for (const ws of workspaces) {
103
+ const candidate = join(root, ws, sessionId, 'session.jsonl.zstd');
104
+ if (existsSync(candidate))
105
+ return candidate;
106
+ }
107
+ }
108
+ return undefined;
109
+ }
110
+ /**
111
+ * Decode a (possibly multi-frame) zstd jsonl log. Frames are split by magic
112
+ * scan; any frame failing to decode or any line failing to parse throws, so
113
+ * callers abort instead of acting on a log they did not fully understand.
114
+ * @param buf - Raw file bytes.
115
+ * @returns Parsed event envelopes, in log order.
116
+ */
117
+ function decodeEvents(buf) {
118
+ const offsets = [];
119
+ for (let i = 0; i + 4 <= buf.length; i++) {
120
+ if (buf.readUInt32LE(i) === ZSTD_MAGIC)
121
+ offsets.push(i);
122
+ }
123
+ if (offsets.length === 0)
124
+ throw new Error('no zstd frame found');
125
+ return offsets.flatMap((start, i) => {
126
+ const end = i + 1 < offsets.length ? offsets[i + 1] : buf.length;
127
+ const text = zstdDecompressSync(buf.subarray(start, end)).toString('utf8');
128
+ return text
129
+ .split('\n')
130
+ .filter((line) => line.length > 0)
131
+ .map((line) => {
132
+ const parsed = JSON.parse(line);
133
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
134
+ throw new Error('session log line is not an event envelope');
135
+ }
136
+ return parsed;
137
+ });
138
+ });
139
+ }
140
+ /**
141
+ * Register every {@link LEGACY_SESSION_EVENT_TYPES} type as known in EVERY
142
+ * reachable KNOWN_SESSION_EVENT_TYPES copy, ahead of the strict read path
143
+ * (`agents.resume` seed validation, `persistence.load`). Idempotent; never
144
+ * throws.
145
+ *
146
+ * Why a walk instead of a single import: a runtime can load dsh-session
147
+ * more than once (CLI tree vs profile tree, version overlap during
148
+ * upgrades, pnpm peer-context splits), and the strict validator — which
149
+ * lives in the dsh-session-persistence package — consults only ITS OWN
150
+ * tree's copy. Registering through one import leaves the other trees'
151
+ * copies untouched. So from EACH base anchor (this module = the dsh-tui
152
+ * tree, the process entry point = the launcher/CLI tree) the walk
153
+ * registers the tree's own dsh-session AND steps one edge further:
154
+ * resolve the validator package from that same tree, then register the
155
+ * dsh-session copy the validator's entry resolves. A branch that cannot
156
+ * be resolved simply is not there; resolved module paths are deduped.
157
+ */
158
+ export function ensureLegacySessionEventTypes() {
159
+ const roots = [import.meta.url, process.argv[1]].filter((anchor) => typeof anchor === 'string' && anchor.length > 0);
160
+ const visitedAnchors = new Set();
161
+ const registeredCopies = new Set();
162
+ const walk = (anchor) => {
163
+ if (visitedAnchors.has(anchor))
164
+ return;
165
+ visitedAnchors.add(anchor);
166
+ let req;
167
+ try {
168
+ req = createRequire(anchor);
169
+ }
170
+ catch {
171
+ return;
172
+ }
173
+ try {
174
+ const copy = req.resolve('@deepseek-ai/dsh-session');
175
+ if (!registeredCopies.has(copy)) {
176
+ registeredCopies.add(copy);
177
+ const mod = req(copy);
178
+ for (const type of LEGACY_SESSION_EVENT_TYPES) {
179
+ mod.KNOWN_SESSION_EVENT_TYPES?.add(type);
180
+ }
181
+ }
182
+ }
183
+ catch {
184
+ // No resolvable dsh-session copy from this anchor — nothing here.
185
+ }
186
+ try {
187
+ walk(req.resolve('@deepseek-ai/dsh-session-persistence'));
188
+ }
189
+ catch {
190
+ // Validator package not reachable from this tree — nothing to cover.
191
+ }
192
+ };
193
+ for (const root of roots)
194
+ walk(root);
195
+ }
196
+ /**
197
+ * Read a session's display title from its persisted log, tolerantly.
198
+ *
199
+ * Why not `persistence.load()`: the backend validates every event against
200
+ * KNOWN_SESSION_EVENT_TYPES and throws the WHOLE load when a third-party
201
+ * plugin wrote an unmarked unknown type. A picker label is
202
+ * read-only UI state: decoding frames directly here keeps titles working
203
+ * for logs the strict path refuses, now and for future plugin event types.
204
+ *
205
+ * Title precedence: the LAST `session/title` event wins (a /rename append
206
+ * overrides the first-prompt auto title), falling back to the first user
207
+ * message text. `hasUserMessage` drives the picker's launch-artifact filter.
208
+ * @param sessionId - Session whose log should be read.
209
+ * @returns The title info, or undefined when the log is absent/undecodable.
210
+ */
211
+ export function readSessionTitleFromLog(sessionId) {
212
+ try {
213
+ const file = findSessionLogFile(sessionId);
214
+ if (file === undefined)
215
+ return undefined;
216
+ const events = decodeEvents(readFileSync(file));
217
+ let titled;
218
+ let firstUser;
219
+ let hasUserMessage = false;
220
+ for (const event of events) {
221
+ if (event['type'] === 'session/title') {
222
+ const title = event['data']?.['title'];
223
+ if (typeof title === 'string' && title.trim().length > 0)
224
+ titled = title;
225
+ }
226
+ else if (event['type'] === 'user/message') {
227
+ hasUserMessage = true;
228
+ if (firstUser === undefined) {
229
+ firstUser = firstTextOfContent(event['data']?.['content']);
230
+ }
231
+ }
232
+ }
233
+ return { title: titled ?? firstUser, hasUserMessage };
234
+ }
235
+ catch {
236
+ return undefined;
237
+ }
238
+ }
239
+ /**
240
+ * Extract the first text block from a user/message `content` payload.
241
+ * Content is normally a block array; a bare string is accepted defensively.
242
+ * @param content - The event's content field.
243
+ * @returns The trimmed text, or undefined when no text block exists.
244
+ */
245
+ function firstTextOfContent(content) {
246
+ if (typeof content === 'string')
247
+ return content.trim() || undefined;
248
+ if (!Array.isArray(content))
249
+ return undefined;
250
+ for (const block of content) {
251
+ if (block !== null &&
252
+ typeof block === 'object' &&
253
+ block.type === 'text' &&
254
+ typeof block.text === 'string') {
255
+ const text = (block.text).trim();
256
+ if (text.length > 0)
257
+ return text;
258
+ }
259
+ }
260
+ return undefined;
261
+ }
262
+ /**
263
+ * Append a `session/title` event to a persisted session's log — the
264
+ * `/resume` picker rename for a NON-LIVE session (the live one goes through
265
+ * `session.append` in the channel). The backend flushes by appending zstd
266
+ * frames, so the new event lands as one more frame: existing bytes stay
267
+ * untouched (the frame-0 header invariant holds), and `last title wins` in
268
+ * {@link readSessionTitleFromLog} surfaces the new name. The seq continues
269
+ * the log's contiguity contract (seq = event count) by taking maxSeq + 1.
270
+ * The frame is APPEND-ONLY (O_APPEND), matching the backend's own flush
271
+ * discipline: this store is shared with dsh web (#24), and a
272
+ * read-concat-rewrite (tmp + rename) would silently drop a frame another
273
+ * writer lands between our read and replace. A single append never rewrites
274
+ * existing bytes, so concurrent frames all survive; the worst remaining
275
+ * race is a duplicate seq when the maxSeq read above passes another
276
+ * appender — benign next to lost frames, since last-title-wins keeps the
277
+ * rename semantics. Never throws.
278
+ * @param sessionId - Session to rename.
279
+ * @param title - New display title (already trimmed by the caller).
280
+ * @returns 'appended', or 'unavailable' when the log is absent/undecodable.
281
+ */
282
+ export function appendSessionTitle(sessionId, title) {
283
+ try {
284
+ const file = findSessionLogFile(sessionId);
285
+ if (file === undefined)
286
+ return 'unavailable';
287
+ const events = decodeEvents(readFileSync(file));
288
+ let maxSeq = -1;
289
+ for (const event of events) {
290
+ const seq = event['seq'];
291
+ if (typeof seq === 'number' && seq > maxSeq)
292
+ maxSeq = seq;
293
+ }
294
+ // Same envelope shape as a manual /rename append ({ title } only); the
295
+ // seed validator asks only for type/seq/time/data on non-message types.
296
+ const event = {
297
+ type: 'session/title',
298
+ seq: maxSeq + 1,
299
+ time: Date.now(),
300
+ data: { title },
301
+ };
302
+ const frame = zstdCompressSync(Buffer.from(JSON.stringify(event) + '\n', 'utf8'));
303
+ appendFileSync(file, frame);
304
+ return 'appended';
305
+ }
306
+ catch {
307
+ return 'unavailable';
308
+ }
309
+ }
310
+ /**
311
+ * Delete a persisted session's log directory (`<root>/<workspace>/<id>/`),
312
+ * the `/resume` picker delete. The directory holds only session.jsonl.zstd
313
+ * today; removing it whole keeps future sidecar files from orphaning. The
314
+ * backend's list() materializes entries from these logs, so the session
315
+ * drops out of the picker on the next refresh. Never throws.
316
+ * @param sessionId - Session to delete (must not be the live session).
317
+ * @returns 'deleted', or 'unavailable' when the log is absent.
318
+ */
319
+ export function deleteSessionLog(sessionId) {
320
+ try {
321
+ const file = findSessionLogFile(sessionId);
322
+ if (file === undefined)
323
+ return 'unavailable';
324
+ const dir = dirname(file);
325
+ // Containment must hold after resolving symlinks, not just lexically:
326
+ // a symlinked workspace directory (<root>/<ws -> /outside>/<id>) would
327
+ // steer the recursive rm outside the sessions root even with a clean
328
+ // whitelisted id. realpath BOTH sides — the root itself may legitimately
329
+ // live behind a symlink (macOS /tmp -> /private/tmp).
330
+ const realDir = realpathSync(dir);
331
+ const contained = sessionsRoots().some(root => {
332
+ try {
333
+ return realDir.startsWith(realpathSync(root) + sep);
334
+ }
335
+ catch {
336
+ return false;
337
+ }
338
+ });
339
+ if (!contained)
340
+ return 'unavailable';
341
+ rmSync(dir, { recursive: true, force: true });
342
+ return 'deleted';
343
+ }
344
+ catch {
345
+ return 'unavailable';
346
+ }
347
+ }
@@ -0,0 +1,20 @@
1
+ export declare const UPSTREAM_VALIDATED_VERSION = "0.1.0-rc.6";
2
+ /**
3
+ * Framework packages version on their own lines; the contract validates
4
+ * their MAJOR (breaking surface), not the harness rc number.
5
+ */
6
+ export declare const UPSTREAM_FRAMEWORK_MAJORS: Record<string, number>;
7
+ /** Official packages the adapter consumes at runtime or as types. */
8
+ export declare const UPSTREAM_BLESSED_PACKAGES: readonly ["@deepseek-ai/cordis", "@deepseek-ai/schemastery", "@deepseek-ai/dsh-invariants", "@deepseek-ai/dsh-agent", "@deepseek-ai/dsh-agent-instructions", "@deepseek-ai/dsh-agent-presets", "@deepseek-ai/dsh-commands", "@deepseek-ai/dsh-cordis-host-runner", "@deepseek-ai/dsh-llm", "@deepseek-ai/dsh-persona", "@deepseek-ai/dsh-session", "@deepseek-ai/dsh-skill", "@deepseek-ai/dsh-storage", "@deepseek-ai/dsh-storage-domain", "@deepseek-ai/dsh-storage-json", "@deepseek-ai/dsh-workspace", "@deepseek-ai/dsh-system-prompt", "@deepseek-ai/dsh-terminal", "@deepseek-ai/dsh-terminal-bash", "@deepseek-ai/dsh-tool-ask-user", "@deepseek-ai/dsh-tool-bash-persistent", "@deepseek-ai/dsh-tool-cordis", "@deepseek-ai/dsh-user-approval", "@deepseek-ai/dsh-user-questions"];
9
+ export interface UpstreamDriftEntry {
10
+ package: string;
11
+ installed: string | undefined;
12
+ validated: string;
13
+ }
14
+ export declare function installedUpstreamVersions(): Record<string, string | undefined>;
15
+ /**
16
+ * Report every blessed package whose installed version is NOT the validated
17
+ * release line. Empty array = the running install matches the contract.
18
+ */
19
+ export declare function upstreamDrift(): UpstreamDriftEntry[];
20
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/contract.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,0BAA0B,eAAe,CAAA;AAEtD;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAG5D,CAAA;AAED,qEAAqE;AACrE,eAAO,MAAM,yBAAyB,6vBAyB5B,CAAA;AAEV,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,SAAS,EAAE,MAAM,CAAA;CAClB;AAWD,wBAAgB,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAgB9E;AAOD;;;GAGG;AACH,wBAAgB,aAAa,IAAI,kBAAkB,EAAE,CAsBpD"}