@deepseek-harness-tui/dsh-tui 0.11.0 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (484) hide show
  1. package/README.md +55 -20
  2. package/assets/whale-girl/whale-girl-dark.png +0 -0
  3. package/assets/whale-girl/whale-girl-happy.png +0 -0
  4. package/assets/whale-girl/whale-girl.png +0 -0
  5. package/bin/dsh-tui.js +63 -3
  6. package/cordis.patch.yml +43 -20
  7. package/cordis.yml +6 -4
  8. package/lib/settings.json +1272 -0
  9. package/lib/types/activityPrefs.d.ts +24 -0
  10. package/lib/types/activityPrefs.d.ts.map +1 -1
  11. package/lib/types/activityPrefs.js +50 -1
  12. package/lib/types/adapter/channel/state.d.ts.map +1 -1
  13. package/lib/types/adapter/channel/state.js +3 -1
  14. package/lib/types/adapter/channel/ui-policy.d.ts +9 -2
  15. package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
  16. package/lib/types/adapter/channel/ui-policy.js +14 -1
  17. package/lib/types/adapter/kernel/replay.d.ts.map +1 -1
  18. package/lib/types/adapter/kernel/replay.js +2 -0
  19. package/lib/types/adapter/ports/channel-display.d.ts +12 -0
  20. package/lib/types/adapter/ports/channel-display.d.ts.map +1 -1
  21. package/lib/types/adapter/ports/channel-session.d.ts +38 -0
  22. package/lib/types/adapter/ports/channel-session.d.ts.map +1 -1
  23. package/lib/types/adapter/ports/channel-settings.d.ts +12 -0
  24. package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
  25. package/lib/types/adapter/ports/channel-ui.d.ts +53 -7
  26. package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
  27. package/lib/types/adapter/ports/channel-view.d.ts +43 -12
  28. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
  29. package/lib/types/adapter/ports/channel.d.ts +4 -1
  30. package/lib/types/adapter/ports/channel.d.ts.map +1 -1
  31. package/lib/types/commands.d.ts.map +1 -1
  32. package/lib/types/commands.js +2 -0
  33. package/lib/types/components/ActivityLine.d.ts +7 -2
  34. package/lib/types/components/ActivityLine.d.ts.map +1 -1
  35. package/lib/types/components/ActivityLine.js +0 -8
  36. package/lib/types/components/BalanceReportRow.d.ts +10 -2
  37. package/lib/types/components/BalanceReportRow.d.ts.map +1 -1
  38. package/lib/types/components/BalanceReportRow.js +18 -4
  39. package/lib/types/components/CompactionStatusRow.d.ts +24 -0
  40. package/lib/types/components/CompactionStatusRow.d.ts.map +1 -0
  41. package/lib/types/components/CompactionStatusRow.js +72 -0
  42. package/lib/types/components/GoalTodoPanel.js +2 -2
  43. package/lib/types/components/HelpMenu.d.ts +2 -2
  44. package/lib/types/components/HelpMenu.d.ts.map +1 -1
  45. package/lib/types/components/HelpMenu.js +5 -4
  46. package/lib/types/components/InlineMathParagraph.d.ts +22 -0
  47. package/lib/types/components/InlineMathParagraph.d.ts.map +1 -0
  48. package/lib/types/components/InlineMathParagraph.js +178 -0
  49. package/lib/types/components/LogoV2.d.ts +41 -3
  50. package/lib/types/components/LogoV2.d.ts.map +1 -1
  51. package/lib/types/components/LogoV2.js +148 -24
  52. package/lib/types/components/Markdown.d.ts +10 -3
  53. package/lib/types/components/Markdown.d.ts.map +1 -1
  54. package/lib/types/components/Markdown.js +47 -14
  55. package/lib/types/components/MathBlock.d.ts +13 -0
  56. package/lib/types/components/MathBlock.d.ts.map +1 -0
  57. package/lib/types/components/MathBlock.js +136 -0
  58. package/lib/types/components/MessageList.d.ts +10 -1
  59. package/lib/types/components/MessageList.d.ts.map +1 -1
  60. package/lib/types/components/MessageList.js +15 -5
  61. package/lib/types/components/MigratePicker.d.ts +30 -0
  62. package/lib/types/components/MigratePicker.d.ts.map +1 -0
  63. package/lib/types/components/MigratePicker.js +38 -0
  64. package/lib/types/components/PromptInput.d.ts +17 -0
  65. package/lib/types/components/PromptInput.d.ts.map +1 -1
  66. package/lib/types/components/PromptInput.js +96 -9
  67. package/lib/types/components/SplitDiffView.d.ts.map +1 -1
  68. package/lib/types/components/SplitDiffView.js +3 -1
  69. package/lib/types/components/StarPrompt.d.ts +53 -0
  70. package/lib/types/components/StarPrompt.d.ts.map +1 -0
  71. package/lib/types/components/StarPrompt.js +281 -0
  72. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  73. package/lib/types/components/StreamingMarkdown.js +20 -3
  74. package/lib/types/components/SubagentCard.d.ts.map +1 -1
  75. package/lib/types/components/SubagentCard.js +12 -6
  76. package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
  77. package/lib/types/components/SubagentDetailScene.js +8 -3
  78. package/lib/types/components/TimelineRail.d.ts.map +1 -1
  79. package/lib/types/components/TimelineRail.js +9 -1
  80. package/lib/types/components/Whale.d.ts +17 -8
  81. package/lib/types/components/Whale.d.ts.map +1 -1
  82. package/lib/types/components/Whale.js +25 -15
  83. package/lib/types/components/WhaleGirl.d.ts +29 -0
  84. package/lib/types/components/WhaleGirl.d.ts.map +1 -0
  85. package/lib/types/components/WhaleGirl.js +32 -0
  86. package/lib/types/components/WorkingSpinner.d.ts +4 -1
  87. package/lib/types/components/WorkingSpinner.d.ts.map +1 -1
  88. package/lib/types/components/WorkingSpinner.js +2 -2
  89. package/lib/types/components/bigfont.d.ts +47 -18
  90. package/lib/types/components/bigfont.d.ts.map +1 -1
  91. package/lib/types/components/bigfont.js +55 -40
  92. package/lib/types/components/design-system/HintLine.d.ts +1 -2
  93. package/lib/types/components/design-system/HintLine.d.ts.map +1 -1
  94. package/lib/types/components/design-system/HintLine.js +1 -2
  95. package/lib/types/components/design-system/ThemeProvider.d.ts +6 -0
  96. package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
  97. package/lib/types/components/design-system/ThemeProvider.js +40 -1
  98. package/lib/types/components/maidPortrait.d.ts +44 -0
  99. package/lib/types/components/maidPortrait.d.ts.map +1 -0
  100. package/lib/types/components/maidPortrait.js +178 -0
  101. package/lib/types/components/mathPreview.d.ts +25 -0
  102. package/lib/types/components/mathPreview.d.ts.map +1 -0
  103. package/lib/types/components/mathPreview.js +48 -0
  104. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -1
  105. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  106. package/lib/types/components/messages/AssistantThinkingMessage.js +4 -2
  107. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +2 -2
  108. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  109. package/lib/types/components/messages/AssistantToolUseMessage.js +31 -26
  110. package/lib/types/components/messages/TranscriptImages.d.ts.map +1 -1
  111. package/lib/types/components/messages/TranscriptImages.js +11 -1
  112. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +14 -2
  113. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
  114. package/lib/types/components/questions/AskUserQuestionPanel.js +80 -38
  115. package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
  116. package/lib/types/components/questions/PlanReviewPanel.js +3 -3
  117. package/lib/types/components/sessions/ForeignSessionRow.d.ts +34 -0
  118. package/lib/types/components/sessions/ForeignSessionRow.d.ts.map +1 -0
  119. package/lib/types/components/sessions/ForeignSessionRow.js +43 -0
  120. package/lib/types/components/sessions/SourceTabs.d.ts +52 -0
  121. package/lib/types/components/sessions/SourceTabs.d.ts.map +1 -0
  122. package/lib/types/components/sessions/SourceTabs.js +70 -0
  123. package/lib/types/components/splashEggs.d.ts +56 -0
  124. package/lib/types/components/splashEggs.d.ts.map +1 -0
  125. package/lib/types/components/splashEggs.js +67 -0
  126. package/lib/types/components/splashFonts.d.ts +119 -0
  127. package/lib/types/components/splashFonts.d.ts.map +1 -0
  128. package/lib/types/components/splashFonts.js +267 -0
  129. package/lib/types/components/splashLayout.d.ts +41 -0
  130. package/lib/types/components/splashLayout.d.ts.map +1 -0
  131. package/lib/types/components/splashLayout.js +40 -0
  132. package/lib/types/components/whaleGirlSprite.d.ts +17 -0
  133. package/lib/types/components/whaleGirlSprite.d.ts.map +1 -0
  134. package/lib/types/components/whaleGirlSprite.js +47 -0
  135. package/lib/types/deepseekPricing.d.ts +74 -0
  136. package/lib/types/deepseekPricing.d.ts.map +1 -1
  137. package/lib/types/deepseekPricing.js +110 -11
  138. package/lib/types/dsh-adapter/activity-store.d.ts +221 -0
  139. package/lib/types/dsh-adapter/activity-store.d.ts.map +1 -0
  140. package/lib/types/dsh-adapter/activity-store.js +359 -0
  141. package/lib/types/dsh-adapter/channel/action-readiness.d.ts +1 -1
  142. package/lib/types/dsh-adapter/channel/action-readiness.d.ts.map +1 -1
  143. package/lib/types/dsh-adapter/channel/action-readiness.js +6 -1
  144. package/lib/types/dsh-adapter/channel/background-action.d.ts +2 -1
  145. package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -1
  146. package/lib/types/dsh-adapter/channel/background-action.js +2 -0
  147. package/lib/types/dsh-adapter/channel/binding-events.d.ts +15 -14
  148. package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
  149. package/lib/types/dsh-adapter/channel/binding-events.js +70 -21
  150. package/lib/types/dsh-adapter/channel/compaction.d.ts +2 -2
  151. package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
  152. package/lib/types/dsh-adapter/channel/compaction.js +35 -4
  153. package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -1
  154. package/lib/types/dsh-adapter/channel/local-actions.js +6 -1
  155. package/lib/types/dsh-adapter/channel/model-switch.d.ts +1 -2
  156. package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -1
  157. package/lib/types/dsh-adapter/channel/model-switch.js +6 -2
  158. package/lib/types/dsh-adapter/channel/paths.d.ts.map +1 -1
  159. package/lib/types/dsh-adapter/channel/paths.js +7 -1
  160. package/lib/types/dsh-adapter/channel/preferences.d.ts +1 -1
  161. package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -1
  162. package/lib/types/dsh-adapter/channel/preferences.js +16 -0
  163. package/lib/types/dsh-adapter/channel/projection.d.ts +1 -2
  164. package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
  165. package/lib/types/dsh-adapter/channel/projection.js +127 -17
  166. package/lib/types/dsh-adapter/channel/question-record.d.ts +76 -0
  167. package/lib/types/dsh-adapter/channel/question-record.d.ts.map +1 -0
  168. package/lib/types/dsh-adapter/channel/question-record.js +107 -0
  169. package/lib/types/dsh-adapter/channel/session-adoption.d.ts +1 -1
  170. package/lib/types/dsh-adapter/channel/session-adoption.d.ts.map +1 -1
  171. package/lib/types/dsh-adapter/channel/session-adoption.js +1 -0
  172. package/lib/types/dsh-adapter/channel/session-lineage.d.ts +42 -0
  173. package/lib/types/dsh-adapter/channel/session-lineage.d.ts.map +1 -0
  174. package/lib/types/dsh-adapter/channel/session-lineage.js +51 -0
  175. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +3 -1
  176. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -1
  177. package/lib/types/dsh-adapter/channel/session-live-adoption.js +10 -3
  178. package/lib/types/dsh-adapter/channel/session-metadata.d.ts +2 -1
  179. package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
  180. package/lib/types/dsh-adapter/channel/session-metadata.js +43 -9
  181. package/lib/types/dsh-adapter/channel/session-reset.d.ts +1 -1
  182. package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -1
  183. package/lib/types/dsh-adapter/channel/session-reset.js +7 -1
  184. package/lib/types/dsh-adapter/channel/session-resume.d.ts +2 -1
  185. package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
  186. package/lib/types/dsh-adapter/channel/session-resume.js +5 -2
  187. package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
  188. package/lib/types/dsh-adapter/channel/settings-host.js +8 -0
  189. package/lib/types/dsh-adapter/channel/state.d.ts +19 -1
  190. package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
  191. package/lib/types/dsh-adapter/channel/state.js +8 -3
  192. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +32 -17
  193. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
  194. package/lib/types/dsh-adapter/channel/subagent-projection.js +309 -8
  195. package/lib/types/dsh-adapter/channel/types.d.ts +1 -1
  196. package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -1
  197. package/lib/types/dsh-adapter/channel.d.ts +1 -1
  198. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  199. package/lib/types/dsh-adapter/channel.js +34 -18
  200. package/lib/types/dsh-adapter/compat/index.d.ts +1 -1
  201. package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -1
  202. package/lib/types/dsh-adapter/compat/index.js +1 -1
  203. package/lib/types/dsh-adapter/compat/messages.d.ts +6 -0
  204. package/lib/types/dsh-adapter/compat/messages.d.ts.map +1 -1
  205. package/lib/types/dsh-adapter/compat/messages.js +9 -0
  206. package/lib/types/dsh-adapter/compat/sessionLog.d.ts +18 -0
  207. package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -1
  208. package/lib/types/dsh-adapter/compat/sessionLog.js +18 -3
  209. package/lib/types/dsh-adapter/compat/settings.d.ts +2 -0
  210. package/lib/types/dsh-adapter/compat/settings.d.ts.map +1 -1
  211. package/lib/types/dsh-adapter/compat/settings.js +14 -0
  212. package/lib/types/dsh-adapter/contract.d.ts +5 -4
  213. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  214. package/lib/types/dsh-adapter/contract.js +9 -5
  215. package/lib/types/dsh-adapter/index.d.ts +36 -1
  216. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  217. package/lib/types/dsh-adapter/index.js +22 -6
  218. package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts +3 -0
  219. package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts.map +1 -0
  220. package/lib/types/dsh-adapter/migrate/adapters/claude-code.js +131 -0
  221. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.d.ts +17 -0
  222. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.d.ts.map +1 -0
  223. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.js +329 -0
  224. package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts +3 -0
  225. package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts.map +1 -0
  226. package/lib/types/dsh-adapter/migrate/adapters/codex.js +102 -0
  227. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.d.ts +16 -0
  228. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.d.ts.map +1 -0
  229. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.js +289 -0
  230. package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts +3 -0
  231. package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts.map +1 -0
  232. package/lib/types/dsh-adapter/migrate/adapters/grok-build.js +117 -0
  233. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.d.ts +13 -0
  234. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.d.ts.map +1 -0
  235. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.js +178 -0
  236. package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts +3 -0
  237. package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts.map +1 -0
  238. package/lib/types/dsh-adapter/migrate/adapters/omp.js +133 -0
  239. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.d.ts +60 -0
  240. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.d.ts.map +1 -0
  241. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.js +178 -0
  242. package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts +8 -0
  243. package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts.map +1 -0
  244. package/lib/types/dsh-adapter/migrate/adapters/scan.js +40 -0
  245. package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts +3 -0
  246. package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts.map +1 -0
  247. package/lib/types/dsh-adapter/migrate/adapters/zcode.js +93 -0
  248. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.d.ts +9 -0
  249. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.d.ts.map +1 -0
  250. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.js +89 -0
  251. package/lib/types/dsh-adapter/migrate/bin-path.d.ts +6 -0
  252. package/lib/types/dsh-adapter/migrate/bin-path.d.ts.map +1 -0
  253. package/lib/types/dsh-adapter/migrate/bin-path.js +30 -0
  254. package/lib/types/dsh-adapter/migrate/browse.d.ts +42 -0
  255. package/lib/types/dsh-adapter/migrate/browse.d.ts.map +1 -0
  256. package/lib/types/dsh-adapter/migrate/browse.js +90 -0
  257. package/lib/types/dsh-adapter/migrate/cli.d.ts +9 -0
  258. package/lib/types/dsh-adapter/migrate/cli.d.ts.map +1 -0
  259. package/lib/types/dsh-adapter/migrate/cli.js +106 -0
  260. package/lib/types/dsh-adapter/migrate/import-one.d.ts +89 -0
  261. package/lib/types/dsh-adapter/migrate/import-one.d.ts.map +1 -0
  262. package/lib/types/dsh-adapter/migrate/import-one.js +133 -0
  263. package/lib/types/dsh-adapter/migrate/index.d.ts +35 -0
  264. package/lib/types/dsh-adapter/migrate/index.d.ts.map +1 -0
  265. package/lib/types/dsh-adapter/migrate/index.js +107 -0
  266. package/lib/types/dsh-adapter/migrate/parse/injection.d.ts +40 -0
  267. package/lib/types/dsh-adapter/migrate/parse/injection.d.ts.map +1 -0
  268. package/lib/types/dsh-adapter/migrate/parse/injection.js +127 -0
  269. package/lib/types/dsh-adapter/migrate/parse/jsonl.d.ts +28 -0
  270. package/lib/types/dsh-adapter/migrate/parse/jsonl.d.ts.map +1 -0
  271. package/lib/types/dsh-adapter/migrate/parse/jsonl.js +40 -0
  272. package/lib/types/dsh-adapter/migrate/parse/role-turns.d.ts +28 -0
  273. package/lib/types/dsh-adapter/migrate/parse/role-turns.d.ts.map +1 -0
  274. package/lib/types/dsh-adapter/migrate/parse/role-turns.js +50 -0
  275. package/lib/types/dsh-adapter/migrate/parse/title.d.ts +18 -0
  276. package/lib/types/dsh-adapter/migrate/parse/title.d.ts.map +1 -0
  277. package/lib/types/dsh-adapter/migrate/parse/title.js +29 -0
  278. package/lib/types/dsh-adapter/migrate/parse/tools.d.ts +62 -0
  279. package/lib/types/dsh-adapter/migrate/parse/tools.d.ts.map +1 -0
  280. package/lib/types/dsh-adapter/migrate/parse/tools.js +110 -0
  281. package/lib/types/dsh-adapter/migrate/picker.d.ts +64 -0
  282. package/lib/types/dsh-adapter/migrate/picker.d.ts.map +1 -0
  283. package/lib/types/dsh-adapter/migrate/picker.js +86 -0
  284. package/lib/types/dsh-adapter/migrate/recent-agents.d.ts +40 -0
  285. package/lib/types/dsh-adapter/migrate/recent-agents.d.ts.map +1 -0
  286. package/lib/types/dsh-adapter/migrate/recent-agents.js +100 -0
  287. package/lib/types/dsh-adapter/migrate/sessionize.d.ts +39 -0
  288. package/lib/types/dsh-adapter/migrate/sessionize.d.ts.map +1 -0
  289. package/lib/types/dsh-adapter/migrate/sessionize.js +271 -0
  290. package/lib/types/dsh-adapter/migrate/types.d.ts +176 -0
  291. package/lib/types/dsh-adapter/migrate/types.d.ts.map +1 -0
  292. package/lib/types/dsh-adapter/migrate/types.js +11 -0
  293. package/lib/types/dsh-adapter/migrate/uuid.d.ts +7 -0
  294. package/lib/types/dsh-adapter/migrate/uuid.d.ts.map +1 -0
  295. package/lib/types/dsh-adapter/migrate/uuid.js +25 -0
  296. package/lib/types/dsh-adapter/plugin.d.ts +5 -3
  297. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  298. package/lib/types/dsh-adapter/plugin.js +168 -372
  299. package/lib/types/dsh-adapter/providerWizard.d.ts +17 -0
  300. package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -1
  301. package/lib/types/dsh-adapter/providerWizard.js +254 -66
  302. package/lib/types/dsh-adapter/questions.d.ts +22 -15
  303. package/lib/types/dsh-adapter/questions.d.ts.map +1 -1
  304. package/lib/types/dsh-adapter/questions.js +47 -45
  305. package/lib/types/dsh-adapter/sessions/digest.d.ts +11 -6
  306. package/lib/types/dsh-adapter/sessions/digest.d.ts.map +1 -1
  307. package/lib/types/dsh-adapter/sessions/digest.js +20 -13
  308. package/lib/types/dsh-adapter/sessions/frames.d.ts +3 -1
  309. package/lib/types/dsh-adapter/sessions/frames.d.ts.map +1 -1
  310. package/lib/types/dsh-adapter/sessions/frames.js +5 -4
  311. package/lib/types/dsh-adapter/sessions/list.d.ts +6 -1
  312. package/lib/types/dsh-adapter/sessions/list.d.ts.map +1 -1
  313. package/lib/types/dsh-adapter/sessions/list.js +188 -164
  314. package/lib/types/dsh-adapter/sessions/recovery.d.ts +16 -0
  315. package/lib/types/dsh-adapter/sessions/recovery.d.ts.map +1 -0
  316. package/lib/types/dsh-adapter/sessions/recovery.js +108 -0
  317. package/lib/types/dsh-adapter/sessions/snapshot.d.ts +7 -0
  318. package/lib/types/dsh-adapter/sessions/snapshot.d.ts.map +1 -0
  319. package/lib/types/dsh-adapter/sessions/snapshot.js +90 -0
  320. package/lib/types/dsh-adapter/sessions/store.d.ts +10 -4
  321. package/lib/types/dsh-adapter/sessions/store.d.ts.map +1 -1
  322. package/lib/types/dsh-adapter/sessions/store.js +62 -25
  323. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
  324. package/lib/types/dsh-adapter/settings-sections.js +7 -4
  325. package/lib/types/dsh-adapter/sideQuestion.d.ts +41 -2
  326. package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -1
  327. package/lib/types/dsh-adapter/sideQuestion.js +98 -2
  328. package/lib/types/dsh-adapter/subagents.d.ts +44 -6
  329. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
  330. package/lib/types/dsh-adapter/subagents.js +163 -26
  331. package/lib/types/herdr.d.ts +2 -0
  332. package/lib/types/herdr.d.ts.map +1 -1
  333. package/lib/types/herdr.js +9 -3
  334. package/lib/types/history.d.ts +13 -1
  335. package/lib/types/history.d.ts.map +1 -1
  336. package/lib/types/history.js +15 -2
  337. package/lib/types/i18n.d.ts +512 -41
  338. package/lib/types/i18n.d.ts.map +1 -1
  339. package/lib/types/i18n.js +199 -20
  340. package/lib/types/ink/components/App.d.ts +2 -2
  341. package/lib/types/ink/components/App.d.ts.map +1 -1
  342. package/lib/types/ink/components/App.js +5 -1
  343. package/lib/types/ink/components/Image.d.ts +14 -1
  344. package/lib/types/ink/components/Image.d.ts.map +1 -1
  345. package/lib/types/ink/components/Image.js +2 -2
  346. package/lib/types/ink/events/input-event.js +3 -3
  347. package/lib/types/ink/hooks/use-terminal-images.d.ts +12 -0
  348. package/lib/types/ink/hooks/use-terminal-images.d.ts.map +1 -1
  349. package/lib/types/ink/hooks/use-terminal-images.js +13 -0
  350. package/lib/types/ink/ink.d.ts +6 -0
  351. package/lib/types/ink/ink.d.ts.map +1 -1
  352. package/lib/types/ink/ink.js +16 -1
  353. package/lib/types/ink/kitty-graphics.d.ts +44 -3
  354. package/lib/types/ink/kitty-graphics.d.ts.map +1 -1
  355. package/lib/types/ink/kitty-graphics.js +184 -23
  356. package/lib/types/ink/log-update.d.ts.map +1 -1
  357. package/lib/types/ink/log-update.js +19 -1
  358. package/lib/types/ink/output.d.ts +24 -2
  359. package/lib/types/ink/output.d.ts.map +1 -1
  360. package/lib/types/ink/output.js +83 -5
  361. package/lib/types/ink/parse-keypress.d.ts +26 -1
  362. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  363. package/lib/types/ink/parse-keypress.js +156 -13
  364. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  365. package/lib/types/ink/render-node-to-output.js +8 -1
  366. package/lib/types/ink/screen.d.ts +24 -0
  367. package/lib/types/ink/screen.d.ts.map +1 -1
  368. package/lib/types/ink/screen.js +89 -0
  369. package/lib/types/ink/selection.d.ts +68 -18
  370. package/lib/types/ink/selection.d.ts.map +1 -1
  371. package/lib/types/ink/selection.js +178 -31
  372. package/lib/types/ink/sixel-codec.d.ts +12 -1
  373. package/lib/types/ink/sixel-codec.d.ts.map +1 -1
  374. package/lib/types/ink/sixel-codec.js +29 -5
  375. package/lib/types/ink/sixel-graphics.d.ts.map +1 -1
  376. package/lib/types/ink/sixel-graphics.js +5 -3
  377. package/lib/types/ink/styles.d.ts +9 -0
  378. package/lib/types/ink/styles.d.ts.map +1 -1
  379. package/lib/types/ink/terminal-image.d.ts +8 -0
  380. package/lib/types/ink/terminal-image.d.ts.map +1 -1
  381. package/lib/types/ink/terminal-querier.d.ts +7 -1
  382. package/lib/types/ink/terminal-querier.d.ts.map +1 -1
  383. package/lib/types/ink/terminal-querier.js +12 -2
  384. package/lib/types/ink/timeline-rail.d.ts +5 -0
  385. package/lib/types/ink/timeline-rail.d.ts.map +1 -1
  386. package/lib/types/math/inline-layout.d.ts +29 -0
  387. package/lib/types/math/inline-layout.d.ts.map +1 -0
  388. package/lib/types/math/inline-layout.js +106 -0
  389. package/lib/types/math/layout.d.ts +58 -0
  390. package/lib/types/math/layout.d.ts.map +1 -0
  391. package/lib/types/math/layout.js +59 -0
  392. package/lib/types/math/renderer.d.ts +64 -0
  393. package/lib/types/math/renderer.d.ts.map +1 -0
  394. package/lib/types/math/renderer.js +256 -0
  395. package/lib/types/screens/Chat.d.ts +17 -1
  396. package/lib/types/screens/Chat.d.ts.map +1 -1
  397. package/lib/types/screens/Chat.js +618 -57
  398. package/lib/types/screens/SessionSupervisor.d.ts +2 -1
  399. package/lib/types/screens/SessionSupervisor.d.ts.map +1 -1
  400. package/lib/types/screens/SessionSupervisor.js +156 -19
  401. package/lib/types/screens/Settings.d.ts.map +1 -1
  402. package/lib/types/screens/Settings.js +49 -11
  403. package/lib/types/screens/StatusLine.d.ts +5 -1
  404. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  405. package/lib/types/screens/StatusLine.js +47 -17
  406. package/lib/types/screens/chatOverlay.d.ts +5 -0
  407. package/lib/types/screens/chatOverlay.d.ts.map +1 -1
  408. package/lib/types/screens/chatOverlay.js +1 -0
  409. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.d.ts +47 -0
  410. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.d.ts.map +1 -0
  411. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.js +65 -0
  412. package/lib/types/screens/sessionSupervisor/model.d.ts +12 -0
  413. package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -1
  414. package/lib/types/screens/sessionSupervisor/model.js +26 -0
  415. package/lib/types/screens/sessionSupervisor/useForeignSessions.d.ts +107 -0
  416. package/lib/types/screens/sessionSupervisor/useForeignSessions.d.ts.map +1 -0
  417. package/lib/types/screens/sessionSupervisor/useForeignSessions.js +312 -0
  418. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts +4 -1
  419. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -1
  420. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +97 -14
  421. package/lib/types/sessionHistory.d.ts +2 -2
  422. package/lib/types/sessionHistory.d.ts.map +1 -1
  423. package/lib/types/sessionHistory.js +31 -5
  424. package/lib/types/settings/definitions.d.ts +681 -0
  425. package/lib/types/settings/definitions.d.ts.map +1 -0
  426. package/lib/types/settings/definitions.js +511 -0
  427. package/lib/types/starAction.d.ts +44 -0
  428. package/lib/types/starAction.d.ts.map +1 -0
  429. package/lib/types/starAction.js +52 -0
  430. package/lib/types/terminal-utils/latex.d.ts +10 -0
  431. package/lib/types/terminal-utils/latex.d.ts.map +1 -0
  432. package/lib/types/terminal-utils/latex.js +1417 -0
  433. package/lib/types/terminal-utils/markdown.d.ts +3 -1
  434. package/lib/types/terminal-utils/markdown.d.ts.map +1 -1
  435. package/lib/types/terminal-utils/markdown.js +26 -1
  436. package/lib/types/terminal-utils/math.d.ts +66 -0
  437. package/lib/types/terminal-utils/math.d.ts.map +1 -0
  438. package/lib/types/terminal-utils/math.js +337 -0
  439. package/lib/types/tips.d.ts.map +1 -1
  440. package/lib/types/tips.js +6 -0
  441. package/lib/types/tuiDisplayPrefs.d.ts +67 -0
  442. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
  443. package/lib/types/tuiDisplayPrefs.js +59 -0
  444. package/lib/types/ui.d.ts +1 -1
  445. package/lib/types/ui.d.ts.map +1 -1
  446. package/lib/types/ui.js +1 -1
  447. package/lib/types/usageStats.d.ts +98 -0
  448. package/lib/types/usageStats.d.ts.map +1 -0
  449. package/lib/types/usageStats.js +169 -0
  450. package/lib/types/utils/bmp.d.ts +17 -0
  451. package/lib/types/utils/bmp.d.ts.map +1 -0
  452. package/lib/types/utils/bmp.js +154 -0
  453. package/lib/types/utils/clipboard.d.ts +14 -2
  454. package/lib/types/utils/clipboard.d.ts.map +1 -1
  455. package/lib/types/utils/clipboard.js +143 -8
  456. package/lib/types/utils/fold-long-lines.d.ts +1 -1
  457. package/lib/types/utils/fold-long-lines.d.ts.map +1 -1
  458. package/lib/types/utils/fold-long-lines.js +3 -2
  459. package/lib/types/utils/keymap.d.ts +4 -1
  460. package/lib/types/utils/keymap.d.ts.map +1 -1
  461. package/lib/types/utils/keymap.js +8 -0
  462. package/lib/types/utils/modifiers.d.ts +4 -3
  463. package/lib/types/utils/modifiers.d.ts.map +1 -1
  464. package/lib/types/utils/modifiers.js +4 -3
  465. package/lib/types/working-activity.d.ts +10 -9
  466. package/lib/types/working-activity.d.ts.map +1 -1
  467. package/lib/types/working-activity.js +17 -10
  468. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/LICENSE +202 -0
  469. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/NOTICE +20 -0
  470. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/index.d.ts +16 -0
  471. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/bundled-packages.json +4 -0
  472. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/index.mjs +20 -0
  473. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/index.mjs.LEGAL.txt +35 -0
  474. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/package.json +29 -0
  475. package/package.json +117 -99
  476. package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +0 -19
  477. package/lib/types/components/design-system/KeyboardShortcutHint.d.ts.map +0 -1
  478. package/lib/types/components/design-system/KeyboardShortcutHint.js +0 -14
  479. package/lib/types/dsh-adapter/channel/activity.d.ts +0 -20
  480. package/lib/types/dsh-adapter/channel/activity.d.ts.map +0 -1
  481. package/lib/types/dsh-adapter/channel/activity.js +0 -113
  482. package/lib/types/terminal-utils/terminal.d.ts +0 -18
  483. package/lib/types/terminal-utils/terminal.d.ts.map +0 -1
  484. package/lib/types/terminal-utils/terminal.js +0 -96
@@ -4,12 +4,13 @@ import { ARGS_PREVIEW_LIMIT, harnessToolResultView, LOCAL_OUTPUT_LIMIT, prepareR
4
4
  import { estimateTokens, isTokenDelta, tokenDeltaChars, usageOutputTokens } from './usage.js';
5
5
  import { transcriptImagesOf } from '../transcript-images.js';
6
6
  import { isCompactionCheckpointSource, toolResultPayload } from '../compat/messages.js';
7
- import { isPeakHour } from '../../deepseekPricing.js';
7
+ import { addUsageToCostBuckets, emptyCostBuckets, isPeakHour } from '../../deepseekPricing.js';
8
8
  import { t } from '../../i18n.js';
9
9
  import { logForDebugging } from '../../utils/debug.js';
10
10
  import { cleanRenderText } from '../sanitize.js';
11
11
  import { NOTICE_CELLS } from './decisions.js';
12
12
  import { markChannelReadDirty } from '../../adapter/channel/read-view.js';
13
+ import { buildQuestionRecord, parseQuestionRecordAnswers, parseQuestionRecordQuestions, } from './question-record.js';
13
14
  /** One authoritative reducer for both durable replay and live session events. */
14
15
  export function createChannelProjection(state, deps) {
15
16
  /** The in-progress assistant text row; `undefined` when no step is streaming. */
@@ -34,6 +35,15 @@ export function createChannelProjection(state, deps) {
34
35
  let tpsStep;
35
36
  /** Tool cards by callId, so tool/result can settle the running card. */
36
37
  const toolCards = new Map();
38
+ /**
39
+ * `ask_user_question` calls by callId, holding their raw arguments. The ask
40
+ * renders as the interactive panel rather than a tool card, so its result
41
+ * has no card to settle — but the answered record is still a transcript
42
+ * fact and must come from the durable log (issue #1009), never from the
43
+ * view. Remembering the call lets `tool/result` derive that record on the
44
+ * live stream AND on every replay (`/resume`, rewind, model switch).
45
+ */
46
+ const askCalls = new Map();
37
47
  /**
38
48
  * Session events are delivered live and can also be replayed around a
39
49
  * reconnect. A repeated sealed message must not create a second assistant
@@ -46,6 +56,11 @@ export function createChannelProjection(state, deps) {
46
56
  let openStep;
47
57
  let activeAttempt;
48
58
  let lastStreamRevision = -1;
59
+ /** 最近一次 request/header 的模型:durable usage 的模型归属真源。replay
60
+ * 会按历史请求逐个还原,因此 /model 切换(reset + replay 整个 seed)
61
+ * 不会把换模型前的用量重估到新模型;旧日志没有 header 时回退
62
+ * 事件发生时的 state.model(AC-A4)。 */
63
+ let eventModel;
49
64
  const assistantRowsByStep = new Map();
50
65
  const lastTextDelta = new Map();
51
66
  const stepKey = (turn, step) => `${turn}:${step}`;
@@ -268,6 +283,40 @@ export function createChannelProjection(state, deps) {
268
283
  if (folded > 0)
269
284
  logForDebugging(`thinking: folded ${folded} reasoning row(s) at turn settle`);
270
285
  };
286
+ /**
287
+ * Project one answered `ask_user_question` result into the transcript.
288
+ *
289
+ * The row shape reuses what `pushLocal` emits (`local` title + one
290
+ * `local-output` per line), so rendering, preview clipping and the local
291
+ * rows' fold exemption all keep their existing behavior. A failed ask
292
+ * renders the log's own error text — never a fabricated answer (the ask
293
+ * was cancelled/aborted, so no human ever chose anything).
294
+ */
295
+ const projectAskResult = (event, rawArguments) => {
296
+ const append = (record) => {
297
+ appendRow({ id: deps.rowIds.value, kind: 'local', text: record.title, seq: event.seq });
298
+ deps.rowIds.value += 1;
299
+ for (const line of record.lines) {
300
+ appendRow({
301
+ id: deps.rowIds.value,
302
+ kind: 'local-output',
303
+ text: preview(line, LOCAL_OUTPUT_LIMIT),
304
+ seq: event.seq,
305
+ });
306
+ deps.rowIds.value += 1;
307
+ }
308
+ };
309
+ if (event.data.error !== undefined || toolResultPayload(event.data.message).isError) {
310
+ const errorText = toolErrorText(event);
311
+ append({ title: errorText, lines: [] });
312
+ return;
313
+ }
314
+ const answers = parseQuestionRecordAnswers(textOf(toolResultPayload(event.data.message).content));
315
+ // No parseable answers (unparseable durable payload, or an older host):
316
+ // `answers: []` still yields the title, so the transcript shows that a
317
+ // questionnaire happened instead of dropping the fact silently.
318
+ append(buildQuestionRecord(parseQuestionRecordQuestions(rawArguments), answers ?? []));
319
+ };
271
320
  /** Recompute the spinner phase from live row/tool state. */
272
321
  const updateSpinnerMode = () => {
273
322
  if (state.activeToolCount > 0) {
@@ -332,6 +381,7 @@ export function createChannelProjection(state, deps) {
332
381
  openStep = undefined;
333
382
  activeAttempt = undefined;
334
383
  lastStreamRevision = -1;
384
+ eventModel = undefined;
335
385
  assistantRowsByStep.clear();
336
386
  lastTextDelta.clear();
337
387
  replaying = true;
@@ -438,7 +488,7 @@ export function createChannelProjection(state, deps) {
438
488
  // than disappearing with the other injected context.
439
489
  if (isCompactionCheckpointSource(event.data.source)) {
440
490
  const summary = textOf(event.data.content);
441
- appendRow({ id: deps.rowIds.value, kind: 'notice', text: 'Session summary is ready' });
491
+ appendRow({ id: deps.rowIds.value, kind: 'notice', text: t('compact-done') });
442
492
  deps.rowIds.value += 1;
443
493
  if (summary) {
444
494
  appendRow({ id: deps.rowIds.value, kind: 'compact', text: summary });
@@ -646,8 +696,9 @@ export function createChannelProjection(state, deps) {
646
696
  // replays historical events, so a resumed session prices each
647
697
  // request at the rate window it actually ran in — the session cost
648
698
  // estimate never prices the whole session at the current window).
699
+ const peak = isPeakHour(new Date(event.time));
649
700
  {
650
- const bucket = isPeakHour(new Date(event.time))
701
+ const bucket = peak
651
702
  ? state.tokens.peak
652
703
  : state.tokens.idle;
653
704
  bucket.input += usage.inputTokens ?? 0;
@@ -655,6 +706,24 @@ export function createChannelProjection(state, deps) {
655
706
  bucket.cacheRead += usage.cacheReadTokens ?? 0;
656
707
  bucket.cacheWrite += usage.cacheWriteTokens ?? 0;
657
708
  }
709
+ // 主会话费用分桶(DESIGN D2):与 tokens 同口径,但按事件发生时
710
+ // 的模型归属——replay 用 request/header 还原历史请求模型,旧日志
711
+ // 回退 channel 模型;换模型不会把历史 token 重估到新模型。
712
+ const costInput = usage.inputTokens ?? 0;
713
+ const costOutput = usage.outputTokens ?? 0;
714
+ const costCacheRead = usage.cacheReadTokens ?? 0;
715
+ const costCacheWrite = usage.cacheWriteTokens ?? 0;
716
+ if (costInput !== 0 || costOutput !== 0 || costCacheRead !== 0 || costCacheWrite !== 0) {
717
+ const model = eventModel ?? state.model;
718
+ const cost = state.mainCost[model] ?? emptyCostBuckets();
719
+ addUsageToCostBuckets(cost, {
720
+ input: costInput,
721
+ output: costOutput,
722
+ cacheRead: costCacheRead,
723
+ cacheWrite: costCacheWrite,
724
+ }, peak);
725
+ state.mainCost[model] = cost;
726
+ }
658
727
  // The most recent request's usage describes the CURRENT context:
659
728
  // input (uncached) + cache hits all occupy the window. Cache hits
660
729
  // also drive the status-line `cache N` readout.
@@ -707,25 +776,21 @@ export function createChannelProjection(state, deps) {
707
776
  // The ask-user-question tool renders as the interactive questionnaire
708
777
  // panel (DSH user-interaction seam), not as a tool card: the model is
709
778
  // parked waiting for the human, so no running card, no active-tool
710
- // spinner, no args noise in the transcript. The Q&A summary is pushed
711
- // by the TUI once the batch is answered; tool/result for a call with
712
- // no card is a no-op below.
713
- if (event.data.name === 'ask_user_question')
779
+ // spinner, no args noise in the transcript. Only the ARGUMENTS are
780
+ // remembered: the paired tool/result below projects the answered
781
+ // record from them (issue #1009), so `/resume`, rewind and replay
782
+ // rebuild it from the persisted log like every other transcript row.
783
+ if (event.data.name === 'ask_user_question') {
784
+ askCalls.set(event.data.callId, event.data.arguments);
714
785
  break;
786
+ }
715
787
  // The Task tool's plain card is replaced by the live subagent card
716
788
  // (Kimi Code semantics): the delegation itself renders as a subagent
717
789
  // row, so the raw args/result card would only duplicate it. The call
718
790
  // still runs - only its transcript rendering is suppressed.
719
791
  if (isSubagentToolName(event.data.name)) {
720
- try {
721
- const args = JSON.parse(event.data.arguments);
722
- if (typeof args.description === 'string' && args.description)
723
- deps.pendingTaskDescriptions.push(args.description);
724
- }
725
- catch {
726
- // Unparseable args leave the queue untouched; the card falls back
727
- // to the provider label.
728
- }
792
+ // The parent-scoped subagent reducer owns pending descriptions,
793
+ // including delegations made while this transcript is parked.
729
794
  break;
730
795
  }
731
796
  // Reasoning that led to a tool call is done thinking — fold the
@@ -759,7 +824,19 @@ export function createChannelProjection(state, deps) {
759
824
  break;
760
825
  }
761
826
  case 'tool/result': {
762
- const card = toolCards.get(event.data.message.source.callId);
827
+ const callId = event.data.message.source.callId;
828
+ const card = toolCards.get(callId);
829
+ const askArguments = askCalls.get(callId);
830
+ // A call with no card is usually an ask_user_question (above) — its
831
+ // interaction lives in the panel, but its OUTCOME still belongs in
832
+ // the transcript. Project it from the durable log here: consumed
833
+ // before the card branch so the two can never both fire, and deleted
834
+ // so a repeated replay of the same result cannot double the record.
835
+ if (card === undefined && askArguments !== undefined) {
836
+ projectAskResult(event, askArguments);
837
+ askCalls.delete(callId);
838
+ break;
839
+ }
763
840
  if (card !== undefined && card.tool !== undefined) {
764
841
  const images = transcriptImages(event.data.message.content);
765
842
  card.images = images.length === 0 ? undefined : images;
@@ -924,6 +1001,12 @@ export function createChannelProjection(state, deps) {
924
1001
  if (typeof effort === 'string') {
925
1002
  state.reasoningEffort = effort;
926
1003
  }
1004
+ // 模型归属真源:该请求的 usage 按这里的 model 计价(replay 时逐请求
1005
+ // 还原;live 时与 state.model 同步更新,AC-A4)。header 缺/空 model
1006
+ // 必须清掉上一条 header 的值——否则后续 usage 会沿用旧模型进错桶;
1007
+ // 归属时再回退 state.model(旧日志没有 header 的既有语义)。
1008
+ const headerModel = event.data.header.config?.model;
1009
+ eventModel = typeof headerModel === 'string' && headerModel !== '' ? headerModel : undefined;
927
1010
  const legacySystem = event.data.header.system;
928
1011
  if (typeof legacySystem === 'string') {
929
1012
  state.contextSegments.system = estimateTokens(legacySystem);
@@ -982,6 +1065,31 @@ export function createChannelProjection(state, deps) {
982
1065
  state.sessionColor = typeof data.color === 'string' ? data.color : '';
983
1066
  break;
984
1067
  }
1068
+ // The compaction bracket is a plugin-appended event pair (not part of
1069
+ // dsh-session's typed map). Opening it here rather than in the manual
1070
+ // path is what makes an AUTOMATIC pressure compaction visible too: the
1071
+ // host writes `compaction/start` before the summarizer runs and
1072
+ // `compaction/end` once the checkpoint is committed or abandoned.
1073
+ // A manual request already installed its own cancellable row, so this
1074
+ // only fills the gap for one this process did not start.
1075
+ if (event.type === 'compaction/start') {
1076
+ // Replay is settled history, and a process killed between start and
1077
+ // end leaves an unmatched start in the log: painting a row for it
1078
+ // would show a compaction that nothing will ever clear.
1079
+ if (!replaying && state.compaction === undefined) {
1080
+ state.compaction = {
1081
+ startedAt: typeof event.time === 'number' ? event.time : Date.now(),
1082
+ phase: 'prefill',
1083
+ outputChars: 0,
1084
+ cancellable: false,
1085
+ };
1086
+ }
1087
+ break;
1088
+ }
1089
+ if (event.type === 'compaction/end') {
1090
+ state.compaction = undefined;
1091
+ break;
1092
+ }
985
1093
  // Custom plugin events (tuiRenderers seam): a registered renderer
986
1094
  // maps the payload to text rows — title as a local row, body as
987
1095
  // preview-clipped local-output rows, same shape pushLocal uses.
@@ -1014,11 +1122,13 @@ export function createChannelProjection(state, deps) {
1014
1122
  sealedReasoning.length = 0;
1015
1123
  lastReasoningRow = undefined;
1016
1124
  toolCards.clear();
1125
+ askCalls.clear();
1017
1126
  handledAssistantMessages.clear();
1018
1127
  handledAssistantChunks.clear();
1019
1128
  openStep = undefined;
1020
1129
  activeAttempt = undefined;
1021
1130
  lastStreamRevision = -1;
1131
+ eventModel = undefined;
1022
1132
  assistantRowsByStep.clear();
1023
1133
  lastTextDelta.clear();
1024
1134
  tpsTurn = undefined;
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Answered-questionnaire transcript record — a PURE fold of the durable
3
+ * session log (issue #1009).
4
+ *
5
+ * `ask_user_question` renders as the interactive panel, not as a tool card,
6
+ * so its `tool/result` had no renderer at all: the answers lived only in the
7
+ * current process's view rows (the TUI used to push a summary when the panel
8
+ * closed). That violated the transcript's source-of-truth rule — `/resume`,
9
+ * rewind, `loadOlder` and any replay lost the record, and an ask that was
10
+ * never observed closing produced none at all.
11
+ *
12
+ * The record now derives from the same log every other transcript row comes
13
+ * from: the `tool/call` arguments carry the questions, the `tool/result`
14
+ * payload carries the answers. Both are parsed at the caller's edge here, so
15
+ * this module stays pure (no store, no i18n state, no projection imports) and
16
+ * is directly testable.
17
+ */
18
+ /**
19
+ * The parts of a question this fold needs. Structurally compatible with the
20
+ * harness's `AskUserQuestionItem`, so `src/dsh-adapter/` callers pass the
21
+ * official type straight through while this module keeps its own shape.
22
+ */
23
+ export interface QuestionRecordQuestion {
24
+ readonly question: string;
25
+ }
26
+ /**
27
+ * One answer as the harness persists it (a subset of
28
+ * `AskUserQuestionAnswerItem`: the fold matches answers to questions BY ORDER,
29
+ * mirroring how the panel collects one answer per question).
30
+ */
31
+ export interface QuestionRecordAnswer {
32
+ readonly selected: readonly string[];
33
+ readonly custom?: string;
34
+ }
35
+ /** One answered questionnaire as the transcript renders it. */
36
+ export interface QuestionRecord {
37
+ /** Local-row title (dictionary text, never hand-written here). */
38
+ readonly title: string;
39
+ /** One `· question → answer` line per answered question. */
40
+ readonly lines: readonly string[];
41
+ }
42
+ /**
43
+ * Fold one answered questionnaire into its transcript record.
44
+ *
45
+ * Tolerant by contract: the projection calls this on durable replay data it
46
+ * does not control (truncated logs, older hosts, a wizard-shaped caller), and
47
+ * a throw inside `renderEvent` would abort the whole transcript fold. So a
48
+ * missing/garbled question list or answer item degrades to a shorter line
49
+ * instead of raising.
50
+ *
51
+ * @param questions - The ask's questions, in the order they were answered.
52
+ * @param answers - The answers the log recorded for that same ask.
53
+ * @param options - `redact` masks answer text (local wizards collecting
54
+ * secrets such as API keys must never leak into the transcript or an
55
+ * `/export` dump); the model-side ask never sets it.
56
+ * @returns The title line plus its `· question → choice` body lines.
57
+ */
58
+ export declare function buildQuestionRecord(questions: readonly (QuestionRecordQuestion | undefined)[] | undefined, answers: readonly (QuestionRecordAnswer | undefined)[] | undefined, options?: {
59
+ redact?: boolean;
60
+ }): QuestionRecord;
61
+ /**
62
+ * Parse the questions out of a persisted `ask_user_question` `tool/call`
63
+ * arguments string. Returns `undefined` when the payload is not the
64
+ * `{ questions: [...] }` object the tool declares, so the caller can fall
65
+ * back to a title-only record.
66
+ */
67
+ export declare function parseQuestionRecordQuestions(rawArguments: string | undefined): QuestionRecordQuestion[] | undefined;
68
+ /**
69
+ * Parse the answers out of a `tool/result` text payload. `dsh-tool-ask-user`
70
+ * renders its output as one JSON text block — the same bytes the model reads
71
+ * back — so the durable log is a sufficient source. A failed ask (or any
72
+ * non-JSON body) yields `undefined`: the caller then renders the log's own
73
+ * error text instead of fabricating an answer.
74
+ */
75
+ export declare function parseQuestionRecordAnswers(rawResult: string): QuestionRecordAnswer[] | undefined;
76
+ //# sourceMappingURL=question-record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-record.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/channel/question-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAClC;AAQD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,SAAS,CAAC,sBAAsB,GAAG,SAAS,CAAC,EAAE,GAAG,SAAS,EACtE,OAAO,EAAE,SAAS,CAAC,oBAAoB,GAAG,SAAS,CAAC,EAAE,GAAG,SAAS,EAClE,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,cAAc,CAyBhB;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,sBAAsB,EAAE,GAAG,SAAS,CAWnH;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,oBAAoB,EAAE,GAAG,SAAS,CAShG"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Answered-questionnaire transcript record — a PURE fold of the durable
3
+ * session log (issue #1009).
4
+ *
5
+ * `ask_user_question` renders as the interactive panel, not as a tool card,
6
+ * so its `tool/result` had no renderer at all: the answers lived only in the
7
+ * current process's view rows (the TUI used to push a summary when the panel
8
+ * closed). That violated the transcript's source-of-truth rule — `/resume`,
9
+ * rewind, `loadOlder` and any replay lost the record, and an ask that was
10
+ * never observed closing produced none at all.
11
+ *
12
+ * The record now derives from the same log every other transcript row comes
13
+ * from: the `tool/call` arguments carry the questions, the `tool/result`
14
+ * payload carries the answers. Both are parsed at the caller's edge here, so
15
+ * this module stays pure (no store, no i18n state, no projection imports) and
16
+ * is directly testable.
17
+ */
18
+ import { t } from '../../i18n.js';
19
+ /** Truncate a long answer line for the transcript summary. */
20
+ function clip(text, max = 140) {
21
+ if (text.length <= max)
22
+ return text;
23
+ return `${text.slice(0, max)}…`;
24
+ }
25
+ /**
26
+ * Fold one answered questionnaire into its transcript record.
27
+ *
28
+ * Tolerant by contract: the projection calls this on durable replay data it
29
+ * does not control (truncated logs, older hosts, a wizard-shaped caller), and
30
+ * a throw inside `renderEvent` would abort the whole transcript fold. So a
31
+ * missing/garbled question list or answer item degrades to a shorter line
32
+ * instead of raising.
33
+ *
34
+ * @param questions - The ask's questions, in the order they were answered.
35
+ * @param answers - The answers the log recorded for that same ask.
36
+ * @param options - `redact` masks answer text (local wizards collecting
37
+ * secrets such as API keys must never leak into the transcript or an
38
+ * `/export` dump); the model-side ask never sets it.
39
+ * @returns The title line plus its `· question → choice` body lines.
40
+ */
41
+ export function buildQuestionRecord(questions, answers, options) {
42
+ const list = questions ?? [];
43
+ const lines = list.flatMap((question, index) => {
44
+ const answer = answers?.[index];
45
+ if (question === undefined || question === null || answer === undefined || answer === null)
46
+ return [];
47
+ // The question text comes from durable args too — a garbled entry must
48
+ // not turn into the string "undefined" in the transcript.
49
+ const prompt = typeof question.question === 'string' ? question.question : '';
50
+ const selected = Array.isArray(answer.selected) ? answer.selected : [];
51
+ if (prompt === '' && selected.length === 0 && (answer.custom ?? '') === '')
52
+ return [];
53
+ const text = options?.redact === true
54
+ ? '••••••'
55
+ : (() => {
56
+ const labels = selected.join('、');
57
+ const custom = answer.custom ?? '';
58
+ return custom !== ''
59
+ ? labels === '' ? custom : `${labels}:${custom}`
60
+ : labels;
61
+ })();
62
+ return `· ${prompt} → ${clip(text)}`;
63
+ });
64
+ return {
65
+ title: t('questionnaire-answered', { total: list.length }),
66
+ lines,
67
+ };
68
+ }
69
+ /**
70
+ * Parse the questions out of a persisted `ask_user_question` `tool/call`
71
+ * arguments string. Returns `undefined` when the payload is not the
72
+ * `{ questions: [...] }` object the tool declares, so the caller can fall
73
+ * back to a title-only record.
74
+ */
75
+ export function parseQuestionRecordQuestions(rawArguments) {
76
+ try {
77
+ const parsed = JSON.parse(rawArguments ?? '');
78
+ if (typeof parsed !== 'object' || parsed === null)
79
+ return undefined;
80
+ const questions = parsed.questions;
81
+ return Array.isArray(questions) ? questions : undefined;
82
+ }
83
+ catch {
84
+ // Unparseable arguments are historical/foreign data, not a program bug:
85
+ // degrade to a title-only record rather than aborting the transcript fold.
86
+ return undefined;
87
+ }
88
+ }
89
+ /**
90
+ * Parse the answers out of a `tool/result` text payload. `dsh-tool-ask-user`
91
+ * renders its output as one JSON text block — the same bytes the model reads
92
+ * back — so the durable log is a sufficient source. A failed ask (or any
93
+ * non-JSON body) yields `undefined`: the caller then renders the log's own
94
+ * error text instead of fabricating an answer.
95
+ */
96
+ export function parseQuestionRecordAnswers(rawResult) {
97
+ try {
98
+ const parsed = JSON.parse(rawResult);
99
+ if (typeof parsed !== 'object' || parsed === null)
100
+ return undefined;
101
+ const answers = parsed.answers;
102
+ return Array.isArray(answers) ? answers : undefined;
103
+ }
104
+ catch {
105
+ return undefined;
106
+ }
107
+ }
@@ -4,7 +4,7 @@ import type { ChannelState } from './types.js';
4
4
  import type { createChannelBinding } from './binding.js';
5
5
  import { resetSessionProjection } from './session-reset.js';
6
6
  type Binding = ReturnType<typeof createChannelBinding>;
7
- type AdoptionState = Pick<ChannelState, 'status' | 'agentId' | 'agentPreset' | 'working' | 'emit'>;
7
+ type AdoptionState = Pick<ChannelState, 'status' | 'agentId' | 'sessionId' | 'agentPreset' | 'working' | 'emit'>;
8
8
  /**
9
9
  * Binding-transaction tails shared by session actions. Construction is inert:
10
10
  * callers install the returned operations only after their ChannelState exists.
@@ -1 +1 @@
1
- {"version":3,"file":"session-adoption.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/channel/session-adoption.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAE3D,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACtD,KAAK,aAAa,GAAG,IAAI,CACvB,YAAY,EACV,QAAQ,GACR,SAAS,GACT,aAAa,GACb,SAAS,GACT,MAAM,CACT,CAAA;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,aAAa,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,EACnE,IAAI,EAAE;IACJ,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC/B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IACzB,cAAc,IAAI,IAAI,CAAA;IACtB,cAAc,IAAI,IAAI,CAAA;IACtB,SAAS,IAAI,IAAI,CAAA;IACjB,MAAM,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI,CAAA;IAC7C,YAAY,IAAI,IAAI,CAAA;IACpB,SAAS,IAAI,IAAI,CAAA;IACjB,eAAe,IAAI,IAAI,CAAA;IACvB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,iBAAiB,IAAI,IAAI,CAAA;IACzB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAA;CACzC;+BAQS,WAAW,WACV,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QACjC,SAAS,YAAY,EAAE,eAChB,MAAM,GAAG,SAAS,WACtB,SAAS,KACjB,MAAM;EAwBV"}
1
+ {"version":3,"file":"session-adoption.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/channel/session-adoption.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAE3D,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACtD,KAAK,aAAa,GAAG,IAAI,CACvB,YAAY,EACV,QAAQ,GACR,SAAS,GACT,WAAW,GACX,aAAa,GACb,SAAS,GACT,MAAM,CACT,CAAA;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,aAAa,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,EACnE,IAAI,EAAE;IACJ,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC/B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IACzB,cAAc,IAAI,IAAI,CAAA;IACtB,cAAc,IAAI,IAAI,CAAA;IACtB,SAAS,IAAI,IAAI,CAAA;IACjB,MAAM,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI,CAAA;IAC7C,YAAY,IAAI,IAAI,CAAA;IACpB,SAAS,IAAI,IAAI,CAAA;IACjB,eAAe,IAAI,IAAI,CAAA;IACvB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,iBAAiB,IAAI,IAAI,CAAA;IACzB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAA;CACzC;+BAQS,WAAW,WACV,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QACjC,SAAS,YAAY,EAAE,eAChB,MAAM,GAAG,SAAS,WACtB,SAAS,KACjB,MAAM;EAyBV"}
@@ -14,6 +14,7 @@ export function createSessionAdoption(state, deps) {
14
14
  resetSessionProjection(state, deps.rowIds, deps.resetProjector, deps.resetSubagents, deps.resetJobs);
15
15
  state.status = handle.agent.status;
16
16
  state.agentId = handle.agent.id;
17
+ state.sessionId = handle.agent.session.id;
17
18
  state.agentPreset = agentPreset;
18
19
  deps.replay(seed);
19
20
  deps.settleReplay();
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Lineage decision consulted by `/model` only.
3
+ *
4
+ * `/rewind` and the `/tree` branch also re-create the live session as a child,
5
+ * but they always record `parentSession` and do not call this helper. A blank
6
+ * log cannot reach them (`boundary < 0`). This module is not their gate.
7
+ *
8
+ * The decision is load-bearing beyond grouping. Upstream's automatic session
9
+ * title only ever runs on a session WITHOUT a parent: `dsh-session-title`
10
+ * schedules its provider on the first human message under
11
+ * `session.header.parentSession === undefined`, and a session that already has
12
+ * one is never offered a generated title again — a fork keeps the title it
13
+ * inherited, and only an explicit `ctx.sessionTitle.refresh()` retries, which
14
+ * no TUI surface calls. A route switch on a session nobody has typed into
15
+ * would therefore cost that user the title of their first real prompt, leaving
16
+ * the deterministic fallback instead (a mid-word truncation of the prompt at
17
+ * `fallbackMaxBytes`).
18
+ *
19
+ * A session with no human message has no conversation for the lineage to
20
+ * describe, so its replacement stands as its own root — the same independent-
21
+ * conversation choice `/fork` already makes (`session-fork.ts`), for the same
22
+ * reason. The seeded prefix is unaffected either way: the child still inherits
23
+ * the source's session scaffolding verbatim.
24
+ *
25
+ * @module
26
+ */
27
+ import type { SessionEvent } from '@deepseek-ai/dsh-session';
28
+ /**
29
+ * Whether a re-created child must record the session it replaces as its parent.
30
+ *
31
+ * A `user/message` whose `source` is the person at the keyboard is a human turn
32
+ * whether or not it carries text (an image-only prompt is still a prompt), so
33
+ * its session is a conversation the lineage must describe. A user-role message
34
+ * from any other producer — a plugin injection, an instruction snapshot, a
35
+ * skill catalogue — is not: the child stays in the same family rather than
36
+ * being promoted to a root on a technicality.
37
+ *
38
+ * @param seed - the exact events the child inherits.
39
+ * @returns whether the child records `parentSession`.
40
+ */
41
+ export declare function childRecordsLineage(seed: readonly SessionEvent[]): boolean;
42
+ //# sourceMappingURL=session-lineage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-lineage.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/channel/session-lineage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAE5D;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAE1E"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Lineage decision consulted by `/model` only.
3
+ *
4
+ * `/rewind` and the `/tree` branch also re-create the live session as a child,
5
+ * but they always record `parentSession` and do not call this helper. A blank
6
+ * log cannot reach them (`boundary < 0`). This module is not their gate.
7
+ *
8
+ * The decision is load-bearing beyond grouping. Upstream's automatic session
9
+ * title only ever runs on a session WITHOUT a parent: `dsh-session-title`
10
+ * schedules its provider on the first human message under
11
+ * `session.header.parentSession === undefined`, and a session that already has
12
+ * one is never offered a generated title again — a fork keeps the title it
13
+ * inherited, and only an explicit `ctx.sessionTitle.refresh()` retries, which
14
+ * no TUI surface calls. A route switch on a session nobody has typed into
15
+ * would therefore cost that user the title of their first real prompt, leaving
16
+ * the deterministic fallback instead (a mid-word truncation of the prompt at
17
+ * `fallbackMaxBytes`).
18
+ *
19
+ * A session with no human message has no conversation for the lineage to
20
+ * describe, so its replacement stands as its own root — the same independent-
21
+ * conversation choice `/fork` already makes (`session-fork.ts`), for the same
22
+ * reason. The seeded prefix is unaffected either way: the child still inherits
23
+ * the source's session scaffolding verbatim.
24
+ *
25
+ * @module
26
+ */
27
+ /**
28
+ * Whether a re-created child must record the session it replaces as its parent.
29
+ *
30
+ * A `user/message` whose `source` is the person at the keyboard is a human turn
31
+ * whether or not it carries text (an image-only prompt is still a prompt), so
32
+ * its session is a conversation the lineage must describe. A user-role message
33
+ * from any other producer — a plugin injection, an instruction snapshot, a
34
+ * skill catalogue — is not: the child stays in the same family rather than
35
+ * being promoted to a root on a technicality.
36
+ *
37
+ * @param seed - the exact events the child inherits.
38
+ * @returns whether the child records `parentSession`.
39
+ */
40
+ export function childRecordsLineage(seed) {
41
+ return seed.some(isHumanMessage);
42
+ }
43
+ /** One message the person at the keyboard sent, by `source.kind` alone. */
44
+ function isHumanMessage(event) {
45
+ if (event.type !== 'user/message')
46
+ return false;
47
+ // Durable data: the source is a merge-extensible sum type whose members are
48
+ // declared by their producers, so narrow instead of trusting the union.
49
+ const source = event.data.source;
50
+ return source?.kind === 'user';
51
+ }
@@ -3,7 +3,7 @@ import { resetSessionProjection } from './session-reset.js';
3
3
  import type { createChannelBinding } from './binding.js';
4
4
  import type { ChannelState, ResumeResult } from './types.js';
5
5
  type Binding = ReturnType<typeof createChannelBinding>;
6
- type LiveAdoptionState = Pick<ChannelState, 'status' | 'agentId' | 'cwd' | 'displayCwd' | 'agentPreset' | 'provider' | 'model' | 'loadedContext' | 'contextWindow' | 'effortLevels' | 'reasoningEffort' | 'tps' | 'tpsSamples' | 'lastUsage' | 'workingActivity' | 'working' | 'emit'> & Parameters<typeof resetSessionProjection>[0];
6
+ type LiveAdoptionState = Pick<ChannelState, 'status' | 'agentId' | 'sessionId' | 'cwd' | 'displayCwd' | 'agentPreset' | 'provider' | 'model' | 'loadedContext' | 'contextWindow' | 'effortLevels' | 'reasoningEffort' | 'tps' | 'tpsSamples' | 'lastUsage' | 'working' | 'emit'> & Parameters<typeof resetSessionProjection>[0];
7
7
  /** Adopt an already-live agent, preserving a meaningful previous handle in the background ledger. */
8
8
  export declare function createLiveAgentAdoption(state: LiveAdoptionState, deps: {
9
9
  binding: Pick<Binding, 'switchTo'>;
@@ -13,6 +13,8 @@ export declare function createLiveAgentAdoption(state: LiveAdoptionState, deps:
13
13
  };
14
14
  resetProjector(): void;
15
15
  resetSubagents(): void;
16
+ restoreSubagents(agent: Agent): void;
17
+ parkSubagents(agent: Agent): void;
16
18
  resetJobs(): void;
17
19
  replay(events: readonly import('@deepseek-ai/dsh-session').SessionEvent[]): void;
18
20
  settleReplay(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"session-live-adoption.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/channel/session-live-adoption.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAMhE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE5D,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACtD,KAAK,iBAAiB,GAAG,IAAI,CAC3B,YAAY,EACV,QAAQ,GACR,SAAS,GACT,KAAK,GACL,YAAY,GACZ,aAAa,GACb,UAAU,GACV,OAAO,GACP,eAAe,GACf,eAAe,GACf,cAAc,GACd,iBAAiB,GACjB,KAAK,GACL,YAAY,GACZ,WAAW,GACX,iBAAiB,GACjB,SAAS,GACT,MAAM,CACT,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAA;AAEhD,qGAAqG;AACrG,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,IAAI,EAAE;IACJ,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;IAClC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IAC3C,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IACzB,cAAc,IAAI,IAAI,CAAA;IACtB,cAAc,IAAI,IAAI,CAAA;IACtB,SAAS,IAAI,IAAI,CAAA;IACjB,MAAM,CAAC,MAAM,EAAE,SAAS,OAAO,0BAA0B,EAAE,YAAY,EAAE,GAAG,IAAI,CAAA;IAChF,YAAY,IAAI,IAAI,CAAA;IACpB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACxD,gBAAgB,IAAI,IAAI,CAAA;IACxB,SAAS,IAAI,IAAI,CAAA;IACjB,eAAe,IAAI,IAAI,CAAA;IACvB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,iBAAiB,IAAI,IAAI,CAAA;IACzB;6CACyC;IACzC,iBAAiB,IAAI,IAAI,CAAA;IACzB,qBAAqB,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7F,eAAe,IAAI,IAAI,CAAA;CACxB,IAEa,QAAQ,KAAK,KAAG,OAAO,CAAC,YAAY,CAAC,CAyDpD"}
1
+ {"version":3,"file":"session-live-adoption.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/channel/session-live-adoption.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAMhE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE5D,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACtD,KAAK,iBAAiB,GAAG,IAAI,CAC3B,YAAY,EACV,QAAQ,GACR,SAAS,GACT,WAAW,GACX,KAAK,GACL,YAAY,GACZ,aAAa,GACb,UAAU,GACV,OAAO,GACP,eAAe,GACf,eAAe,GACf,cAAc,GACd,iBAAiB,GACjB,KAAK,GACL,YAAY,GACZ,WAAW,GACX,SAAS,GACT,MAAM,CACT,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAA;AAEhD,qGAAqG;AACrG,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,IAAI,EAAE;IACJ,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;IAClC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IAC3C,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IACzB,cAAc,IAAI,IAAI,CAAA;IACtB,cAAc,IAAI,IAAI,CAAA;IACtB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IACpC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IACjC,SAAS,IAAI,IAAI,CAAA;IACjB,MAAM,CAAC,MAAM,EAAE,SAAS,OAAO,0BAA0B,EAAE,YAAY,EAAE,GAAG,IAAI,CAAA;IAChF,YAAY,IAAI,IAAI,CAAA;IACpB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACxD,gBAAgB,IAAI,IAAI,CAAA;IACxB,SAAS,IAAI,IAAI,CAAA;IACjB,eAAe,IAAI,IAAI,CAAA;IACvB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,iBAAiB,IAAI,IAAI,CAAA;IACzB;6CACyC;IACzC,iBAAiB,IAAI,IAAI,CAAA;IACzB,qBAAqB,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7F,eAAe,IAAI,IAAI,CAAA;CACxB,IAEa,QAAQ,KAAK,KAAG,OAAO,CAAC,YAAY,CAAC,CA+DpD"}
@@ -9,10 +9,20 @@ export function createLiveAgentAdoption(state, deps) {
9
9
  return async (target) => deps.binding.switchTo(target, deps.backgroundHandles.get(String(target.id)), (committed, disposePrevious) => {
10
10
  const previousHandle = committed.handle;
11
11
  const previousSessionId = String(committed.agent.session.id);
12
+ const keepPrevious = previousHandle !== undefined
13
+ && previousHandle.agent !== target
14
+ && (previousHandle.agent.status === 'running' || agentViewHasTurns(snapshotLiveSessionEvents(previousHandle.agent.session)));
15
+ // Registry attachment borrows an Agent without taking its upstream
16
+ // handle. Leaving that view must retain its projection independently
17
+ // of whether this channel can transfer or dispose the handle.
18
+ if (committed.agent !== target && (previousHandle === undefined || keepPrevious))
19
+ deps.parkSubagents(committed.agent);
12
20
  deps.backgroundHandles.delete(String(target.id));
13
21
  resetSessionProjection(state, deps.rowIds, deps.resetProjector, deps.resetSubagents, deps.resetJobs);
22
+ deps.restoreSubagents(target);
14
23
  state.status = target.status;
15
24
  state.agentId = target.id;
25
+ state.sessionId = target.session.id;
16
26
  state.cwd = target.session.header.cwd ?? state.cwd;
17
27
  state.displayCwd = deps.describeWorkspace(state.cwd).description ?? state.cwd;
18
28
  deps.resetIdeSelection();
@@ -42,9 +52,6 @@ export function createLiveAgentAdoption(state, deps) {
42
52
  writeResumeTarget(String(target.id));
43
53
  touchSession(target.id);
44
54
  state.emit();
45
- const keepPrevious = previousHandle !== undefined
46
- && previousHandle.agent !== target
47
- && (previousHandle.agent.status === 'running' || agentViewHasTurns(snapshotLiveSessionEvents(previousHandle.agent.session)));
48
55
  if (previousHandle !== undefined && previousHandle.agent !== target) {
49
56
  if (keepPrevious) {
50
57
  deps.backgroundHandles.set(previousSessionId, previousHandle);
@@ -54,7 +54,8 @@ export declare function createSessionMetadataActions(ctx: Context, deps: {
54
54
  cwd: string;
55
55
  };
56
56
  }): {
57
- listSessions: () => Promise<readonly SessionSummary[]>;
57
+ cachedSessions: () => readonly SessionSummary[] | undefined;
58
+ listSessions: (onEnriched?: (summary: SessionSummary) => void, onPartial?: (rows: readonly SessionSummary[]) => void) => Promise<readonly SessionSummary[]>;
58
59
  previewSession: (sessionId: string) => Promise<import("../sessions/types.js").PreviewEntry[]>;
59
60
  listSkills: () => Promise<{
60
61
  name: string;