@drscrewdriver/dsh-better-display 0.3.3-fork.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (390) hide show
  1. package/CHANGELOG.md +259 -0
  2. package/DESIGN.md +72 -0
  3. package/LICENSE +24 -0
  4. package/README.en.md +55 -0
  5. package/README.md +55 -0
  6. package/THIRD_PARTY_NOTICES.md +65 -0
  7. package/compat/harness-rc2.json +99 -0
  8. package/cordis.patch.yml +5 -0
  9. package/cordis.yml +4 -0
  10. package/docs/official-rendering-bridge.md +65 -0
  11. package/dshx.yml +5 -0
  12. package/lib/client.js +49292 -0
  13. package/lib/client.js.map +1 -0
  14. package/lib/dsh-better-display.js +101 -0
  15. package/lib/types/client/Blocks.d.ts +49 -0
  16. package/lib/types/client/Blocks.d.ts.map +1 -0
  17. package/lib/types/client/Blocks.js +143 -0
  18. package/lib/types/client/Blocks.js.map +1 -0
  19. package/lib/types/client/ChoreographedFlow.d.ts +22 -0
  20. package/lib/types/client/ChoreographedFlow.d.ts.map +1 -0
  21. package/lib/types/client/ChoreographedFlow.js +218 -0
  22. package/lib/types/client/ChoreographedFlow.js.map +1 -0
  23. package/lib/types/client/ClosedProcessSummary.d.ts +9 -0
  24. package/lib/types/client/ClosedProcessSummary.d.ts.map +1 -0
  25. package/lib/types/client/ClosedProcessSummary.js +16 -0
  26. package/lib/types/client/ClosedProcessSummary.js.map +1 -0
  27. package/lib/types/client/DiffPanel.d.ts +13 -0
  28. package/lib/types/client/DiffPanel.d.ts.map +1 -0
  29. package/lib/types/client/DiffPanel.js +115 -0
  30. package/lib/types/client/DiffPanel.js.map +1 -0
  31. package/lib/types/client/LiveFold.d.ts +10 -0
  32. package/lib/types/client/LiveFold.d.ts.map +1 -0
  33. package/lib/types/client/LiveFold.js +39 -0
  34. package/lib/types/client/LiveFold.js.map +1 -0
  35. package/lib/types/client/McpAppFrame.d.ts +32 -0
  36. package/lib/types/client/McpAppFrame.d.ts.map +1 -0
  37. package/lib/types/client/McpAppFrame.js +193 -0
  38. package/lib/types/client/McpAppFrame.js.map +1 -0
  39. package/lib/types/client/OfficialContent.d.ts +25 -0
  40. package/lib/types/client/OfficialContent.d.ts.map +1 -0
  41. package/lib/types/client/OfficialContent.js +53 -0
  42. package/lib/types/client/OfficialContent.js.map +1 -0
  43. package/lib/types/client/Reader.d.ts +3 -0
  44. package/lib/types/client/Reader.d.ts.map +1 -0
  45. package/lib/types/client/Reader.js +603 -0
  46. package/lib/types/client/Reader.js.map +1 -0
  47. package/lib/types/client/ReasoningCard.d.ts +11 -0
  48. package/lib/types/client/ReasoningCard.d.ts.map +1 -0
  49. package/lib/types/client/ReasoningCard.js +322 -0
  50. package/lib/types/client/ReasoningCard.js.map +1 -0
  51. package/lib/types/client/SettingsSection.d.ts +37 -0
  52. package/lib/types/client/SettingsSection.d.ts.map +1 -0
  53. package/lib/types/client/SettingsSection.js +63 -0
  54. package/lib/types/client/SettingsSection.js.map +1 -0
  55. package/lib/types/client/StickyLane.d.ts +8 -0
  56. package/lib/types/client/StickyLane.d.ts.map +1 -0
  57. package/lib/types/client/StickyLane.js +39 -0
  58. package/lib/types/client/StickyLane.js.map +1 -0
  59. package/lib/types/client/TimelineRail.d.ts +10 -0
  60. package/lib/types/client/TimelineRail.d.ts.map +1 -0
  61. package/lib/types/client/TimelineRail.js +168 -0
  62. package/lib/types/client/TimelineRail.js.map +1 -0
  63. package/lib/types/client/ToolActivity.d.ts +17 -0
  64. package/lib/types/client/ToolActivity.d.ts.map +1 -0
  65. package/lib/types/client/ToolActivity.js +244 -0
  66. package/lib/types/client/ToolActivity.js.map +1 -0
  67. package/lib/types/client/TurnMetrics.d.ts +11 -0
  68. package/lib/types/client/TurnMetrics.d.ts.map +1 -0
  69. package/lib/types/client/TurnMetrics.js +44 -0
  70. package/lib/types/client/TurnMetrics.js.map +1 -0
  71. package/lib/types/client/WaitClock.d.ts +16 -0
  72. package/lib/types/client/WaitClock.d.ts.map +1 -0
  73. package/lib/types/client/WaitClock.js +29 -0
  74. package/lib/types/client/WaitClock.js.map +1 -0
  75. package/lib/types/client/WaitingClock.d.ts +15 -0
  76. package/lib/types/client/WaitingClock.d.ts.map +1 -0
  77. package/lib/types/client/WaitingClock.js +30 -0
  78. package/lib/types/client/WaitingClock.js.map +1 -0
  79. package/lib/types/client/WaitingStatus.d.ts +6 -0
  80. package/lib/types/client/WaitingStatus.d.ts.map +1 -0
  81. package/lib/types/client/WaitingStatus.js +9 -0
  82. package/lib/types/client/WaitingStatus.js.map +1 -0
  83. package/lib/types/client/conversation-scroll.d.ts +19 -0
  84. package/lib/types/client/conversation-scroll.d.ts.map +1 -0
  85. package/lib/types/client/conversation-scroll.js +25 -0
  86. package/lib/types/client/conversation-scroll.js.map +1 -0
  87. package/lib/types/client/deliverables.d.ts +24 -0
  88. package/lib/types/client/deliverables.d.ts.map +1 -0
  89. package/lib/types/client/deliverables.js +104 -0
  90. package/lib/types/client/deliverables.js.map +1 -0
  91. package/lib/types/client/entry-policy.d.ts +10 -0
  92. package/lib/types/client/entry-policy.d.ts.map +1 -0
  93. package/lib/types/client/entry-policy.js +24 -0
  94. package/lib/types/client/entry-policy.js.map +1 -0
  95. package/lib/types/client/entry.d.ts +4 -0
  96. package/lib/types/client/entry.d.ts.map +1 -0
  97. package/lib/types/client/entry.js +34 -0
  98. package/lib/types/client/entry.js.map +1 -0
  99. package/lib/types/client/fold-choreography.d.ts +40 -0
  100. package/lib/types/client/fold-choreography.d.ts.map +1 -0
  101. package/lib/types/client/fold-choreography.js +48 -0
  102. package/lib/types/client/fold-choreography.js.map +1 -0
  103. package/lib/types/client/fold-intensity.d.ts +11 -0
  104. package/lib/types/client/fold-intensity.d.ts.map +1 -0
  105. package/lib/types/client/fold-intensity.js +32 -0
  106. package/lib/types/client/fold-intensity.js.map +1 -0
  107. package/lib/types/client/index.d.ts +7 -0
  108. package/lib/types/client/index.d.ts.map +1 -0
  109. package/lib/types/client/index.js +195 -0
  110. package/lib/types/client/index.js.map +1 -0
  111. package/lib/types/client/live-turn.d.ts +58 -0
  112. package/lib/types/client/live-turn.d.ts.map +1 -0
  113. package/lib/types/client/live-turn.js +190 -0
  114. package/lib/types/client/live-turn.js.map +1 -0
  115. package/lib/types/client/markdown/MarkdownText.d.ts +41 -0
  116. package/lib/types/client/markdown/MarkdownText.d.ts.map +1 -0
  117. package/lib/types/client/markdown/MarkdownText.js +178 -0
  118. package/lib/types/client/markdown/MarkdownText.js.map +1 -0
  119. package/lib/types/client/markdown/cjkFriendlyStrong.d.ts +9 -0
  120. package/lib/types/client/markdown/cjkFriendlyStrong.d.ts.map +1 -0
  121. package/lib/types/client/markdown/cjkFriendlyStrong.js +73 -0
  122. package/lib/types/client/markdown/cjkFriendlyStrong.js.map +1 -0
  123. package/lib/types/client/markdown/incremental.d.ts +69 -0
  124. package/lib/types/client/markdown/incremental.d.ts.map +1 -0
  125. package/lib/types/client/markdown/incremental.js +108 -0
  126. package/lib/types/client/markdown/incremental.js.map +1 -0
  127. package/lib/types/client/markdown/katex.d.ts +27 -0
  128. package/lib/types/client/markdown/katex.d.ts.map +1 -0
  129. package/lib/types/client/markdown/katex.js +88 -0
  130. package/lib/types/client/markdown/katex.js.map +1 -0
  131. package/lib/types/client/markdown/mathCompatibility.d.ts +11 -0
  132. package/lib/types/client/markdown/mathCompatibility.d.ts.map +1 -0
  133. package/lib/types/client/markdown/mathCompatibility.js +293 -0
  134. package/lib/types/client/markdown/mathCompatibility.js.map +1 -0
  135. package/lib/types/client/markdown/parse.d.ts +25 -0
  136. package/lib/types/client/markdown/parse.d.ts.map +1 -0
  137. package/lib/types/client/markdown/parse.js +42 -0
  138. package/lib/types/client/markdown/parse.js.map +1 -0
  139. package/lib/types/client/markdown/render.d.ts +121 -0
  140. package/lib/types/client/markdown/render.d.ts.map +1 -0
  141. package/lib/types/client/markdown/render.js +452 -0
  142. package/lib/types/client/markdown/render.js.map +1 -0
  143. package/lib/types/client/mcp-app.d.ts +50 -0
  144. package/lib/types/client/mcp-app.d.ts.map +1 -0
  145. package/lib/types/client/mcp-app.js +328 -0
  146. package/lib/types/client/mcp-app.js.map +1 -0
  147. package/lib/types/client/message-chrome.d.ts +19 -0
  148. package/lib/types/client/message-chrome.d.ts.map +1 -0
  149. package/lib/types/client/message-chrome.js +42 -0
  150. package/lib/types/client/message-chrome.js.map +1 -0
  151. package/lib/types/client/motion.d.ts +38 -0
  152. package/lib/types/client/motion.d.ts.map +1 -0
  153. package/lib/types/client/motion.js +453 -0
  154. package/lib/types/client/motion.js.map +1 -0
  155. package/lib/types/client/native/ContextBody.d.ts +130 -0
  156. package/lib/types/client/native/ContextBody.d.ts.map +1 -0
  157. package/lib/types/client/native/ContextBody.js +398 -0
  158. package/lib/types/client/native/ContextBody.js.map +1 -0
  159. package/lib/types/client/native/ContextInjectionRow.d.ts +35 -0
  160. package/lib/types/client/native/ContextInjectionRow.d.ts.map +1 -0
  161. package/lib/types/client/native/ContextInjectionRow.js +42 -0
  162. package/lib/types/client/native/ContextInjectionRow.js.map +1 -0
  163. package/lib/types/client/native/ReferenceIcon.d.ts +16 -0
  164. package/lib/types/client/native/ReferenceIcon.d.ts.map +1 -0
  165. package/lib/types/client/native/ReferenceIcon.js +16 -0
  166. package/lib/types/client/native/ReferenceIcon.js.map +1 -0
  167. package/lib/types/client/native/tool-call-model.d.ts +58 -0
  168. package/lib/types/client/native/tool-call-model.d.ts.map +1 -0
  169. package/lib/types/client/native/tool-call-model.js +219 -0
  170. package/lib/types/client/native/tool-call-model.js.map +1 -0
  171. package/lib/types/client/native/tool-update.d.ts +23 -0
  172. package/lib/types/client/native/tool-update.d.ts.map +1 -0
  173. package/lib/types/client/native/tool-update.js +22 -0
  174. package/lib/types/client/native/tool-update.js.map +1 -0
  175. package/lib/types/client/official-slots.d.ts +71 -0
  176. package/lib/types/client/official-slots.d.ts.map +1 -0
  177. package/lib/types/client/official-slots.js +183 -0
  178. package/lib/types/client/official-slots.js.map +1 -0
  179. package/lib/types/client/open-file.d.ts +29 -0
  180. package/lib/types/client/open-file.d.ts.map +1 -0
  181. package/lib/types/client/open-file.js +71 -0
  182. package/lib/types/client/open-file.js.map +1 -0
  183. package/lib/types/client/pending-submission.d.ts +28 -0
  184. package/lib/types/client/pending-submission.d.ts.map +1 -0
  185. package/lib/types/client/pending-submission.js +28 -0
  186. package/lib/types/client/pending-submission.js.map +1 -0
  187. package/lib/types/client/platform-media.d.ts +6 -0
  188. package/lib/types/client/platform-media.d.ts.map +1 -0
  189. package/lib/types/client/platform-media.js +18 -0
  190. package/lib/types/client/platform-media.js.map +1 -0
  191. package/lib/types/client/primitive-labels.d.ts +10 -0
  192. package/lib/types/client/primitive-labels.d.ts.map +1 -0
  193. package/lib/types/client/primitive-labels.js +38 -0
  194. package/lib/types/client/primitive-labels.js.map +1 -0
  195. package/lib/types/client/projection.d.ts +41 -0
  196. package/lib/types/client/projection.d.ts.map +1 -0
  197. package/lib/types/client/projection.js +112 -0
  198. package/lib/types/client/projection.js.map +1 -0
  199. package/lib/types/client/reasoning-follow.d.ts +10 -0
  200. package/lib/types/client/reasoning-follow.d.ts.map +1 -0
  201. package/lib/types/client/reasoning-follow.js +21 -0
  202. package/lib/types/client/reasoning-follow.js.map +1 -0
  203. package/lib/types/client/resource-address.d.ts +3 -0
  204. package/lib/types/client/resource-address.d.ts.map +1 -0
  205. package/lib/types/client/resource-address.js +33 -0
  206. package/lib/types/client/resource-address.js.map +1 -0
  207. package/lib/types/client/settings-copy.d.ts +7 -0
  208. package/lib/types/client/settings-copy.d.ts.map +1 -0
  209. package/lib/types/client/settings-copy.js +53 -0
  210. package/lib/types/client/settings-copy.js.map +1 -0
  211. package/lib/types/client/settings-slots.d.ts +23 -0
  212. package/lib/types/client/settings-slots.d.ts.map +1 -0
  213. package/lib/types/client/settings-slots.js +2 -0
  214. package/lib/types/client/settings-slots.js.map +1 -0
  215. package/lib/types/client/settings.d.ts +4 -0
  216. package/lib/types/client/settings.d.ts.map +1 -0
  217. package/lib/types/client/settings.js +60 -0
  218. package/lib/types/client/settings.js.map +1 -0
  219. package/lib/types/client/skill-status.d.ts +25 -0
  220. package/lib/types/client/skill-status.d.ts.map +1 -0
  221. package/lib/types/client/skill-status.js +44 -0
  222. package/lib/types/client/skill-status.js.map +1 -0
  223. package/lib/types/client/store.d.ts +35 -0
  224. package/lib/types/client/store.d.ts.map +1 -0
  225. package/lib/types/client/store.js +37 -0
  226. package/lib/types/client/store.js.map +1 -0
  227. package/lib/types/client/stream-buffer.d.ts +37 -0
  228. package/lib/types/client/stream-buffer.d.ts.map +1 -0
  229. package/lib/types/client/stream-buffer.js +150 -0
  230. package/lib/types/client/stream-buffer.js.map +1 -0
  231. package/lib/types/client/streaming.d.ts +18 -0
  232. package/lib/types/client/streaming.d.ts.map +1 -0
  233. package/lib/types/client/streaming.js +84 -0
  234. package/lib/types/client/streaming.js.map +1 -0
  235. package/lib/types/client/timeline.d.ts +26 -0
  236. package/lib/types/client/timeline.d.ts.map +1 -0
  237. package/lib/types/client/timeline.js +48 -0
  238. package/lib/types/client/timeline.js.map +1 -0
  239. package/lib/types/client/tool-activity.d.ts +98 -0
  240. package/lib/types/client/tool-activity.d.ts.map +1 -0
  241. package/lib/types/client/tool-activity.js +301 -0
  242. package/lib/types/client/tool-activity.js.map +1 -0
  243. package/lib/types/client/types.d.ts +91 -0
  244. package/lib/types/client/types.d.ts.map +1 -0
  245. package/lib/types/client/types.js +2 -0
  246. package/lib/types/client/types.js.map +1 -0
  247. package/lib/types/client/waiting-clock.d.ts +49 -0
  248. package/lib/types/client/waiting-clock.d.ts.map +1 -0
  249. package/lib/types/client/waiting-clock.js +80 -0
  250. package/lib/types/client/waiting-clock.js.map +1 -0
  251. package/lib/types/client/word-motion.d.ts +16 -0
  252. package/lib/types/client/word-motion.d.ts.map +1 -0
  253. package/lib/types/client/word-motion.js +90 -0
  254. package/lib/types/client/word-motion.js.map +1 -0
  255. package/lib/types/client/word-timeline.d.ts +32 -0
  256. package/lib/types/client/word-timeline.d.ts.map +1 -0
  257. package/lib/types/client/word-timeline.js +119 -0
  258. package/lib/types/client/word-timeline.js.map +1 -0
  259. package/lib/types/dsh-better-display.d.ts +17 -0
  260. package/lib/types/dsh-better-display.d.ts.map +1 -0
  261. package/lib/types/dsh-better-display.js +93 -0
  262. package/lib/types/dsh-better-display.js.map +1 -0
  263. package/lib/types/skill-roots.d.ts +22 -0
  264. package/lib/types/skill-roots.d.ts.map +1 -0
  265. package/lib/types/skill-roots.js +126 -0
  266. package/lib/types/skill-roots.js.map +1 -0
  267. package/lib/types/skill-status.d.ts +36 -0
  268. package/lib/types/skill-status.d.ts.map +1 -0
  269. package/lib/types/skill-status.js +51 -0
  270. package/lib/types/skill-status.js.map +1 -0
  271. package/package.json +133 -0
  272. package/scripts/build-motion-fixture.mjs +26 -0
  273. package/scripts/check-harness-compat.mjs +71 -0
  274. package/scripts/link-harness-dependencies.mjs +54 -0
  275. package/scripts/verify-auto-fold.mjs +114 -0
  276. package/scripts/verify-official-bridge.mjs +121 -0
  277. package/scripts/verify-tool-shimmer.mjs +62 -0
  278. package/skills/generative-mcpapps/SKILL.md +47 -0
  279. package/skills/generative-mcpapps/examples/interactive_quiz.html +153 -0
  280. package/skills/generative-mcpapps/references/html_boilerplate.md +122 -0
  281. package/skills/generative-mcpapps/references/sep1865_protocol.md +54 -0
  282. package/src/client/Blocks.tsx +213 -0
  283. package/src/client/ChoreographedFlow.tsx +232 -0
  284. package/src/client/ClosedProcessSummary.tsx +23 -0
  285. package/src/client/DiffPanel.tsx +124 -0
  286. package/src/client/LiveFold.tsx +43 -0
  287. package/src/client/McpAppFrame.module.css +210 -0
  288. package/src/client/McpAppFrame.tsx +317 -0
  289. package/src/client/OfficialContent.tsx +69 -0
  290. package/src/client/Reader.module.css +692 -0
  291. package/src/client/Reader.tsx +878 -0
  292. package/src/client/ReasoningCard.tsx +306 -0
  293. package/src/client/SettingsSection.module.css +184 -0
  294. package/src/client/SettingsSection.tsx +194 -0
  295. package/src/client/StickyLane.tsx +34 -0
  296. package/src/client/TimelineRail.module.css +170 -0
  297. package/src/client/TimelineRail.tsx +262 -0
  298. package/src/client/ToolActivity.tsx +274 -0
  299. package/src/client/TurnMetrics.module.css +139 -0
  300. package/src/client/TurnMetrics.tsx +160 -0
  301. package/src/client/WaitClock.tsx +33 -0
  302. package/src/client/WaitingStatus.tsx +13 -0
  303. package/src/client/conversation-scroll.ts +28 -0
  304. package/src/client/deliverables.ts +122 -0
  305. package/src/client/entry-policy.ts +20 -0
  306. package/src/client/entry.tsx +40 -0
  307. package/src/client/fold-choreography.ts +55 -0
  308. package/src/client/fold-intensity.ts +36 -0
  309. package/src/client/index.tsx +222 -0
  310. package/src/client/live-turn.ts +198 -0
  311. package/src/client/markdown/MarkdownText.module.css +304 -0
  312. package/src/client/markdown/MarkdownText.tsx +195 -0
  313. package/src/client/markdown/cjkFriendlyStrong.ts +84 -0
  314. package/src/client/markdown/incremental.ts +131 -0
  315. package/src/client/markdown/katex.tsx +91 -0
  316. package/src/client/markdown/mathCompatibility.ts +350 -0
  317. package/src/client/markdown/parse.ts +45 -0
  318. package/src/client/markdown/render.tsx +647 -0
  319. package/src/client/markdown/upstream.json +14 -0
  320. package/src/client/mcp-app.ts +323 -0
  321. package/src/client/message-chrome.ts +47 -0
  322. package/src/client/motion.tsx +410 -0
  323. package/src/client/native/ContextBody.module.css +161 -0
  324. package/src/client/native/ContextBody.tsx +591 -0
  325. package/src/client/native/ContextInjectionRow.module.css +66 -0
  326. package/src/client/native/ContextInjectionRow.tsx +106 -0
  327. package/src/client/native/ReferenceIcon.tsx +35 -0
  328. package/src/client/native/tool-call-model.ts +248 -0
  329. package/src/client/native/tool-update.ts +32 -0
  330. package/src/client/native/upstream.json +41 -0
  331. package/src/client/official-slots.tsx +211 -0
  332. package/src/client/open-file.ts +94 -0
  333. package/src/client/pending-submission.ts +49 -0
  334. package/src/client/platform-media.ts +17 -0
  335. package/src/client/primitive-labels.ts +54 -0
  336. package/src/client/projection.ts +118 -0
  337. package/src/client/reasoning-follow.ts +28 -0
  338. package/src/client/settings-copy.ts +80 -0
  339. package/src/client/settings-slots.ts +20 -0
  340. package/src/client/settings.tsx +73 -0
  341. package/src/client/skill-status.ts +78 -0
  342. package/src/client/store.ts +75 -0
  343. package/src/client/stream-buffer.ts +136 -0
  344. package/src/client/streaming.tsx +70 -0
  345. package/src/client/style.d.ts +4 -0
  346. package/src/client/timeline.ts +77 -0
  347. package/src/client/tool-activity.ts +298 -0
  348. package/src/client/types.ts +89 -0
  349. package/src/client/waiting-clock.ts +83 -0
  350. package/src/client/word-motion.tsx +92 -0
  351. package/src/client/word-timeline.ts +113 -0
  352. package/src/dsh-better-display.ts +108 -0
  353. package/src/skill-roots.ts +138 -0
  354. package/src/skill-status.ts +81 -0
  355. package/tests/browser-auto-fold.tsx +64 -0
  356. package/tests/browser-closed-gap.tsx +20 -0
  357. package/tests/browser-motion.tsx +65 -0
  358. package/tests/browser-official-bridge.tsx +152 -0
  359. package/tests/browser-sticky-lanes.tsx +22 -0
  360. package/tests/browser-waiting-clock.tsx +14 -0
  361. package/tests/chat-flow-hook.test.ts +66 -0
  362. package/tests/cloud-gate.test.ts +34 -0
  363. package/tests/context-tool-update.test.ts +33 -0
  364. package/tests/conversation-scroll.test.ts +47 -0
  365. package/tests/deliverables.test.ts +128 -0
  366. package/tests/entry.test.ts +42 -0
  367. package/tests/fixtures/maid-composer-hide.html +31 -0
  368. package/tests/fold-choreography.test.ts +54 -0
  369. package/tests/fold-intensity.test.ts +94 -0
  370. package/tests/footer-precedence.test.ts +129 -0
  371. package/tests/history-word-regression.test.ts +16 -0
  372. package/tests/live-turn.test.ts +218 -0
  373. package/tests/mcp-apps.test.ts +157 -0
  374. package/tests/message-chrome.test.ts +29 -0
  375. package/tests/official-slots.test.ts +112 -0
  376. package/tests/open-file.test.ts +114 -0
  377. package/tests/pending-submission.test.ts +45 -0
  378. package/tests/platform-media.test.ts +23 -0
  379. package/tests/projection.test.ts +184 -0
  380. package/tests/reasoning-follow.test.ts +34 -0
  381. package/tests/settings-copy.test.ts +63 -0
  382. package/tests/skill-status.test.ts +137 -0
  383. package/tests/stock-install.test.ts +58 -0
  384. package/tests/stream-buffer.test.ts +102 -0
  385. package/tests/timeline.test.ts +59 -0
  386. package/tests/tool-diff.test.ts +57 -0
  387. package/tests/waiting-clock.test.ts +83 -0
  388. package/tests/word-timeline.test.ts +146 -0
  389. package/tsconfig.json +11 -0
  390. package/tsdown.config.ts +51 -0
@@ -0,0 +1,4 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import { type OpenPrefs } from './SettingsSection.js';
3
+ export declare function installBetterDisplaySettings(ctx: Context, prefs: OpenPrefs): void;
4
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/client/settings.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAGnD,OAAO,EAAuD,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAiD3G,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAoBjF"}
@@ -0,0 +1,60 @@
1
+ import { settingsCopyFor, zh, en } from './settings-copy.js';
2
+ import { SettingsSection } from './SettingsSection.js';
3
+ import { firstSessionId, skillsFromListResult } from './skill-status.js';
4
+ function languageTag(ctx) {
5
+ const locale = (ctx.get?.('locale') ?? ctx.locale);
6
+ const snap = locale?.getSnapshot?.();
7
+ return snap?.locale ?? snap?.language
8
+ ?? (typeof document !== 'undefined' ? document.documentElement.lang : undefined)
9
+ ?? (typeof navigator !== 'undefined' ? navigator.language : undefined);
10
+ }
11
+ function createSkillProbe(ctx) {
12
+ return {
13
+ fetchHostStatus: async () => {
14
+ const sessions = ctx.sessions;
15
+ const snap = sessions?.list?.getSnapshot?.();
16
+ const id = firstSessionId(snap);
17
+ const cwd = id && snap?.byId ? snap.byId[id]?.cwd : undefined;
18
+ const url = cwd
19
+ ? `/better-display/skill-status?cwd=${encodeURIComponent(cwd)}`
20
+ : '/better-display/skill-status';
21
+ const res = await fetch(url);
22
+ if (!res.ok)
23
+ return undefined;
24
+ return await res.json();
25
+ },
26
+ listRemoteSkills: async () => {
27
+ const remote = ctx.remote;
28
+ const skills = remote?.skills
29
+ ?? ctx.get?.('remote.skills')
30
+ ?? (ctx.get?.('remote')?.skills);
31
+ const sessions = ctx.sessions;
32
+ const sessionId = firstSessionId(sessions?.list?.getSnapshot?.());
33
+ if (!skills?.list || !sessionId)
34
+ return undefined;
35
+ return skillsFromListResult(await skills.list({ sessionId }));
36
+ },
37
+ };
38
+ }
39
+ export function installBetterDisplaySettings(ctx, prefs) {
40
+ const locale = (ctx.get?.('locale') ?? ctx.locale);
41
+ if (locale?.register) {
42
+ ctx.effect(() => locale.register('better-display', { zh, en }), 'dsh-better-display: settings copy');
43
+ }
44
+ const checkSkill = createSkillProbe(ctx);
45
+ const injected = () => ({
46
+ prefs,
47
+ copy: settingsCopyFor(languageTag(ctx)),
48
+ languageTag: languageTag(ctx),
49
+ checkSkill,
50
+ });
51
+ ctx.slots.inject('settings.section', () => ctx.slots.register({
52
+ name: 'settings.section',
53
+ id: 'better-display',
54
+ order: 40,
55
+ label: () => locale?.bind?.('better-display')?.('nav') || settingsCopyFor(languageTag(ctx)).nav,
56
+ locale: locale?.bind ? 'better-display' : undefined,
57
+ inject: injected,
58
+ }, SettingsSection));
59
+ }
60
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/client/settings.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { CONVENTIONAL_SKILL_ROOTS, GENERATIVE_MCPAPPS_SKILL, SKILL_PACK_RELATIVE, publicSkillRoots, skillListIncludes, skillsFromListResult, toPublicSkillStatus, type HostSkillStatus } from '../skill-status.js';
2
+ export { CONVENTIONAL_SKILL_ROOTS, GENERATIVE_MCPAPPS_SKILL, SKILL_PACK_RELATIVE, publicSkillRoots, skillListIncludes, skillsFromListResult, toPublicSkillStatus, };
3
+ export type { HostSkillStatus };
4
+ export interface SkillStatusSnapshot {
5
+ readonly name: typeof GENERATIVE_MCPAPPS_SKILL;
6
+ readonly installed: boolean;
7
+ readonly via: 'skills.list' | 'skill-root' | null;
8
+ readonly roots: HostSkillStatus['roots'];
9
+ readonly packPath?: string;
10
+ readonly hostReached: boolean;
11
+ }
12
+ export interface SkillStatusProbe {
13
+ listRemoteSkills?: () => Promise<readonly {
14
+ readonly name?: string;
15
+ }[] | undefined>;
16
+ fetchHostStatus?: () => Promise<HostSkillStatus | undefined>;
17
+ }
18
+ export declare function detectGenerativeMcpappsSkill(probe: SkillStatusProbe): Promise<SkillStatusSnapshot>;
19
+ /** mkdir/cp using conventional relative roots only. Host paths are ignored. */
20
+ export declare function shortestInstallCommand(_status?: Pick<SkillStatusSnapshot, 'packPath' | 'roots'>): string;
21
+ export declare function firstSessionId(list: {
22
+ ids?: readonly string[];
23
+ byId?: Record<string, unknown>;
24
+ } | undefined): string | undefined;
25
+ //# sourceMappingURL=skill-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-status.d.ts","sourceRoot":"","sources":["../../../src/client/skill-status.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,GACpB,CAAC;AACF,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,OAAO,wBAAwB,CAAC;IAC/C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,GAAG,IAAI,CAAC;IAClD,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,SAAS;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,SAAS,CAAC,CAAC;IACpF,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC;CAC9D;AAED,wBAAsB,4BAA4B,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA6BxG;AAED,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,MAAM,CAGxG;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE;IAAE,GAAG,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAIhI"}
@@ -0,0 +1,44 @@
1
+ import { CONVENTIONAL_SKILL_ROOTS, GENERATIVE_MCPAPPS_SKILL, SKILL_PACK_RELATIVE, publicSkillRoots, skillListIncludes, skillsFromListResult, toPublicSkillStatus, } from '../skill-status.js';
2
+ export { CONVENTIONAL_SKILL_ROOTS, GENERATIVE_MCPAPPS_SKILL, SKILL_PACK_RELATIVE, publicSkillRoots, skillListIncludes, skillsFromListResult, toPublicSkillStatus, };
3
+ export async function detectGenerativeMcpappsSkill(probe) {
4
+ let host;
5
+ if (probe.fetchHostStatus) {
6
+ try {
7
+ host = await probe.fetchHostStatus();
8
+ }
9
+ catch {
10
+ host = undefined;
11
+ }
12
+ }
13
+ let remoteHit = false;
14
+ if (probe.listRemoteSkills) {
15
+ try {
16
+ remoteHit = skillListIncludes(await probe.listRemoteSkills());
17
+ }
18
+ catch {
19
+ remoteHit = false;
20
+ }
21
+ }
22
+ const installed = Boolean(host?.installed || remoteHit);
23
+ const via = remoteHit ? 'skills.list' : (host?.via ?? null);
24
+ const publicHost = host === undefined ? undefined : toPublicSkillStatus(host);
25
+ return {
26
+ name: GENERATIVE_MCPAPPS_SKILL,
27
+ installed,
28
+ via,
29
+ roots: publicHost?.roots ?? publicSkillRoots(),
30
+ hostReached: host !== undefined,
31
+ };
32
+ }
33
+ /** mkdir/cp using conventional relative roots only. Host paths are ignored. */
34
+ export function shortestInstallCommand(_status) {
35
+ const dest = CONVENTIONAL_SKILL_ROOTS[0];
36
+ return `mkdir -p ${dest} && cp -R ${SKILL_PACK_RELATIVE} ${dest}/`;
37
+ }
38
+ export function firstSessionId(list) {
39
+ if (list?.ids && list.ids.length > 0)
40
+ return list.ids[0];
41
+ const keys = list?.byId ? Object.keys(list.byId) : [];
42
+ return keys[0];
43
+ }
44
+ //# sourceMappingURL=skill-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-status.js","sourceRoot":"","sources":["../../../src/client/skill-status.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,GAEpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,GACpB,CAAC;AAiBF,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,KAAuB;IACxE,IAAI,IAAiC,CAAC;IACtC,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,GAAG,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,SAAS,GAAG,iBAAiB,CAAC,MAAM,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,SAAS,IAAI,SAAS,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC9E,OAAO;QACL,IAAI,EAAE,wBAAwB;QAC9B,SAAS;QACT,GAAG;QACH,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,gBAAgB,EAAE;QAC9C,WAAW,EAAE,IAAI,KAAK,SAAS;KAChC,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,sBAAsB,CAAC,OAAyD;IAC9F,MAAM,IAAI,GAAG,wBAAwB,CAAC,CAAC,CAAC,CAAC;IACzC,OAAO,YAAY,IAAI,aAAa,mBAAmB,IAAI,IAAI,GAAG,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAA6E;IAC1G,IAAI,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACtD,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { EngineStoreHandle } from '@deepseek-ai/dsh-client-store';
2
+ import { type FoldIntensity } from './fold-intensity.js';
3
+ import type { DeliverableOpenMode } from './open-file.js';
4
+ export interface ReaderState {
5
+ expanded: Record<string, boolean>;
6
+ motion: boolean;
7
+ /** Derived from foldIntensity; kept so older persisted snapshots still read. */
8
+ autoFold: boolean;
9
+ /** Default stays the system app. `sidebar` is opt-in. */
10
+ deliverableOpenMode: DeliverableOpenMode;
11
+ /**
12
+ * 0 = no auto-fold, 1 = current-main fold-on-next-reasoning (default),
13
+ * 2 = process-summary mode from community PR #14.
14
+ */
15
+ foldIntensity: FoldIntensity;
16
+ /** Translucent frosted chrome. Default off so opaque main chrome stays. */
17
+ frostedGlass: boolean;
18
+ /** Rounded answer bubbles. Default on; off lays answers flat on the page. */
19
+ bubbles: boolean;
20
+ /** Derived from foldIntensity === 2; kept for older #14 snapshots. */
21
+ processOnly: boolean;
22
+ }
23
+ type ReaderActions = {
24
+ setExpanded: (draft: ReaderState, key: string, value: boolean) => void;
25
+ resetExpanded: (draft: ReaderState) => void;
26
+ setMotion: (draft: ReaderState, value: boolean) => void;
27
+ setAutoFold: (draft: ReaderState, value: boolean) => void;
28
+ setDeliverableOpenMode: (draft: ReaderState, value: DeliverableOpenMode) => void;
29
+ setFoldIntensity: (draft: ReaderState, value: FoldIntensity) => void;
30
+ setFrostedGlass: (draft: ReaderState, value: boolean) => void;
31
+ setBubbles: (draft: ReaderState, value: boolean) => void;
32
+ };
33
+ export declare function createReaderStore(): EngineStoreHandle<ReaderState, ReaderActions>;
34
+ export {};
35
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/client/store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,gFAAgF;IAChF,QAAQ,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,mBAAmB,EAAE,mBAAmB,CAAC;IACzC;;;OAGG;IACH,aAAa,EAAE,aAAa,CAAC;IAC7B,2EAA2E;IAC3E,YAAY,EAAE,OAAO,CAAC;IACtB,6EAA6E;IAC7E,OAAO,EAAE,OAAO,CAAC;IACjB,sEAAsE;IACtE,WAAW,EAAE,OAAO,CAAC;CACtB;AACD,KAAK,aAAa,GAAG;IACnB,WAAW,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACvE,aAAa,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAC5C,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD,WAAW,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1D,sBAAsB,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACjF,gBAAgB,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACrE,eAAe,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9D,UAAU,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1D,CAAC;AAQF,wBAAgB,iBAAiB,IAAI,iBAAiB,CAAC,WAAW,EAAE,aAAa,CAAC,CA4BjF"}
@@ -0,0 +1,37 @@
1
+ import { defineStore } from '@deepseek-ai/dsh-client-store';
2
+ import { FOLD_INTENSITY_DEFAULT, autoFoldFromIntensity, processOnlyFromIntensity, } from './fold-intensity.js';
3
+ function applyFoldIntensity(draft, value) {
4
+ draft.foldIntensity = value;
5
+ draft.autoFold = autoFoldFromIntensity(value);
6
+ draft.processOnly = processOnlyFromIntensity(value);
7
+ }
8
+ export function createReaderStore() {
9
+ return defineStore({
10
+ init: () => ({
11
+ expanded: {},
12
+ motion: true,
13
+ autoFold: true,
14
+ deliverableOpenMode: 'external',
15
+ foldIntensity: FOLD_INTENSITY_DEFAULT,
16
+ frostedGlass: false,
17
+ bubbles: true,
18
+ processOnly: false,
19
+ }),
20
+ persist: 'dsh.reader.v1',
21
+ actions: {
22
+ setExpanded: (draft, key, value) => { draft.expanded[key] = value; },
23
+ resetExpanded: draft => { draft.expanded = {}; },
24
+ setMotion: (draft, value) => { draft.motion = value; },
25
+ setAutoFold: (draft, value) => {
26
+ applyFoldIntensity(draft, value
27
+ ? (draft.foldIntensity === 2 ? 2 : 1)
28
+ : 0);
29
+ },
30
+ setDeliverableOpenMode: (draft, value) => { draft.deliverableOpenMode = value; },
31
+ setFoldIntensity: (draft, value) => { applyFoldIntensity(draft, value); },
32
+ setFrostedGlass: (draft, value) => { draft.frostedGlass = value; },
33
+ setBubbles: (draft, value) => { draft.bubbles = value; },
34
+ },
35
+ });
36
+ }
37
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/client/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE5D,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,GAEzB,MAAM,qBAAqB,CAAC;AAiC7B,SAAS,kBAAkB,CAAC,KAAkB,EAAE,KAAoB;IAClE,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;IAC5B,KAAK,CAAC,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAC9C,KAAK,CAAC,WAAW,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,WAAW,CAAC;QACjB,IAAI,EAAE,GAAgB,EAAE,CAAC,CAAC;YACxB,QAAQ,EAAE,EAAE;YACZ,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,IAAI;YACd,mBAAmB,EAAE,UAAU;YAC/B,aAAa,EAAE,sBAAsB;YACrC,YAAY,EAAE,KAAK;YACnB,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,KAAK;SACnB,CAAC;QACF,OAAO,EAAE,eAAe;QACxB,OAAO,EAAE;YACP,WAAW,EAAE,CAAC,KAAK,EAAE,GAAW,EAAE,KAAc,EAAE,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;YACrF,aAAa,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC;YAChD,SAAS,EAAE,CAAC,KAAK,EAAE,KAAc,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;YAC/D,WAAW,EAAE,CAAC,KAAK,EAAE,KAAc,EAAE,EAAE;gBACrC,kBAAkB,CAAC,KAAK,EAAE,KAAK;oBAC7B,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBACrC,CAAC,CAAC,CAAC,CAAC,CAAC;YACT,CAAC;YACD,sBAAsB,EAAE,CAAC,KAAK,EAAE,KAA0B,EAAE,EAAE,GAAG,KAAK,CAAC,mBAAmB,GAAG,KAAK,CAAC,CAAC,CAAC;YACrG,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAoB,EAAE,EAAE,GAAG,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;YACxF,eAAe,EAAE,CAAC,KAAK,EAAE,KAAc,EAAE,EAAE,GAAG,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC;YAC3E,UAAU,EAAE,CAAC,KAAK,EAAE,KAAc,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC;SAClE;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,37 @@
1
+ /** Presentation only. The original session string remains the source of truth. */
2
+ export declare const STREAM_TIMING: {
3
+ readonly catchUpMs: 520;
4
+ readonly maxQueuedMs: 600;
5
+ readonly finishMs: 96;
6
+ readonly revealMs: 350;
7
+ readonly minimumRate: 260;
8
+ /** Weight of the newest arrival sample in the smoothed source rate. */
9
+ readonly rateWeight: 0.35;
10
+ /** A longer gap is a pause between runs, not a slow model: keep the estimate. */
11
+ readonly rateGapMs: 250;
12
+ };
13
+ export declare class StreamBuffer {
14
+ target: string;
15
+ visible: string;
16
+ revision: number;
17
+ private boundaries;
18
+ private arrivals;
19
+ private lastAt;
20
+ private credit;
21
+ private finishAt;
22
+ private rateEwma;
23
+ private lastArrival;
24
+ constructor(initial?: string);
25
+ get pending(): boolean;
26
+ private segment;
27
+ /** Non-append updates, cancellations and hidden/reduced views never replay. */
28
+ update(text: string, now: number, options?: {
29
+ immediate?: boolean;
30
+ finished?: boolean;
31
+ }): void;
32
+ /** Smoothed source rate, so one jittery transport chunk cannot set the pace. */
33
+ private observe;
34
+ flush(): void;
35
+ advance(now: number): boolean;
36
+ }
37
+ //# sourceMappingURL=stream-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-buffer.d.ts","sourceRoot":"","sources":["../../../src/client/stream-buffer.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAOlF,eAAO,MAAM,aAAa;;;;;;IAMxB,uEAAuE;;IAEvE,iFAAiF;;CAEzE,CAAC;AAcX,qBAAa,YAAY;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,SAAK;IACb,OAAO,CAAC,UAAU,CAAO;IACzB,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,WAAW,CAAuB;gBAE9B,OAAO,SAAK;IAMxB,IAAI,OAAO,IAAI,OAAO,CAAqD;IAE3E,OAAO,CAAC,OAAO;IAOf,+EAA+E;IAC/E,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,IAAI;IA0BlG,gFAAgF;IAChF,OAAO,CAAC,OAAO;IAYf,KAAK,IAAI,IAAI;IASb,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;CA4B9B"}
@@ -0,0 +1,150 @@
1
+ /** Presentation only. The original session string remains the source of truth. */
2
+ // The reveal runs at the rate the source is actually producing (feed-forward)
3
+ // plus a proportional term that closes whatever backlog jitter left behind.
4
+ // A proportional-only controller drains exactly one window per window, so the
5
+ // display trails live output by catchUpMs forever — unreadable-but-smooth at
6
+ // 75 chars/s, permanently behind at 1000. The feed-forward term is what makes
7
+ // the pace adapt to the model instead of to a fixed constant.
8
+ export const STREAM_TIMING = {
9
+ catchUpMs: 520,
10
+ maxQueuedMs: 600,
11
+ finishMs: 96,
12
+ revealMs: 350,
13
+ minimumRate: 260,
14
+ /** Weight of the newest arrival sample in the smoothed source rate. */
15
+ rateWeight: 0.35,
16
+ /** A longer gap is a pause between runs, not a slow model: keep the estimate. */
17
+ rateGapMs: 250,
18
+ };
19
+ const graphemes = new Intl.Segmenter(undefined, { granularity: 'grapheme' });
20
+ function atOrAfter(values, target) {
21
+ let low = 0;
22
+ let high = values.length - 1;
23
+ while (low < high) {
24
+ const middle = (low + high) >>> 1;
25
+ if (values[middle] < target)
26
+ low = middle + 1;
27
+ else
28
+ high = middle;
29
+ }
30
+ return low;
31
+ }
32
+ export class StreamBuffer {
33
+ target;
34
+ visible;
35
+ revision = 0;
36
+ boundaries = [0];
37
+ arrivals = [];
38
+ lastAt = null;
39
+ credit = 0;
40
+ finishAt = null;
41
+ rateEwma = 0;
42
+ lastArrival = null;
43
+ constructor(initial = '') {
44
+ this.target = initial;
45
+ this.visible = initial;
46
+ this.segment(0);
47
+ }
48
+ get pending() { return this.visible.length < this.target.length; }
49
+ segment(from) {
50
+ const index = atOrAfter(this.boundaries, from);
51
+ this.boundaries.length = index;
52
+ for (const part of graphemes.segment(this.target.slice(from)))
53
+ this.boundaries.push(from + part.index);
54
+ if (this.boundaries.at(-1) !== this.target.length)
55
+ this.boundaries.push(this.target.length);
56
+ }
57
+ /** Non-append updates, cancellations and hidden/reduced views never replay. */
58
+ update(text, now, options = {}) {
59
+ if (options.immediate || !text.startsWith(this.target)) {
60
+ if (text !== this.target)
61
+ this.revision++;
62
+ this.target = text;
63
+ this.flush();
64
+ this.boundaries = [0];
65
+ this.segment(0);
66
+ return;
67
+ }
68
+ if (text !== this.target) {
69
+ const wasPending = this.pending;
70
+ const grew = text.length - this.target.length;
71
+ const from = this.boundaries.at(-2) ?? 0;
72
+ this.observe(grew, now);
73
+ this.target = text;
74
+ // Re-segment the previous last cluster: an emoji/combining sequence can
75
+ // itself span transport chunks. Frozen source prefixes are not scanned.
76
+ this.segment(from);
77
+ this.arrivals.push({ end: text.length, at: now });
78
+ if (!wasPending) {
79
+ this.lastAt = now;
80
+ this.credit = 0;
81
+ }
82
+ }
83
+ if (options.finished && this.finishAt === null)
84
+ this.finishAt = now + STREAM_TIMING.finishMs;
85
+ if (!options.finished)
86
+ this.finishAt = null;
87
+ if (this.target.length - this.visible.length > 8192) {
88
+ this.revision++;
89
+ this.flush();
90
+ }
91
+ }
92
+ /** Smoothed source rate, so one jittery transport chunk cannot set the pace. */
93
+ observe(grew, now) {
94
+ const previous = this.lastArrival;
95
+ this.lastArrival = now;
96
+ if (previous === null || grew <= 0)
97
+ return;
98
+ const elapsed = now - previous;
99
+ if (elapsed <= 0 || elapsed > STREAM_TIMING.rateGapMs)
100
+ return;
101
+ const sample = grew * 1000 / elapsed;
102
+ this.rateEwma = this.rateEwma === 0
103
+ ? sample
104
+ : this.rateEwma * (1 - STREAM_TIMING.rateWeight) + sample * STREAM_TIMING.rateWeight;
105
+ }
106
+ flush() {
107
+ this.visible = this.target;
108
+ this.arrivals = [];
109
+ this.credit = 0;
110
+ this.lastAt = null;
111
+ this.lastArrival = null;
112
+ this.finishAt = null;
113
+ }
114
+ advance(now) {
115
+ if (!this.pending)
116
+ return false;
117
+ const before = this.visible.length;
118
+ const index = atOrAfter(this.boundaries, before);
119
+ const remaining = this.boundaries.length - index - 1;
120
+ const delta = Math.max(0, now - (this.lastAt ?? now));
121
+ this.lastAt = now;
122
+ const windowMs = this.finishAt === null ? STREAM_TIMING.catchUpMs : Math.max(16, Math.min(STREAM_TIMING.catchUpMs, this.finishAt - now));
123
+ // Feed-forward keeps pace with the source; the proportional term then drains
124
+ // whatever backlog is left, so lag decays instead of settling at one window.
125
+ const rate = Math.max(STREAM_TIMING.minimumRate, this.rateEwma + remaining * 1000 / windowMs);
126
+ this.credit += rate * delta / 1000;
127
+ const count = Math.floor(this.credit);
128
+ this.credit -= count;
129
+ let end = this.boundaries[Math.min(this.boundaries.length - 1, index + count)];
130
+ for (const item of this.arrivals) {
131
+ if (now - item.at < STREAM_TIMING.maxQueuedMs)
132
+ break;
133
+ end = Math.max(end, this.boundaries[atOrAfter(this.boundaries, item.end)]);
134
+ }
135
+ if (this.finishAt !== null && now >= this.finishAt)
136
+ end = this.target.length;
137
+ // Never expose half of a surrogate pair while the source can still grow.
138
+ if (end && /[\uD800-\uDBFF]/.test(this.target[end - 1]) && this.finishAt === null)
139
+ end--;
140
+ end = Math.max(before, end);
141
+ this.visible = this.target.slice(0, end);
142
+ this.arrivals = this.arrivals.filter(item => item.end > end);
143
+ if (!this.pending) {
144
+ this.credit = 0;
145
+ this.lastAt = null;
146
+ }
147
+ return end !== before;
148
+ }
149
+ }
150
+ //# sourceMappingURL=stream-buffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-buffer.js","sourceRoot":"","sources":["../../../src/client/stream-buffer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export declare const StreamMotionContext: import("react").Context<{
2
+ enabled: boolean;
3
+ activatedAt: number;
4
+ paused?: boolean;
5
+ resumed?: boolean;
6
+ }>;
7
+ export declare function useStreamingText(source: string, streaming: boolean, options: {
8
+ startedAt?: number;
9
+ interrupted: boolean;
10
+ selected: boolean;
11
+ }): {
12
+ text: string;
13
+ pending: boolean;
14
+ revision: number;
15
+ formatStreaming: boolean;
16
+ reveal: boolean;
17
+ };
18
+ //# sourceMappingURL=streaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../../src/client/streaming.tsx"],"names":[],"mappings":"AAIA,eAAO,MAAM,mBAAmB;aAA4B,OAAO;iBAAe,MAAM;aAAW,OAAO;cAAY,OAAO;EAAuC,CAAC;AAErK,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE;;;;;;EA+D5I"}
@@ -0,0 +1,84 @@
1
+ import { createContext, useContext, useEffect, useLayoutEffect, useRef, useState } from 'react';
2
+ import { StreamBuffer } from './stream-buffer.js';
3
+ import { WORD_MOTION } from './word-timeline.js';
4
+ export const StreamMotionContext = createContext({ enabled: false, activatedAt: 0 });
5
+ export function useStreamingText(source, streaming, options) {
6
+ const { enabled, activatedAt, paused = false, resumed = false } = useContext(StreamMotionContext);
7
+ const fresh = resumed || (options.startedAt ?? 0) >= activatedAt;
8
+ const buffer = useRef();
9
+ // Only newly mounted content after a fold uses the catch-up path. History and
10
+ // user-opened drawers stay immediate; already mounted prefixes never replay.
11
+ if (!buffer.current)
12
+ buffer.current = new StreamBuffer(enabled && (streaming || resumed) && fresh ? '' : source);
13
+ const [display, setDisplay] = useState(() => ({ text: buffer.current.visible, revision: 0 }));
14
+ const [finalizing, setFinalizing] = useState(streaming);
15
+ const frame = useRef(0);
16
+ const immediate = !enabled || options.interrupted || options.selected;
17
+ const publish = () => {
18
+ const current = buffer.current;
19
+ setDisplay(previous => previous.text === current.visible && previous.revision === current.revision ? previous : { text: current.visible, revision: current.revision });
20
+ };
21
+ const handoff = useRef(resumed);
22
+ const presentationClock = useRef(performance.now());
23
+ useLayoutEffect(() => {
24
+ cancelAnimationFrame(frame.current);
25
+ const current = buffer.current;
26
+ // While the choreography holds the reveal, keep the buffer absorbing the
27
+ // source instead of returning early: the target must never lag behind what
28
+ // arrived, or the text would keep catching up long after the fold settled.
29
+ // Dropping the frame loop is what pauses the reveal; the target still tracks.
30
+ if (paused && !immediate && !document.hidden) {
31
+ current.update(source, performance.now(), { immediate: false, finished: !streaming });
32
+ publish();
33
+ return;
34
+ }
35
+ let previous = performance.now();
36
+ current.update(source, handoff.current ? presentationClock.current : previous, { immediate: immediate || document.hidden, finished: !streaming && !resumed });
37
+ publish();
38
+ const tick = (now) => {
39
+ // A delayed browser frame must not dump the whole buffered response at
40
+ // first paint. Bound catch-up by visible frame time for this handoff only.
41
+ presentationClock.current += Math.min(32, Math.max(0, now - previous));
42
+ previous = now;
43
+ if (document.hidden)
44
+ current.flush();
45
+ else
46
+ current.advance(handoff.current ? presentationClock.current : now);
47
+ publish();
48
+ if (current.pending)
49
+ frame.current = requestAnimationFrame(tick);
50
+ else
51
+ handoff.current = false;
52
+ };
53
+ if (current.pending)
54
+ frame.current = requestAnimationFrame(tick);
55
+ return () => cancelAnimationFrame(frame.current);
56
+ }, [source, streaming, immediate, paused, resumed]);
57
+ useEffect(() => {
58
+ const hidden = () => {
59
+ if (!document.hidden)
60
+ return;
61
+ cancelAnimationFrame(frame.current);
62
+ buffer.current.flush();
63
+ publish();
64
+ setFinalizing(false);
65
+ };
66
+ document.addEventListener('visibilitychange', hidden);
67
+ return () => document.removeEventListener('visibilitychange', hidden);
68
+ }, []);
69
+ const pending = display.text !== source;
70
+ useEffect(() => {
71
+ if (streaming || pending) {
72
+ setFinalizing(true);
73
+ return;
74
+ }
75
+ if (immediate || document.hidden) {
76
+ setFinalizing(false);
77
+ return;
78
+ }
79
+ const timer = setTimeout(() => setFinalizing(false), WORD_MOTION.duration + WORD_MOTION.maxDelay);
80
+ return () => clearTimeout(timer);
81
+ }, [streaming, pending, immediate]);
82
+ return { text: immediate ? source : display.text, pending: !immediate && pending, revision: display.revision, formatStreaming: streaming || (!immediate && (pending || finalizing)), reveal: enabled && !options.interrupted && !options.selected };
83
+ }
84
+ //# sourceMappingURL=streaming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../../src/client/streaming.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export interface TimelineItem {
2
+ readonly turn: number;
3
+ readonly prompt: string;
4
+ readonly response: string;
5
+ readonly hasDeliverables: boolean;
6
+ readonly anchor: {
7
+ readonly kind: 'loaded';
8
+ readonly key: string;
9
+ } | {
10
+ readonly kind: 'unloaded';
11
+ readonly seq: number;
12
+ };
13
+ }
14
+ interface LoadedTurnNavigationItem {
15
+ readonly turn: number;
16
+ readonly anchorKey: string;
17
+ readonly prompt: string;
18
+ readonly response: string;
19
+ }
20
+ /**
21
+ * Merge host turn outline with loaded navigation items and turn deliverables.
22
+ * Guarantees strictly ascending turn order and dedupes entries.
23
+ */
24
+ export declare function mergeTimelineItems(loaded: readonly LoadedTurnNavigationItem[] | undefined, outline: unknown, turnsWithDeliverables?: ReadonlySet<number>): readonly TimelineItem[];
25
+ export {};
26
+ //# sourceMappingURL=timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../../src/client/timeline.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,MAAM,EACX;QAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GACjD;QAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD;AASD,UAAU,wBAAwB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,wBAAwB,EAAE,GAAG,SAAS,EACvD,OAAO,EAAE,OAAO,EAChB,qBAAqB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAC1C,SAAS,YAAY,EAAE,CA0CzB"}