@deepseek-harness-tui/dsh-tui 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (692) hide show
  1. package/README.md +41 -5
  2. package/assets/deepy/README.md +60 -0
  3. package/assets/deepy/frames.json +1 -0
  4. package/assets/whale-girl/whale-girl-happy.png +0 -0
  5. package/assets/whaleGirl/README.md +7 -0
  6. package/assets/whaleGirl/frames.json +1 -0
  7. package/assets/whaleGirl/img/building/00.png +0 -0
  8. package/assets/whaleGirl/img/building/01.png +0 -0
  9. package/assets/whaleGirl/img/building/02.png +0 -0
  10. package/assets/whaleGirl/img/building/03.png +0 -0
  11. package/assets/whaleGirl/img/building/04.png +0 -0
  12. package/assets/whaleGirl/img/building/05.png +0 -0
  13. package/assets/whaleGirl/img/building/06.png +0 -0
  14. package/assets/whaleGirl/img/building/07.png +0 -0
  15. package/assets/whaleGirl/img/building/08.png +0 -0
  16. package/assets/whaleGirl/img/building/09.png +0 -0
  17. package/assets/whaleGirl/img/building/10.png +0 -0
  18. package/assets/whaleGirl/img/building/11.png +0 -0
  19. package/assets/whaleGirl/img/building/12.png +0 -0
  20. package/assets/whaleGirl/img/building/13.png +0 -0
  21. package/assets/whaleGirl/img/building/14.png +0 -0
  22. package/assets/whaleGirl/img/building/15.png +0 -0
  23. package/assets/whaleGirl/img/building/16.png +0 -0
  24. package/assets/whaleGirl/img/building/17.png +0 -0
  25. package/assets/whaleGirl/img/building/18.png +0 -0
  26. package/assets/whaleGirl/img/building/19.png +0 -0
  27. package/assets/whaleGirl/img/building/20.png +0 -0
  28. package/assets/whaleGirl/img/building/21.png +0 -0
  29. package/assets/whaleGirl/img/building/22.png +0 -0
  30. package/assets/whaleGirl/img/building/23.png +0 -0
  31. package/assets/whaleGirl/img/carrying/00.png +0 -0
  32. package/assets/whaleGirl/img/carrying/01.png +0 -0
  33. package/assets/whaleGirl/img/carrying/02.png +0 -0
  34. package/assets/whaleGirl/img/carrying/03.png +0 -0
  35. package/assets/whaleGirl/img/carrying/04.png +0 -0
  36. package/assets/whaleGirl/img/carrying/05.png +0 -0
  37. package/assets/whaleGirl/img/carrying/06.png +0 -0
  38. package/assets/whaleGirl/img/carrying/07.png +0 -0
  39. package/assets/whaleGirl/img/compacting/00.png +0 -0
  40. package/assets/whaleGirl/img/compacting/01.png +0 -0
  41. package/assets/whaleGirl/img/compacting/02.png +0 -0
  42. package/assets/whaleGirl/img/compacting/03.png +0 -0
  43. package/assets/whaleGirl/img/compacting/04.png +0 -0
  44. package/assets/whaleGirl/img/compacting/05.png +0 -0
  45. package/assets/whaleGirl/img/compacting/06.png +0 -0
  46. package/assets/whaleGirl/img/compacting/07.png +0 -0
  47. package/assets/whaleGirl/img/compacting/08.png +0 -0
  48. package/assets/whaleGirl/img/compacting/09.png +0 -0
  49. package/assets/whaleGirl/img/conducting/00.png +0 -0
  50. package/assets/whaleGirl/img/conducting/01.png +0 -0
  51. package/assets/whaleGirl/img/conducting/02.png +0 -0
  52. package/assets/whaleGirl/img/conducting/03.png +0 -0
  53. package/assets/whaleGirl/img/conducting/04.png +0 -0
  54. package/assets/whaleGirl/img/conducting/05.png +0 -0
  55. package/assets/whaleGirl/img/conducting/06.png +0 -0
  56. package/assets/whaleGirl/img/conducting/07.png +0 -0
  57. package/assets/whaleGirl/img/conducting/08.png +0 -0
  58. package/assets/whaleGirl/img/conducting/09.png +0 -0
  59. package/assets/whaleGirl/img/conducting/10.png +0 -0
  60. package/assets/whaleGirl/img/conducting/11.png +0 -0
  61. package/assets/whaleGirl/img/drag/00.png +0 -0
  62. package/assets/whaleGirl/img/drag/01.png +0 -0
  63. package/assets/whaleGirl/img/drag/02.png +0 -0
  64. package/assets/whaleGirl/img/drag/03.png +0 -0
  65. package/assets/whaleGirl/img/drag/04.png +0 -0
  66. package/assets/whaleGirl/img/drag/05.png +0 -0
  67. package/assets/whaleGirl/img/drag/06.png +0 -0
  68. package/assets/whaleGirl/img/drag/07.png +0 -0
  69. package/assets/whaleGirl/img/drag/08.png +0 -0
  70. package/assets/whaleGirl/img/drag/09.png +0 -0
  71. package/assets/whaleGirl/img/error/00.png +0 -0
  72. package/assets/whaleGirl/img/error/01.png +0 -0
  73. package/assets/whaleGirl/img/error/02.png +0 -0
  74. package/assets/whaleGirl/img/error/03.png +0 -0
  75. package/assets/whaleGirl/img/error/04.png +0 -0
  76. package/assets/whaleGirl/img/error/05.png +0 -0
  77. package/assets/whaleGirl/img/error/06.png +0 -0
  78. package/assets/whaleGirl/img/error/07.png +0 -0
  79. package/assets/whaleGirl/img/error/08.png +0 -0
  80. package/assets/whaleGirl/img/error/09.png +0 -0
  81. package/assets/whaleGirl/img/happy/00.png +0 -0
  82. package/assets/whaleGirl/img/happy/01.png +0 -0
  83. package/assets/whaleGirl/img/happy/02.png +0 -0
  84. package/assets/whaleGirl/img/happy/03.png +0 -0
  85. package/assets/whaleGirl/img/happy/04.png +0 -0
  86. package/assets/whaleGirl/img/happy/05.png +0 -0
  87. package/assets/whaleGirl/img/happy/06.png +0 -0
  88. package/assets/whaleGirl/img/happy/07.png +0 -0
  89. package/assets/whaleGirl/img/happy/08.png +0 -0
  90. package/assets/whaleGirl/img/happy/09.png +0 -0
  91. package/assets/whaleGirl/img/happy/10.png +0 -0
  92. package/assets/whaleGirl/img/idle/00.png +0 -0
  93. package/assets/whaleGirl/img/idle/01.png +0 -0
  94. package/assets/whaleGirl/img/idle/02.png +0 -0
  95. package/assets/whaleGirl/img/idle/03.png +0 -0
  96. package/assets/whaleGirl/img/idle/04.png +0 -0
  97. package/assets/whaleGirl/img/idle/05.png +0 -0
  98. package/assets/whaleGirl/img/idle/06.png +0 -0
  99. package/assets/whaleGirl/img/idle/07.png +0 -0
  100. package/assets/whaleGirl/img/idle/08.png +0 -0
  101. package/assets/whaleGirl/img/idle/09.png +0 -0
  102. package/assets/whaleGirl/img/idle/10.png +0 -0
  103. package/assets/whaleGirl/img/idle/11.png +0 -0
  104. package/assets/whaleGirl/img/idle/12.png +0 -0
  105. package/assets/whaleGirl/img/idle/13.png +0 -0
  106. package/assets/whaleGirl/img/idle/14.png +0 -0
  107. package/assets/whaleGirl/img/idle/15.png +0 -0
  108. package/assets/whaleGirl/img/idle/16.png +0 -0
  109. package/assets/whaleGirl/img/idle/17.png +0 -0
  110. package/assets/whaleGirl/img/idle/18.png +0 -0
  111. package/assets/whaleGirl/img/idle/19.png +0 -0
  112. package/assets/whaleGirl/img/idle/20.png +0 -0
  113. package/assets/whaleGirl/img/idle-look/00.png +0 -0
  114. package/assets/whaleGirl/img/idle-look/01.png +0 -0
  115. package/assets/whaleGirl/img/idle-look/02.png +0 -0
  116. package/assets/whaleGirl/img/idle-look/03.png +0 -0
  117. package/assets/whaleGirl/img/idle-look/04.png +0 -0
  118. package/assets/whaleGirl/img/idle-look/05.png +0 -0
  119. package/assets/whaleGirl/img/idle-look/06.png +0 -0
  120. package/assets/whaleGirl/img/idle-look/07.png +0 -0
  121. package/assets/whaleGirl/img/idle-look/08.png +0 -0
  122. package/assets/whaleGirl/img/idle-look/09.png +0 -0
  123. package/assets/whaleGirl/img/idle-look/10.png +0 -0
  124. package/assets/whaleGirl/img/idle-look/11.png +0 -0
  125. package/assets/whaleGirl/img/idle-look/12.png +0 -0
  126. package/assets/whaleGirl/img/idle-spout/00.png +0 -0
  127. package/assets/whaleGirl/img/idle-spout/01.png +0 -0
  128. package/assets/whaleGirl/img/idle-spout/02.png +0 -0
  129. package/assets/whaleGirl/img/idle-spout/03.png +0 -0
  130. package/assets/whaleGirl/img/idle-spout/04.png +0 -0
  131. package/assets/whaleGirl/img/idle-spout/05.png +0 -0
  132. package/assets/whaleGirl/img/idle-spout/06.png +0 -0
  133. package/assets/whaleGirl/img/idle-spout/07.png +0 -0
  134. package/assets/whaleGirl/img/idle-spout/08.png +0 -0
  135. package/assets/whaleGirl/img/idle-spout/09.png +0 -0
  136. package/assets/whaleGirl/img/idle-spout/10.png +0 -0
  137. package/assets/whaleGirl/img/music/00.png +0 -0
  138. package/assets/whaleGirl/img/music/01.png +0 -0
  139. package/assets/whaleGirl/img/music/02.png +0 -0
  140. package/assets/whaleGirl/img/music/03.png +0 -0
  141. package/assets/whaleGirl/img/music/04.png +0 -0
  142. package/assets/whaleGirl/img/music/05.png +0 -0
  143. package/assets/whaleGirl/img/music/06.png +0 -0
  144. package/assets/whaleGirl/img/music/07.png +0 -0
  145. package/assets/whaleGirl/img/notification/00.png +0 -0
  146. package/assets/whaleGirl/img/notification/01.png +0 -0
  147. package/assets/whaleGirl/img/notification/02.png +0 -0
  148. package/assets/whaleGirl/img/notification/03.png +0 -0
  149. package/assets/whaleGirl/img/notification/04.png +0 -0
  150. package/assets/whaleGirl/img/notification/05.png +0 -0
  151. package/assets/whaleGirl/img/notification/06.png +0 -0
  152. package/assets/whaleGirl/img/notification/07.png +0 -0
  153. package/assets/whaleGirl/img/poke-left/00.png +0 -0
  154. package/assets/whaleGirl/img/poke-left/01.png +0 -0
  155. package/assets/whaleGirl/img/poke-left/02.png +0 -0
  156. package/assets/whaleGirl/img/poke-left/03.png +0 -0
  157. package/assets/whaleGirl/img/poke-left/04.png +0 -0
  158. package/assets/whaleGirl/img/poke-left/05.png +0 -0
  159. package/assets/whaleGirl/img/poke-left/06.png +0 -0
  160. package/assets/whaleGirl/img/poke-left/07.png +0 -0
  161. package/assets/whaleGirl/img/poke-left/08.png +0 -0
  162. package/assets/whaleGirl/img/poke-left/09.png +0 -0
  163. package/assets/whaleGirl/img/poke-left/10.png +0 -0
  164. package/assets/whaleGirl/img/poke-right/00.png +0 -0
  165. package/assets/whaleGirl/img/poke-right/01.png +0 -0
  166. package/assets/whaleGirl/img/poke-right/02.png +0 -0
  167. package/assets/whaleGirl/img/poke-right/03.png +0 -0
  168. package/assets/whaleGirl/img/poke-right/04.png +0 -0
  169. package/assets/whaleGirl/img/poke-right/05.png +0 -0
  170. package/assets/whaleGirl/img/poke-right/06.png +0 -0
  171. package/assets/whaleGirl/img/poke-right/07.png +0 -0
  172. package/assets/whaleGirl/img/poke-right/08.png +0 -0
  173. package/assets/whaleGirl/img/poke-right/09.png +0 -0
  174. package/assets/whaleGirl/img/poke-right/10.png +0 -0
  175. package/assets/whaleGirl/img/sleeping/00.png +0 -0
  176. package/assets/whaleGirl/img/sleeping/01.png +0 -0
  177. package/assets/whaleGirl/img/sleeping/02.png +0 -0
  178. package/assets/whaleGirl/img/sleeping/03.png +0 -0
  179. package/assets/whaleGirl/img/sleeping/04.png +0 -0
  180. package/assets/whaleGirl/img/sleeping/05.png +0 -0
  181. package/assets/whaleGirl/img/smile-hearts/00.png +0 -0
  182. package/assets/whaleGirl/img/smile-hearts/01.png +0 -0
  183. package/assets/whaleGirl/img/smile-hearts/02.png +0 -0
  184. package/assets/whaleGirl/img/smile-hearts/03.png +0 -0
  185. package/assets/whaleGirl/img/smile-hearts/04.png +0 -0
  186. package/assets/whaleGirl/img/smile-hearts/05.png +0 -0
  187. package/assets/whaleGirl/img/smile-hearts/06.png +0 -0
  188. package/assets/whaleGirl/img/smile-hearts/07.png +0 -0
  189. package/assets/whaleGirl/img/smile-hearts/08.png +0 -0
  190. package/assets/whaleGirl/img/smile-hearts/09.png +0 -0
  191. package/assets/whaleGirl/img/smile-hearts/10.png +0 -0
  192. package/assets/whaleGirl/img/smile-hearts/11.png +0 -0
  193. package/assets/whaleGirl/img/smile-hearts/12.png +0 -0
  194. package/assets/whaleGirl/img/smile-hearts/13.png +0 -0
  195. package/assets/whaleGirl/img/smile-hearts/14.png +0 -0
  196. package/assets/whaleGirl/img/smile-hearts/15.png +0 -0
  197. package/assets/whaleGirl/img/swim/00.png +0 -0
  198. package/assets/whaleGirl/img/swim/01.png +0 -0
  199. package/assets/whaleGirl/img/swim/02.png +0 -0
  200. package/assets/whaleGirl/img/swim/03.png +0 -0
  201. package/assets/whaleGirl/img/swim/04.png +0 -0
  202. package/assets/whaleGirl/img/swim/05.png +0 -0
  203. package/assets/whaleGirl/img/swim/06.png +0 -0
  204. package/assets/whaleGirl/img/swim/07.png +0 -0
  205. package/assets/whaleGirl/img/thinking/00.png +0 -0
  206. package/assets/whaleGirl/img/thinking/01.png +0 -0
  207. package/assets/whaleGirl/img/thinking/02.png +0 -0
  208. package/assets/whaleGirl/img/thinking/03.png +0 -0
  209. package/assets/whaleGirl/img/thinking/04.png +0 -0
  210. package/assets/whaleGirl/img/thinking/05.png +0 -0
  211. package/assets/whaleGirl/img/thinking/06.png +0 -0
  212. package/assets/whaleGirl/img/thinking/07.png +0 -0
  213. package/assets/whaleGirl/img/thinking/08.png +0 -0
  214. package/assets/whaleGirl/img/thinking/09.png +0 -0
  215. package/assets/whaleGirl/img/thinking/10.png +0 -0
  216. package/assets/whaleGirl/img/thinking/11.png +0 -0
  217. package/assets/whaleGirl/img/thinking/12.png +0 -0
  218. package/assets/whaleGirl/img/thinking/13.png +0 -0
  219. package/assets/whaleGirl/img/thinking/14.png +0 -0
  220. package/assets/whaleGirl/img/thinking/15.png +0 -0
  221. package/assets/whaleGirl/img/thinking/16.png +0 -0
  222. package/assets/whaleGirl/img/thumbs-up/00.png +0 -0
  223. package/assets/whaleGirl/img/thumbs-up/01.png +0 -0
  224. package/assets/whaleGirl/img/thumbs-up/02.png +0 -0
  225. package/assets/whaleGirl/img/thumbs-up/03.png +0 -0
  226. package/assets/whaleGirl/img/thumbs-up/04.png +0 -0
  227. package/assets/whaleGirl/img/thumbs-up/05.png +0 -0
  228. package/assets/whaleGirl/img/thumbs-up/06.png +0 -0
  229. package/assets/whaleGirl/img/thumbs-up/07.png +0 -0
  230. package/assets/whaleGirl/img/thumbs-up/08.png +0 -0
  231. package/assets/whaleGirl/img/thumbs-up/09.png +0 -0
  232. package/assets/whaleGirl/img/thumbs-up/10.png +0 -0
  233. package/assets/whaleGirl/img/thumbs-up/11.png +0 -0
  234. package/assets/whaleGirl/img/thumbs-up/12.png +0 -0
  235. package/assets/whaleGirl/img/tickle/00.png +0 -0
  236. package/assets/whaleGirl/img/tickle/01.png +0 -0
  237. package/assets/whaleGirl/img/tickle/02.png +0 -0
  238. package/assets/whaleGirl/img/tickle/03.png +0 -0
  239. package/assets/whaleGirl/img/tickle/04.png +0 -0
  240. package/assets/whaleGirl/img/tickle/05.png +0 -0
  241. package/assets/whaleGirl/img/tickle/06.png +0 -0
  242. package/assets/whaleGirl/img/tickle/07.png +0 -0
  243. package/assets/whaleGirl/img/tickle/08.png +0 -0
  244. package/assets/whaleGirl/img/tickle/09.png +0 -0
  245. package/assets/whaleGirl/img/tickle/10.png +0 -0
  246. package/assets/whaleGirl/img/tickle/11.png +0 -0
  247. package/assets/whaleGirl/img/tickle/12.png +0 -0
  248. package/assets/whaleGirl/img/tickle/13.png +0 -0
  249. package/assets/whaleGirl/img/timings.json +1 -0
  250. package/assets/whaleGirl/img/typing/00.png +0 -0
  251. package/assets/whaleGirl/img/typing/01.png +0 -0
  252. package/assets/whaleGirl/img/typing/02.png +0 -0
  253. package/assets/whaleGirl/img/typing/03.png +0 -0
  254. package/assets/whaleGirl/img/typing/04.png +0 -0
  255. package/assets/whaleGirl/img/typing/05.png +0 -0
  256. package/assets/whaleGirl/img/typing/06.png +0 -0
  257. package/assets/whaleGirl/img/typing/07.png +0 -0
  258. package/assets/whaleGirl/img/typing/08.png +0 -0
  259. package/assets/whaleGirl/img/typing/09.png +0 -0
  260. package/assets/whaleGirl/img/typing/10.png +0 -0
  261. package/assets/whaleGirl/img/typing/11.png +0 -0
  262. package/assets/whaleGirl/img/typing/12.png +0 -0
  263. package/assets/whaleGirl/img/typing/13.png +0 -0
  264. package/assets/whaleGirl/img/waking/00.png +0 -0
  265. package/assets/whaleGirl/img/waking/01.png +0 -0
  266. package/assets/whaleGirl/img/waking/02.png +0 -0
  267. package/assets/whaleGirl/img/waking/03.png +0 -0
  268. package/assets/whaleGirl/img/waking/04.png +0 -0
  269. package/assets/whaleGirl/img/waking/05.png +0 -0
  270. package/assets/whaleGirl/img/waking/06.png +0 -0
  271. package/assets/whaleGirl/img/waking/07.png +0 -0
  272. package/assets/whaleGirl/img/waking/08.png +0 -0
  273. package/assets/whaleGirl/img/waking/09.png +0 -0
  274. package/assets/whaleGirl/img/waking/10.png +0 -0
  275. package/bin/dsh-tui.js +8 -3
  276. package/cordis.patch.yml +7 -1
  277. package/guide/dsh-tui-guide/configuration.en.md +6 -1
  278. package/guide/dsh-tui-guide/configuration.md +6 -1
  279. package/guide/dsh-tui-guide/getting-started.en.md +6 -3
  280. package/guide/dsh-tui-guide/getting-started.md +4 -2
  281. package/guide/dsh-tui-guide/interaction.en.md +68 -4
  282. package/guide/dsh-tui-guide/interaction.md +49 -3
  283. package/guide/dsh-tui-guide/plugins.en.md +16 -6
  284. package/guide/dsh-tui-guide/plugins.md +14 -6
  285. package/guide/dsh-tui-guide/themes.en.md +7 -2
  286. package/guide/dsh-tui-guide/themes.md +5 -2
  287. package/guide/dsh-tui-guide/user-guide.en.md +124 -21
  288. package/guide/dsh-tui-guide/user-guide.md +96 -16
  289. package/lib/settings.json +215 -1
  290. package/lib/types/adapter/channel/ui-policy.d.ts +6 -2
  291. package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
  292. package/lib/types/adapter/channel/ui-policy.js +14 -1
  293. package/lib/types/adapter/index.d.ts +1 -1
  294. package/lib/types/adapter/index.js +1 -1
  295. package/lib/types/adapter/kernel/host-facade.d.ts +4 -1
  296. package/lib/types/adapter/kernel/host-facade.d.ts.map +1 -1
  297. package/lib/types/adapter/kernel/host-facade.js +8 -1
  298. package/lib/types/adapter/kernel/runtime.d.ts.map +1 -1
  299. package/lib/types/adapter/kernel/runtime.js +13 -0
  300. package/lib/types/adapter/kernel/slices/index.d.ts +1 -0
  301. package/lib/types/adapter/kernel/slices/index.d.ts.map +1 -1
  302. package/lib/types/adapter/kernel/slices/index.js +3 -0
  303. package/lib/types/adapter/kernel/slices/panels.d.ts +3 -0
  304. package/lib/types/adapter/kernel/slices/panels.d.ts.map +1 -0
  305. package/lib/types/adapter/kernel/slices/panels.js +14 -0
  306. package/lib/types/adapter/ports/channel-capabilities.d.ts +48 -0
  307. package/lib/types/adapter/ports/channel-capabilities.d.ts.map +1 -0
  308. package/lib/types/adapter/ports/channel-capabilities.js +2 -0
  309. package/lib/types/adapter/ports/channel-catalog.d.ts +7 -0
  310. package/lib/types/adapter/ports/channel-catalog.d.ts.map +1 -1
  311. package/lib/types/adapter/ports/channel-display.d.ts +10 -0
  312. package/lib/types/adapter/ports/channel-display.d.ts.map +1 -1
  313. package/lib/types/adapter/ports/channel-ui.d.ts +62 -2
  314. package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
  315. package/lib/types/adapter/ports/channel-view.d.ts +94 -0
  316. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
  317. package/lib/types/adapter/ports/channel.d.ts +1 -1
  318. package/lib/types/adapter/ports/channel.js +1 -1
  319. package/lib/types/adapter/ports/descriptor.d.ts +1 -1
  320. package/lib/types/adapter/ports/descriptor.js +1 -1
  321. package/lib/types/adapter/ports/index.d.ts +1 -1
  322. package/lib/types/adapter/ports/index.js +1 -1
  323. package/lib/types/adapter/ports/panels.d.ts +28 -0
  324. package/lib/types/adapter/ports/panels.d.ts.map +1 -0
  325. package/lib/types/adapter/ports/panels.js +8 -0
  326. package/lib/types/adapter/ports/workspace.d.ts +1 -1
  327. package/lib/types/adapter/ports/workspace.js +1 -1
  328. package/lib/types/adapter/spec/index.d.ts +2 -2
  329. package/lib/types/adapter/spec/index.js +2 -2
  330. package/lib/types/adapter/spec/profile.d.ts +6 -6
  331. package/lib/types/adapter/spec/profile.d.ts.map +1 -1
  332. package/lib/types/adapter/spec/profile.js +6 -6
  333. package/lib/types/adapter/spec/protocol-constants.d.ts +3 -3
  334. package/lib/types/adapter/spec/protocol-constants.d.ts.map +1 -1
  335. package/lib/types/adapter/spec/protocol-constants.js +5 -5
  336. package/lib/types/adapter/spec/tui-contributions.d.ts +4 -4
  337. package/lib/types/adapter/spec/tui-contributions.d.ts.map +1 -1
  338. package/lib/types/adapter/spec/tui-contributions.js +5 -5
  339. package/lib/types/adapter/standard/descriptor.js +1 -1
  340. package/lib/types/adapter/standard/index.d.ts +3 -3
  341. package/lib/types/adapter/standard/index.js +3 -3
  342. package/lib/types/adapter/standard/registry.d.ts +3 -2
  343. package/lib/types/adapter/standard/registry.d.ts.map +1 -1
  344. package/lib/types/adapter/standard/registry.js +6 -5
  345. package/lib/types/adapter/standard/tui-extension.d.ts +1 -1
  346. package/lib/types/adapter/standard/tui-extension.js +1 -1
  347. package/lib/types/adapter/upstream/index.d.ts +1 -0
  348. package/lib/types/adapter/upstream/index.d.ts.map +1 -1
  349. package/lib/types/adapter/upstream/index.js +1 -0
  350. package/lib/types/adapter/upstream/panels-driver.d.ts +18 -0
  351. package/lib/types/adapter/upstream/panels-driver.d.ts.map +1 -0
  352. package/lib/types/adapter/upstream/panels-driver.js +159 -0
  353. package/lib/types/api.d.ts +2 -0
  354. package/lib/types/api.d.ts.map +1 -1
  355. package/lib/types/api.js +3 -1
  356. package/lib/types/commands.d.ts.map +1 -1
  357. package/lib/types/commands.js +12 -4
  358. package/lib/types/components/ActivityLine.d.ts +6 -9
  359. package/lib/types/components/ActivityLine.d.ts.map +1 -1
  360. package/lib/types/components/ActivityLine.js +7 -8
  361. package/lib/types/components/Chat/JobCard.d.ts +18 -1
  362. package/lib/types/components/Chat/JobCard.d.ts.map +1 -1
  363. package/lib/types/components/Chat/JobCard.js +90 -22
  364. package/lib/types/components/Chat/JobGroupHeader.d.ts +27 -0
  365. package/lib/types/components/Chat/JobGroupHeader.d.ts.map +1 -0
  366. package/lib/types/components/Chat/JobGroupHeader.js +62 -0
  367. package/lib/types/components/GoalTodoPanel.d.ts +13 -1
  368. package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
  369. package/lib/types/components/GoalTodoPanel.js +55 -14
  370. package/lib/types/components/JobsPanel.d.ts +42 -2
  371. package/lib/types/components/JobsPanel.d.ts.map +1 -1
  372. package/lib/types/components/JobsPanel.js +147 -14
  373. package/lib/types/components/LogoV2.d.ts +43 -3
  374. package/lib/types/components/LogoV2.d.ts.map +1 -1
  375. package/lib/types/components/LogoV2.js +42 -15
  376. package/lib/types/components/MessageList.d.ts +8 -2
  377. package/lib/types/components/MessageList.d.ts.map +1 -1
  378. package/lib/types/components/MessageList.js +212 -18
  379. package/lib/types/components/OverlayAbove.d.ts +11 -1
  380. package/lib/types/components/OverlayAbove.d.ts.map +1 -1
  381. package/lib/types/components/OverlayAbove.js +2 -12
  382. package/lib/types/components/PageMargin.d.ts.map +1 -1
  383. package/lib/types/components/PageMargin.js +3 -1
  384. package/lib/types/components/PluginSceneBoundary.d.ts +1 -1
  385. package/lib/types/components/PluginSceneBoundary.js +1 -1
  386. package/lib/types/components/PromptInput.d.ts +20 -22
  387. package/lib/types/components/PromptInput.d.ts.map +1 -1
  388. package/lib/types/components/PromptInput.js +413 -156
  389. package/lib/types/components/SearchBox.d.ts +22 -5
  390. package/lib/types/components/SearchBox.d.ts.map +1 -1
  391. package/lib/types/components/SearchBox.js +17 -13
  392. package/lib/types/components/SubagentCard.d.ts.map +1 -1
  393. package/lib/types/components/SubagentCard.js +17 -2
  394. package/lib/types/components/SubagentDashboard.d.ts +18 -3
  395. package/lib/types/components/SubagentDashboard.d.ts.map +1 -1
  396. package/lib/types/components/SubagentDashboard.js +53 -5
  397. package/lib/types/components/SubagentDetailScene.d.ts +7 -1
  398. package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
  399. package/lib/types/components/SubagentDetailScene.js +54 -5
  400. package/lib/types/components/SurfaceEdges.d.ts +21 -0
  401. package/lib/types/components/SurfaceEdges.d.ts.map +1 -0
  402. package/lib/types/components/SurfaceEdges.js +7 -0
  403. package/lib/types/components/ThemePicker.d.ts +9 -0
  404. package/lib/types/components/ThemePicker.d.ts.map +1 -1
  405. package/lib/types/components/ThemePicker.js +74 -10
  406. package/lib/types/components/ThemePreviewPane.d.ts +26 -0
  407. package/lib/types/components/ThemePreviewPane.d.ts.map +1 -0
  408. package/lib/types/components/ThemePreviewPane.js +99 -0
  409. package/lib/types/components/design-system/Divider.d.ts.map +1 -1
  410. package/lib/types/components/design-system/Divider.js +14 -9
  411. package/lib/types/components/launchpadActions.d.ts +73 -0
  412. package/lib/types/components/launchpadActions.d.ts.map +1 -0
  413. package/lib/types/components/launchpadActions.js +111 -0
  414. package/lib/types/components/launchpadLayout.d.ts +62 -0
  415. package/lib/types/components/launchpadLayout.d.ts.map +1 -0
  416. package/lib/types/components/launchpadLayout.js +176 -0
  417. package/lib/types/components/onboardingModel.d.ts +83 -0
  418. package/lib/types/components/onboardingModel.d.ts.map +1 -0
  419. package/lib/types/components/onboardingModel.js +128 -0
  420. package/lib/types/components/sidePanel/InfoPanel.d.ts +17 -0
  421. package/lib/types/components/sidePanel/InfoPanel.d.ts.map +1 -0
  422. package/lib/types/components/sidePanel/InfoPanel.js +124 -0
  423. package/lib/types/components/sidePanel/PanelBar.d.ts +45 -0
  424. package/lib/types/components/sidePanel/PanelBar.d.ts.map +1 -0
  425. package/lib/types/components/sidePanel/PanelBar.js +104 -0
  426. package/lib/types/components/sidePanel/PanelErrorBoundary.d.ts +21 -0
  427. package/lib/types/components/sidePanel/PanelErrorBoundary.d.ts.map +1 -0
  428. package/lib/types/components/sidePanel/PanelErrorBoundary.js +30 -0
  429. package/lib/types/components/sidePanel/PanelHost.d.ts +36 -0
  430. package/lib/types/components/sidePanel/PanelHost.d.ts.map +1 -0
  431. package/lib/types/components/sidePanel/PanelHost.js +81 -0
  432. package/lib/types/components/sidePanel/PanelPicker.d.ts +24 -0
  433. package/lib/types/components/sidePanel/PanelPicker.d.ts.map +1 -0
  434. package/lib/types/components/sidePanel/PanelPicker.js +45 -0
  435. package/lib/types/components/sidePanel/PanelStore.d.ts +55 -0
  436. package/lib/types/components/sidePanel/PanelStore.d.ts.map +1 -0
  437. package/lib/types/components/sidePanel/PanelStore.js +109 -0
  438. package/lib/types/components/sidePanel/SidePanelColumn.d.ts +31 -0
  439. package/lib/types/components/sidePanel/SidePanelColumn.d.ts.map +1 -0
  440. package/lib/types/components/sidePanel/SidePanelColumn.js +70 -0
  441. package/lib/types/components/sidePanel/SidePanelLayout.d.ts +54 -0
  442. package/lib/types/components/sidePanel/SidePanelLayout.d.ts.map +1 -0
  443. package/lib/types/components/sidePanel/SidePanelLayout.js +81 -0
  444. package/lib/types/components/sidePanel/SidePanelRuntimeContext.d.ts +43 -0
  445. package/lib/types/components/sidePanel/SidePanelRuntimeContext.d.ts.map +1 -0
  446. package/lib/types/components/sidePanel/SidePanelRuntimeContext.js +26 -0
  447. package/lib/types/components/sidePanel/TrajectoryPanel.d.ts +7 -0
  448. package/lib/types/components/sidePanel/TrajectoryPanel.d.ts.map +1 -0
  449. package/lib/types/components/sidePanel/TrajectoryPanel.js +263 -0
  450. package/lib/types/components/sidePanel/WorkspacePanel.d.ts +4 -0
  451. package/lib/types/components/sidePanel/WorkspacePanel.d.ts.map +1 -0
  452. package/lib/types/components/sidePanel/WorkspacePanel.js +171 -0
  453. package/lib/types/components/sidePanel/builtinPanels.d.ts +3 -0
  454. package/lib/types/components/sidePanel/builtinPanels.d.ts.map +1 -0
  455. package/lib/types/components/sidePanel/builtinPanels.js +229 -0
  456. package/lib/types/components/sidePanel/companion/CompanionPanel.d.ts +53 -0
  457. package/lib/types/components/sidePanel/companion/CompanionPanel.d.ts.map +1 -0
  458. package/lib/types/components/sidePanel/companion/CompanionPanel.js +528 -0
  459. package/lib/types/components/sidePanel/companion/SplashMascot.d.ts +32 -0
  460. package/lib/types/components/sidePanel/companion/SplashMascot.d.ts.map +1 -0
  461. package/lib/types/components/sidePanel/companion/SplashMascot.js +103 -0
  462. package/lib/types/components/sidePanel/companion/deepy.d.ts +75 -0
  463. package/lib/types/components/sidePanel/companion/deepy.d.ts.map +1 -0
  464. package/lib/types/components/sidePanel/companion/deepy.js +222 -0
  465. package/lib/types/components/sidePanel/companion/mood.d.ts +176 -0
  466. package/lib/types/components/sidePanel/companion/mood.d.ts.map +1 -0
  467. package/lib/types/components/sidePanel/companion/mood.js +212 -0
  468. package/lib/types/components/sidePanel/companion/pose.d.ts +43 -0
  469. package/lib/types/components/sidePanel/companion/pose.d.ts.map +1 -0
  470. package/lib/types/components/sidePanel/companion/pose.js +34 -0
  471. package/lib/types/components/sidePanel/companion/skins.d.ts +102 -0
  472. package/lib/types/components/sidePanel/companion/skins.d.ts.map +1 -0
  473. package/lib/types/components/sidePanel/companion/skins.js +408 -0
  474. package/lib/types/components/sidePanel/dimensions.d.ts +60 -0
  475. package/lib/types/components/sidePanel/dimensions.d.ts.map +1 -0
  476. package/lib/types/components/sidePanel/dimensions.js +75 -0
  477. package/lib/types/components/sidePanel/jobsFocusStore.d.ts +21 -0
  478. package/lib/types/components/sidePanel/jobsFocusStore.d.ts.map +1 -0
  479. package/lib/types/components/sidePanel/jobsFocusStore.js +30 -0
  480. package/lib/types/components/sidePanel/panelBridge.d.ts +44 -0
  481. package/lib/types/components/sidePanel/panelBridge.d.ts.map +1 -0
  482. package/lib/types/components/sidePanel/panelBridge.js +55 -0
  483. package/lib/types/components/sidePanel/pluginPanelAdapter.d.ts +22 -0
  484. package/lib/types/components/sidePanel/pluginPanelAdapter.d.ts.map +1 -0
  485. package/lib/types/components/sidePanel/pluginPanelAdapter.js +148 -0
  486. package/lib/types/components/sidePanel/types.d.ts +110 -0
  487. package/lib/types/components/sidePanel/types.d.ts.map +1 -0
  488. package/lib/types/components/sidePanel/types.js +1 -0
  489. package/lib/types/components/sidePanel/usePanelInput.d.ts +5 -0
  490. package/lib/types/components/sidePanel/usePanelInput.d.ts.map +1 -0
  491. package/lib/types/components/sidePanel/usePanelInput.js +44 -0
  492. package/lib/types/components/sidePanel/useSidePanel.d.ts +47 -0
  493. package/lib/types/components/sidePanel/useSidePanel.d.ts.map +1 -0
  494. package/lib/types/components/sidePanel/useSidePanel.js +284 -0
  495. package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts +3 -1
  496. package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts.map +1 -1
  497. package/lib/types/components/workspaces/HomeWorkspaceRow.js +3 -2
  498. package/lib/types/deepseekPricing.d.ts +10 -9
  499. package/lib/types/deepseekPricing.d.ts.map +1 -1
  500. package/lib/types/deepseekPricing.js +18 -11
  501. package/lib/types/dsh-adapter/channel/attached-context.d.ts +58 -0
  502. package/lib/types/dsh-adapter/channel/attached-context.d.ts.map +1 -0
  503. package/lib/types/dsh-adapter/channel/attached-context.js +109 -0
  504. package/lib/types/dsh-adapter/channel/binding-events.d.ts +6 -0
  505. package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
  506. package/lib/types/dsh-adapter/channel/binding-events.js +43 -0
  507. package/lib/types/dsh-adapter/channel/capabilities.d.ts +82 -0
  508. package/lib/types/dsh-adapter/channel/capabilities.d.ts.map +1 -0
  509. package/lib/types/dsh-adapter/channel/capabilities.js +165 -0
  510. package/lib/types/dsh-adapter/channel/command-completions.d.ts.map +1 -1
  511. package/lib/types/dsh-adapter/channel/command-completions.js +8 -0
  512. package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts +4 -12
  513. package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts.map +1 -1
  514. package/lib/types/dsh-adapter/channel/context-bookkeeping.js +9 -4
  515. package/lib/types/dsh-adapter/channel/input-delivery.d.ts +13 -2
  516. package/lib/types/dsh-adapter/channel/input-delivery.d.ts.map +1 -1
  517. package/lib/types/dsh-adapter/channel/input-delivery.js +18 -1
  518. package/lib/types/dsh-adapter/channel/mode-actions.d.ts +0 -3
  519. package/lib/types/dsh-adapter/channel/mode-actions.d.ts.map +1 -1
  520. package/lib/types/dsh-adapter/channel/mode-actions.js +7 -2
  521. package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts +8 -1
  522. package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts.map +1 -1
  523. package/lib/types/dsh-adapter/channel/mode-permission-actions.js +0 -1
  524. package/lib/types/dsh-adapter/channel/preferences.d.ts +1 -1
  525. package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -1
  526. package/lib/types/dsh-adapter/channel/preferences.js +9 -1
  527. package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
  528. package/lib/types/dsh-adapter/channel/projection.js +42 -37
  529. package/lib/types/dsh-adapter/channel/reports.d.ts.map +1 -1
  530. package/lib/types/dsh-adapter/channel/reports.js +13 -4
  531. package/lib/types/dsh-adapter/channel/session-reset.d.ts +5 -1
  532. package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -1
  533. package/lib/types/dsh-adapter/channel/session-reset.js +1 -0
  534. package/lib/types/dsh-adapter/channel/state.d.ts +18 -2
  535. package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
  536. package/lib/types/dsh-adapter/channel/state.js +2 -1
  537. package/lib/types/dsh-adapter/channel/types.d.ts +1 -1
  538. package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -1
  539. package/lib/types/dsh-adapter/channel/usage.d.ts +18 -1
  540. package/lib/types/dsh-adapter/channel/usage.d.ts.map +1 -1
  541. package/lib/types/dsh-adapter/channel/usage.js +97 -2
  542. package/lib/types/dsh-adapter/channel.d.ts +1 -1
  543. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  544. package/lib/types/dsh-adapter/channel.js +56 -3
  545. package/lib/types/dsh-adapter/context-occupancy.d.ts +204 -0
  546. package/lib/types/dsh-adapter/context-occupancy.d.ts.map +1 -0
  547. package/lib/types/dsh-adapter/context-occupancy.js +299 -0
  548. package/lib/types/dsh-adapter/contract.d.ts +14 -0
  549. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  550. package/lib/types/dsh-adapter/contract.js +24 -0
  551. package/lib/types/dsh-adapter/index.d.ts +32 -0
  552. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  553. package/lib/types/dsh-adapter/index.js +20 -1
  554. package/lib/types/dsh-adapter/migrate/sessionize.d.ts.map +1 -1
  555. package/lib/types/dsh-adapter/migrate/sessionize.js +11 -12
  556. package/lib/types/dsh-adapter/panel-runtime-registry.d.ts +39 -0
  557. package/lib/types/dsh-adapter/panel-runtime-registry.d.ts.map +1 -0
  558. package/lib/types/dsh-adapter/panel-runtime-registry.js +84 -0
  559. package/lib/types/dsh-adapter/panels.d.ts +251 -0
  560. package/lib/types/dsh-adapter/panels.d.ts.map +1 -0
  561. package/lib/types/dsh-adapter/panels.js +407 -0
  562. package/lib/types/dsh-adapter/plugin-host.js +1 -1
  563. package/lib/types/dsh-adapter/plugin.d.ts +17 -1
  564. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  565. package/lib/types/dsh-adapter/plugin.js +169 -32
  566. package/lib/types/dsh-adapter/presets.d.ts +26 -6
  567. package/lib/types/dsh-adapter/presets.d.ts.map +1 -1
  568. package/lib/types/dsh-adapter/presets.js +29 -7
  569. package/lib/types/dsh-adapter/startup-args.d.ts +8 -0
  570. package/lib/types/dsh-adapter/startup-args.d.ts.map +1 -0
  571. package/lib/types/dsh-adapter/startup-args.js +34 -0
  572. package/lib/types/history.d.ts +24 -7
  573. package/lib/types/history.d.ts.map +1 -1
  574. package/lib/types/history.js +77 -18
  575. package/lib/types/i18n.d.ts +734 -15
  576. package/lib/types/i18n.d.ts.map +1 -1
  577. package/lib/types/i18n.js +302 -6
  578. package/lib/types/ink/components/App.d.ts +14 -1
  579. package/lib/types/ink/components/App.d.ts.map +1 -1
  580. package/lib/types/ink/components/App.js +62 -61
  581. package/lib/types/ink/components/TerminalSizeContext.d.ts +7 -0
  582. package/lib/types/ink/components/TerminalSizeContext.d.ts.map +1 -1
  583. package/lib/types/ink/hooks/use-input.d.ts +11 -0
  584. package/lib/types/ink/hooks/use-input.d.ts.map +1 -1
  585. package/lib/types/ink/hooks/use-input.js +8 -2
  586. package/lib/types/ink/hooks/use-terminal-viewport.d.ts.map +1 -1
  587. package/lib/types/ink/hooks/use-terminal-viewport.js +3 -1
  588. package/lib/types/ink/ink.d.ts +18 -0
  589. package/lib/types/ink/ink.d.ts.map +1 -1
  590. package/lib/types/ink/ink.js +51 -8
  591. package/lib/types/ink/output.d.ts +10 -1
  592. package/lib/types/ink/output.d.ts.map +1 -1
  593. package/lib/types/ink/output.js +3 -3
  594. package/lib/types/ink/parse-keypress.d.ts +36 -3
  595. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  596. package/lib/types/ink/parse-keypress.js +262 -108
  597. package/lib/types/ink/render-node-to-output.d.ts +1 -1
  598. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  599. package/lib/types/ink/render-node-to-output.js +37 -5
  600. package/lib/types/ink/screen.d.ts +26 -1
  601. package/lib/types/ink/screen.d.ts.map +1 -1
  602. package/lib/types/ink/screen.js +96 -1
  603. package/lib/types/ink/selection.d.ts +23 -1
  604. package/lib/types/ink/selection.d.ts.map +1 -1
  605. package/lib/types/ink/selection.js +102 -26
  606. package/lib/types/ink/sixel-codec.d.ts +11 -0
  607. package/lib/types/ink/sixel-codec.d.ts.map +1 -1
  608. package/lib/types/ink/sixel-codec.js +42 -8
  609. package/lib/types/math/renderer.d.ts +2 -0
  610. package/lib/types/math/renderer.d.ts.map +1 -1
  611. package/lib/types/math/renderer.js +4 -0
  612. package/lib/types/onboardingPrefs.d.ts +52 -0
  613. package/lib/types/onboardingPrefs.d.ts.map +1 -0
  614. package/lib/types/onboardingPrefs.js +107 -0
  615. package/lib/types/panels.d.ts +4 -0
  616. package/lib/types/panels.d.ts.map +1 -0
  617. package/lib/types/panels.js +4 -0
  618. package/lib/types/screens/Chat.d.ts +22 -1
  619. package/lib/types/screens/Chat.d.ts.map +1 -1
  620. package/lib/types/screens/Chat.js +1126 -299
  621. package/lib/types/screens/Launchpad.d.ts +194 -0
  622. package/lib/types/screens/Launchpad.d.ts.map +1 -0
  623. package/lib/types/screens/Launchpad.js +607 -0
  624. package/lib/types/screens/Onboarding.d.ts +37 -0
  625. package/lib/types/screens/Onboarding.d.ts.map +1 -0
  626. package/lib/types/screens/Onboarding.js +492 -0
  627. package/lib/types/screens/SessionSupervisor.d.ts.map +1 -1
  628. package/lib/types/screens/SessionSupervisor.js +18 -12
  629. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  630. package/lib/types/screens/StatusLine.js +32 -14
  631. package/lib/types/screens/StatusMetrics.d.ts +22 -0
  632. package/lib/types/screens/StatusMetrics.d.ts.map +1 -1
  633. package/lib/types/screens/StatusMetrics.js +20 -0
  634. package/lib/types/screens/chatOverlay.d.ts +18 -1
  635. package/lib/types/screens/chatOverlay.d.ts.map +1 -1
  636. package/lib/types/screens/chatOverlay.js +3 -0
  637. package/lib/types/screens/sessionSupervisor/model.d.ts +1 -2
  638. package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -1
  639. package/lib/types/screens/sessionSupervisor/model.js +4 -2
  640. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -1
  641. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +7 -3
  642. package/lib/types/settings/definitions.d.ts +93 -0
  643. package/lib/types/settings/definitions.d.ts.map +1 -1
  644. package/lib/types/settings/definitions.js +83 -0
  645. package/lib/types/tips.js +5 -5
  646. package/lib/types/tuiDisplayPrefs.d.ts +42 -2
  647. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
  648. package/lib/types/tuiDisplayPrefs.js +74 -0
  649. package/lib/types/update.d.ts +53 -9
  650. package/lib/types/update.d.ts.map +1 -1
  651. package/lib/types/update.js +101 -44
  652. package/lib/types/utils/bmp.d.ts.map +1 -1
  653. package/lib/types/utils/bmp.js +8 -1
  654. package/lib/types/utils/clipboard.d.ts.map +1 -1
  655. package/lib/types/utils/clipboard.js +25 -6
  656. package/lib/types/utils/credentials.d.ts.map +1 -1
  657. package/lib/types/utils/credentials.js +5 -1
  658. package/lib/types/utils/draftWordBoundary.d.ts +23 -0
  659. package/lib/types/utils/draftWordBoundary.d.ts.map +1 -0
  660. package/lib/types/utils/draftWordBoundary.js +161 -0
  661. package/lib/types/utils/fileTarget.d.ts.map +1 -1
  662. package/lib/types/utils/fileTarget.js +7 -9
  663. package/lib/types/utils/inputPaste.d.ts +62 -0
  664. package/lib/types/utils/inputPaste.d.ts.map +1 -0
  665. package/lib/types/utils/inputPaste.js +111 -0
  666. package/lib/types/utils/intl.d.ts +8 -0
  667. package/lib/types/utils/intl.d.ts.map +1 -1
  668. package/lib/types/utils/intl.js +11 -0
  669. package/lib/types/utils/keymap.d.ts +13 -3
  670. package/lib/types/utils/keymap.d.ts.map +1 -1
  671. package/lib/types/utils/keymap.js +27 -5
  672. package/package.json +19 -8
  673. package/{dsh-ecosystem-spec → tui-profile}/registry/README.md +1 -1
  674. package/{dsh-ecosystem-spec → tui-profile}/registry/registry-0.15.json +1 -1
  675. /package/{dsh-ecosystem-spec → tui-profile}/protocols/profile-definitions.d.ts +0 -0
  676. /package/{dsh-ecosystem-spec → tui-profile}/protocols/profile-definitions.js +0 -0
  677. /package/{dsh-ecosystem-spec → tui-profile}/protocols/tui-channel-http.d.ts +0 -0
  678. /package/{dsh-ecosystem-spec → tui-profile}/protocols/tui-channel-http.js +0 -0
  679. /package/{dsh-ecosystem-spec → tui-profile}/protocols/tui-channel.d.ts +0 -0
  680. /package/{dsh-ecosystem-spec → tui-profile}/protocols/tui-channel.js +0 -0
  681. /package/{dsh-ecosystem-spec → tui-profile}/protocols/tui-contributions.d.ts +0 -0
  682. /package/{dsh-ecosystem-spec → tui-profile}/protocols/tui-contributions.js +0 -0
  683. /package/{dsh-ecosystem-spec → tui-profile}/registry/contracts/decision-events-v1alpha1.json +0 -0
  684. /package/{dsh-ecosystem-spec → tui-profile}/registry/contracts/scene-v1alpha1.json +0 -0
  685. /package/{dsh-ecosystem-spec → tui-profile}/registry/contracts/settings-section-v1alpha1.json +0 -0
  686. /package/{dsh-ecosystem-spec → tui-profile}/registry/contracts/tui-channel-v1alpha1.json +0 -0
  687. /package/{dsh-ecosystem-spec → tui-profile}/registry/contracts/workspace-provider-v1alpha1.json +0 -0
  688. /package/{dsh-ecosystem-spec → tui-profile}/registry/host-descriptor.tui.example.json +0 -0
  689. /package/{dsh-ecosystem-spec → tui-profile}/registry/permissions-0.1.json +0 -0
  690. /package/{dsh-ecosystem-spec → tui-profile}/schemas/conformance-claim.schema.json +0 -0
  691. /package/{dsh-ecosystem-spec → tui-profile}/schemas/effect-ledger-record.schema.json +0 -0
  692. /package/{dsh-ecosystem-spec → tui-profile}/schemas/host-descriptor.schema.json +0 -0
@@ -75,6 +75,20 @@ const SGR_MOUSE_TAIL_RE = /^\[<\d+;\d+;\d+[Mm]$/;
75
75
  // "token is exactly one report" path.
76
76
  // eslint-disable-next-line no-control-regex
77
77
  const SGR_MOUSE_TAIL_PREFIX_RE = /^\[<\d+;\d+;\d+[Mm]/;
78
+ // True prefix of an SGR report body (`[<btn;col;row`), including the
79
+ // ambiguous 2/3-byte heads `[` and `[<`. Mirrors SGR_MOUSE_RE's grammar
80
+ // (three numeric params, final byte excluded) and MUST stay in sync with
81
+ // SGR_MOUSE_RE / parseMouseEvent() — the single SGR grammar source for this
82
+ // family. Only the provenance-gated head hold below uses it; the pre-existing
83
+ // `[<`+digits hold keeps SGR_MOUSE_PREFIX_RE.
84
+ const SGR_MOUSE_HEAD_PREFIX_RE = /^\[(?:<(?:\d+(?:;\d*){0,2})?)?$/;
85
+ // ADR-0007 D4: an ambiguous `[`/`ESC[` head may be claimed this long after a
86
+ // REAL mouse report (kind:'mouse') was parsed — the P2 evidence that the user
87
+ // is actually using the mouse. 5s is the initial value; on-device calibration
88
+ // may retune it (still bounded by the first-capture hold deadline below).
89
+ const MOUSE_REPORT_ACTIVITY_MS = 5000;
90
+ // ADR-0007 D5: gated head holds obey the family's 64-byte bound.
91
+ const MOUSE_HEAD_HOLD_MAX_LENGTH = 64;
78
92
  // How long a held SGR mouse prefix waits for its continuation before being
79
93
  // discarded. The hold sentinel re-arms App's 50ms flush timer, so the hold
80
94
  // faces a discard decision on every parse call — the lifetime is measured
@@ -1122,6 +1136,11 @@ export function parseMultipleKeypresses(prevState, input = '') {
1122
1136
  if (win32EscFlushedAt !== undefined && now - win32EscFlushedAt >= WIN32_INPUT_GRACE_MS) {
1123
1137
  win32EscFlushedAt = undefined;
1124
1138
  }
1139
+ // Tracks the win32 ESC-flush recovery below: a reconstructed `ESC` byte is
1140
+ // NOT transport evidence for the single-read `ESC[` claim (F-2) — the ESC
1141
+ // came from an earlier read's flush, i.e. exactly the two-stroke typing the
1142
+ // P2 gate exists for.
1143
+ let win32EscPrepended = false;
1125
1144
  // Same deadline discipline for the reply-prefix hold: first capture only,
1126
1145
  // checked on every call (not just on flush, so continuous input cannot
1127
1146
  // starve it), and released by resetting the tokenizer — bytes dropped, the
@@ -1138,8 +1157,10 @@ export function parseMultipleKeypresses(prevState, input = '') {
1138
1157
  // a missing introducer. Never capture arbitrary '['-led user text.
1139
1158
  if (prevState.mode !== 'IN_PASTE' && tokenizer.buffer() === '' &&
1140
1159
  /^\[(?:[\d;]|$)/.test(inputString) &&
1141
- (WIN32_INPUT_BODY_PREFIX_RE.test('\x1b' + inputString) || win32HoldAllowed))
1160
+ (WIN32_INPUT_BODY_PREFIX_RE.test('\x1b' + inputString) || win32HoldAllowed)) {
1142
1161
  inputString = '\x1b' + inputString;
1162
+ win32EscPrepended = true;
1163
+ }
1143
1164
  win32EscFlushedAt = undefined;
1144
1165
  }
1145
1166
  const pending = tokenizer.buffer();
@@ -1181,6 +1202,10 @@ export function parseMultipleKeypresses(prevState, input = '') {
1181
1202
  tokenizer.reset();
1182
1203
  deferFlush = false;
1183
1204
  }
1205
+ // Tokenizer buffer entering THIS call — captured before feed so the
1206
+ // single-read `ESC[` evidence below cannot be granted to a head whose ESC
1207
+ // or `[` was buffered by an earlier call.
1208
+ const pendingBeforeFeed = tokenizer.buffer();
1184
1209
  // First capture only: later flushes (App re-arms its timer while
1185
1210
  // `incomplete` is set) must not renew the deadline.
1186
1211
  if (deferFlush && claimsResponsePrefix)
@@ -1204,6 +1229,13 @@ export function parseMultipleKeypresses(prevState, input = '') {
1204
1229
  const tokens = isFlush
1205
1230
  ? deferFlush || releaseResponseHold ? [] : tokenizer.flush()
1206
1231
  : tokenizer.feed(inputString);
1232
+ // ADR-0007 D4 addendum (F-2): grant the ambiguous `ESC[` head P1-only claim
1233
+ // when both bytes were buffered inside this one non-flush read from an empty
1234
+ // buffer. Set here, consumed by the flush call that emits it, then cleared
1235
+ // (a flush feeds nothing). Cross-read accumulation leaves it unset → P2.
1236
+ const mouseHeadSingleRead = !isFlush && !win32EscPrepended && pendingBeforeFeed === '' && tokenizer.buffer() === '\x1b['
1237
+ ? '\x1b['
1238
+ : undefined;
1207
1239
  if (isFlush && !inPaste && tokens.some(token => token.value === '\x1b')) {
1208
1240
  win32EscFlushedAt = now;
1209
1241
  }
@@ -1270,16 +1302,81 @@ export function parseMultipleKeypresses(prevState, input = '') {
1270
1302
  // dropped rather than shown.
1271
1303
  if (carryTailAfterEscFlush === undefined)
1272
1304
  terminalResponseReattachTail = undefined;
1273
- // Hard deadline, checked at the top of EVERY call — not only on flush.
1274
- // Continuous input keeps cancelling and re-arming App's 50ms flush timer,
1275
- // so a flush-only check can starve while the user types: a hold past its
1276
- // grace would then still merge a late `;34M` (or plain digits) into a
1277
- // phantom report.
1278
- if (mouseTailHold !== undefined &&
1279
- Date.now() - (mouseTailHoldAt ?? 0) > MOUSE_TAIL_HOLD_GRACE_MS) {
1305
+ // Claim provenance of the current hold (see KeyParseState docs): true =
1306
+ // gated (RELEASE on expiry/overflow), false = legacy silent discard,
1307
+ // undefined = no hold.
1308
+ let mouseTailHoldReleasable = prevState.mouseTailHoldReleasable;
1309
+ let lastMouseReportAt = prevState.lastMouseReportAt;
1310
+ const clearMouseTailHold = () => {
1280
1311
  mouseTailHold = undefined;
1281
1312
  mouseTailHoldAt = undefined;
1282
- }
1313
+ mouseTailHoldReleasable = undefined;
1314
+ };
1315
+ // Evidence gate for the SGR head family (ADR-0007 D2/D4). App injects
1316
+ // mouseReportingActive on every processInput; absent keeps direct callers on
1317
+ // the pre-gate `[<`+digits hold, explicit `false` claims nothing, explicit
1318
+ // `true` also allows the ambiguous `[`/`[<` heads — with `[`/`ESC[` needing
1319
+ // a real report inside MOUSE_REPORT_ACTIVITY_MS (P2 evidence).
1320
+ const mouseClaim = prevState.mouseReportingActive === true
1321
+ ? 'gated'
1322
+ : prevState.mouseReportingActive === false
1323
+ ? 'closed'
1324
+ : 'legacy';
1325
+ const mouseReportActivityLive = () => lastMouseReportAt !== undefined &&
1326
+ now - lastMouseReportAt <= MOUSE_REPORT_ACTIVITY_MS;
1327
+ /**
1328
+ * Decide whether `body` (a token with any leading ESC stripped) is an SGR
1329
+ * report head this parser may hold. `undefined` = ordinary input (no claim);
1330
+ * otherwise `releasable` says whether invalidation RELEASES the bytes
1331
+ * (gated claim) or silently discards them (legacy shape-specific claim).
1332
+ * `singleReadHead` = the `ESC[` body was formed inside ONE read (transport
1333
+ * evidence, ADR-0007 D4 addendum) and therefore counts as P1 evidence.
1334
+ */
1335
+ const claimSgrHead = (body, singleReadHead = false) => {
1336
+ if (mouseClaim === 'closed')
1337
+ return undefined;
1338
+ if (SGR_MOUSE_PREFIX_RE.test(body))
1339
+ return { releasable: mouseClaim === 'gated' };
1340
+ // The ambiguous 1/2-byte heads exist only for the gated family; legacy
1341
+ // callers keep the pre-gate behavior (plain text).
1342
+ if (mouseClaim !== 'gated')
1343
+ return undefined;
1344
+ if (body === '[<')
1345
+ return { releasable: true };
1346
+ // `[`/`ESC[` (D4): without a recent real report this stays ordinary text
1347
+ // (the pre-fix Esc+`[` behavior) unless both bytes arrived in one read —
1348
+ // human two-stroke typing cannot do that (F-2).
1349
+ if (body === '[')
1350
+ return mouseReportActivityLive() || singleReadHead ? { releasable: true } : undefined;
1351
+ return undefined;
1352
+ };
1353
+ /**
1354
+ * Single invalidation/RELEASE entry (F-6): a gated hold is replayed as
1355
+ * ordinary keys in arrival order (ADR-0007 D5); a legacy hold keeps the
1356
+ * pre-gate silent discard. Every invalidation, including an unrelated
1357
+ * protocol boundary, funnels through here; only successful completion of
1358
+ * the held report clears it without replay.
1359
+ */
1360
+ const releaseHeldMouseHead = () => {
1361
+ if (mouseTailHold === undefined)
1362
+ return;
1363
+ if (mouseTailHoldReleasable === true)
1364
+ keys.push(parseKeypress(mouseTailHold));
1365
+ clearMouseTailHold();
1366
+ };
1367
+ /** Hard deadline + gated size bound, checked at the top of EVERY call. */
1368
+ const shouldReleaseHold = () => mouseTailHold !== undefined &&
1369
+ (now - (mouseTailHoldAt ?? 0) > MOUSE_TAIL_HOLD_GRACE_MS ||
1370
+ (mouseTailHoldReleasable === true &&
1371
+ mouseTailHold.length > MOUSE_HEAD_HOLD_MAX_LENGTH));
1372
+ // Hard deadline + size bound, checked at the top of EVERY call — not only on
1373
+ // flush. Continuous input keeps cancelling and re-arming App's 50ms flush
1374
+ // timer, so a flush-only check can starve while the user types: a hold past
1375
+ // its grace would then still merge a late `;34M` (or plain digits) into a
1376
+ // phantom report. A gated hold RELEASES its bytes as ordinary keys instead
1377
+ // of dropping them (ADR-0007 D5); legacy holds keep the pre-gate discard.
1378
+ if (shouldReleaseHold())
1379
+ releaseHeldMouseHead();
1283
1380
  // Mutable token queue: a text token that starts with the completion of
1284
1381
  // the CURRENT hold but carries trailing bytes is split in-place — the
1285
1382
  // completion tail is consumed now, the suffix is pushed back for the
@@ -1326,10 +1423,9 @@ export function parseMultipleKeypresses(prevState, input = '') {
1326
1423
  pasteBuffer = '';
1327
1424
  // Bracketed paste is a terminal-controlled mode: report bytes are
1328
1425
  // contiguous on the wire, so a held SGR prefix's report is dead
1329
- // once paste starts. Discard it — a late `;34M` arriving after the
1426
+ // once paste starts. Release it — a late `;34M` arriving after the
1330
1427
  // paste must not merge into a phantom press.
1331
- mouseTailHold = undefined;
1332
- mouseTailHoldAt = undefined;
1428
+ releaseHeldMouseHead();
1333
1429
  }
1334
1430
  else if (token.value === PASTE_END) {
1335
1431
  // Always emit a paste key, even for empty pastes. This allows
@@ -1340,8 +1436,7 @@ export function parseMultipleKeypresses(prevState, input = '') {
1340
1436
  pasteBuffer = '';
1341
1437
  // Paste end is a terminal protocol boundary too — a held SGR prefix
1342
1438
  // from before the paste cannot complete now.
1343
- mouseTailHold = undefined;
1344
- mouseTailHoldAt = undefined;
1439
+ releaseHeldMouseHead();
1345
1440
  }
1346
1441
  else if (inPaste) {
1347
1442
  // Sequences inside paste are treated as literal text
@@ -1354,8 +1449,7 @@ export function parseMultipleKeypresses(prevState, input = '') {
1354
1449
  // A fresh protocol record proves a held SGR prefix's report died:
1355
1450
  // report bytes are contiguous on the wire, so nothing may
1356
1451
  // interleave between a report's fragments.
1357
- mouseTailHold = undefined;
1358
- mouseTailHoldAt = undefined;
1452
+ releaseHeldMouseHead();
1359
1453
  // win32-input-mode record. null means a swallowed event (keyup,
1360
1454
  // bare modifier, orphaned surrogate) — the sequence is consumed
1361
1455
  // either way and never reaches the VT keypress parser.
@@ -1370,40 +1464,62 @@ export function parseMultipleKeypresses(prevState, input = '') {
1370
1464
  }
1371
1465
  else {
1372
1466
  // Fixed decision order (D6) for one complete token — see
1373
- // claimProtocolSequence: OSC 8 drop → terminal reply → mouse.
1374
- // SGR mouse comes first (1006); X10 (legacy 1000/1002 without SGR)
1375
- // is the compatibility fallback. Wheel falls through to
1376
- // parseKeypress, which turns it into a wheel key WITH the pointer
1377
- // coordinates for position-based routing.
1467
+ // claimProtocolSequence: OSC 8 drop (#1178) → terminal reply
1468
+ // (#1177) → mouse (SGR 1006 first, X10 as the legacy 1000/1002
1469
+ // fallback). This parser's SGR head-fragment claim family
1470
+ // (#1160/#1120) lives inside the mouse step, below the complete
1471
+ // claim, and never runs ahead of OSC 8 or a reply. Wheel falls
1472
+ // through to parseKeypress, which turns it into a wheel key WITH
1473
+ // the pointer coordinates for position-based routing.
1378
1474
  const claimed = claimProtocolSequence(token.value);
1379
1475
  if (claimed !== null) {
1380
1476
  // Any claim — drop, terminal reply or complete mouse report — is
1381
1477
  // a protocol boundary: a held prefix belongs to an older, dead
1382
- // report. Discard it BEFORE it can merge the next fragment into
1383
- // a phantom event.
1384
- mouseTailHold = undefined;
1385
- mouseTailHoldAt = undefined;
1478
+ // report. Release it BEFORE it can merge the next fragment into
1479
+ // a phantom event. A complete report also lights the P2 evidence
1480
+ // window for the ambiguous `[`/`ESC[` heads.
1481
+ if (claimed.kind === 'mouse')
1482
+ lastMouseReportAt = now;
1483
+ releaseHeldMouseHead();
1386
1484
  keys.push(claimed);
1387
1485
  }
1388
- else if (SGR_MOUSE_PREFIX_RE.test(token.value.replace(/^\x1b/, ''))) {
1389
- // Flush-truncated SGR mouse report: the tokenizer's flush
1390
- // emitted the buffered prefix (ESC still attached) as a
1391
- // sequence token. It is protocol bytes mid-report, not a key —
1392
- // strip the ESC, hold for the continuation (the text-token
1393
- // branch above completes it), and never let it fall through
1394
- // to parseKeypress, where it would leak into the prompt.
1395
- // A fresh prefix REPLACES any stale hold instead of appending:
1396
- // the new report's arrival proves the old one's tail never
1397
- // came (`[<0;18` + `[<64;…` concatenated parses as garbage).
1398
- mouseTailHold = token.value.replace(/^\x1b/, '');
1399
- mouseTailHoldAt = Date.now();
1400
- }
1401
1486
  else {
1402
- // Ordinary key sequence (arrows, function keys, …) — still an
1403
- // ESC protocol start, so a held prefix's report is dead.
1404
- mouseTailHold = undefined;
1405
- mouseTailHoldAt = undefined;
1406
- keys.push(parseKeypress(token.value));
1487
+ const head = token.value.replace(/^\x1b/, '');
1488
+ // F-2 transport evidence: `ESC[` buffered in ONE read (see
1489
+ // KeyParseState.mouseHeadSingleRead) grants the P1-only claim.
1490
+ const singleReadHead = token.value === '\x1b[' && prevState.mouseHeadSingleRead === token.value;
1491
+ const claim = claimSgrHead(head, singleReadHead);
1492
+ if (claim !== undefined &&
1493
+ (!claim.releasable || head.length <= MOUSE_HEAD_HOLD_MAX_LENGTH)) {
1494
+ // Flush-truncated SGR head: the tokenizer's flush emitted the
1495
+ // buffered head (ESC still attached) as a sequence token. It
1496
+ // is protocol bytes mid-report, not a key — strip the ESC,
1497
+ // hold for the continuation (the text-token branch below
1498
+ // completes it), and never let it fall through to
1499
+ // parseKeypress, where it would leak into the prompt.
1500
+ // A fresh head REPLACES any stale hold instead of appending:
1501
+ // the new report's arrival proves the old one's tail never
1502
+ // came (`[<0;18` + `[<64;…` concatenated parses as garbage).
1503
+ // F-1: a gated old hold is RELEASED first so its bytes are
1504
+ // neither dropped nor ordered after the new head's bytes.
1505
+ releaseHeldMouseHead();
1506
+ mouseTailHold = head;
1507
+ mouseTailHoldAt = now;
1508
+ mouseTailHoldReleasable = claim.releasable;
1509
+ }
1510
+ else if (claim !== undefined && claim.releasable) {
1511
+ // Over the gated 64B bound: release immediately — never hold,
1512
+ // never drop (ADR-0007 D5).
1513
+ releaseHeldMouseHead();
1514
+ keys.push(parseKeypress(head));
1515
+ }
1516
+ else {
1517
+ // Ordinary key sequence (arrows, function keys, …) — still an
1518
+ // ESC protocol start, so a held head's report is dead. F-1:
1519
+ // a gated hold is RELEASED in arrival order first.
1520
+ releaseHeldMouseHead();
1521
+ keys.push(parseKeypress(token.value));
1522
+ }
1407
1523
  }
1408
1524
  }
1409
1525
  }
@@ -1414,9 +1530,8 @@ export function parseMultipleKeypresses(prevState, input = '') {
1414
1530
  }
1415
1531
  else if (WIN32_INPUT_TAILS_RE.test(token.value)) {
1416
1532
  // Protocol bytes — a live SGR mouse report cannot contain them, so
1417
- // a held prefix's report is dead. Discard before recovering.
1418
- mouseTailHold = undefined;
1419
- mouseTailHoldAt = undefined;
1533
+ // a held prefix's report is dead. Release before recovering.
1534
+ releaseHeldMouseHead();
1420
1535
  terminalResponseReattachTail = undefined;
1421
1536
  // A delayed win32-input-mode continuation can arrive after App's
1422
1537
  // escape timer has already flushed its ESC prefix. Recover complete
@@ -1445,15 +1560,17 @@ export function parseMultipleKeypresses(prevState, input = '') {
1445
1560
  // a full [\x20-] range would match typed input like `[MAX]` batched
1446
1561
  // into one read and silently drop it as a phantom click.
1447
1562
  // Any older hold belongs to a DIFFERENT, dead report: a complete
1448
- // report's arrival proves its tail never came. Discard the stale
1563
+ // report's arrival proves its tail never came. Release the stale
1449
1564
  // hold and resynthesize this tail cleanly — concatenating them
1450
1565
  // (`ESC + hold + complete tail`) parses as garbage and leaks the
1451
1566
  // protocol bytes into the prompt as an ordinary key.
1452
- mouseTailHold = undefined;
1453
- mouseTailHoldAt = undefined;
1567
+ releaseHeldMouseHead();
1454
1568
  terminalResponseReattachTail = undefined;
1455
1569
  const resynthesized = '\x1b' + token.value;
1456
1570
  const mouse = parseMouseEvent(resynthesized);
1571
+ // A real report lights the P2 evidence window for ambiguous heads.
1572
+ if (mouse)
1573
+ lastMouseReportAt = now;
1457
1574
  keys.push(mouse ?? parseKeypress(resynthesized));
1458
1575
  }
1459
1576
  else if (mouseTailHold !== undefined &&
@@ -1476,81 +1593,109 @@ export function parseMultipleKeypresses(prevState, input = '') {
1476
1593
  tokenQueue.splice(qi + 1, 0, { type: 'text', value: suffix });
1477
1594
  }
1478
1595
  const resynthesized = '\x1b' + combined.slice(0, reportEnd);
1479
- mouseTailHold = undefined;
1480
- mouseTailHoldAt = undefined;
1596
+ clearMouseTailHold();
1481
1597
  const mouse = parseMouseEvent(resynthesized);
1598
+ // A real report lights the P2 evidence window for ambiguous heads.
1599
+ if (mouse)
1600
+ lastMouseReportAt = now;
1482
1601
  keys.push(mouse ?? parseKeypress(resynthesized));
1483
1602
  }
1484
- else if (SGR_MOUSE_PREFIX_RE.test(token.value) ||
1485
- // Continuation of an active hold: with the prefix already captured,
1486
- // the next fragment (`32;5M`'s leading digits, more params) is
1487
- // digits/semicolons — ambiguous with typing, so treat them as part
1488
- // of the in-flight report until the deadline. Completion uses the branch
1489
- // above first, so reaching here with a hold means still incomplete.
1490
- (mouseTailHold !== undefined && /^[\d;]*$/.test(token.value) && token.value !== '')) {
1491
- // Incomplete SGR mouse prefix: ConPTY split the report mid-sequence
1492
- // and the flush timer already released the buffered ESC prefix, so
1493
- // this text token carries protocol bytes, not typing. Hold it for
1494
- // the next chunk (which completes the tail — handled by the branch
1495
- // above via the combined `hold + value` check) instead of leaking
1496
- // into the prompt; the deadline check at the top of every call
1497
- // discards the hold once its grace expires. The regex demands `<` +
1498
- // digits, which no realistic typed text produces as a single text
1499
- // token.
1500
- terminalResponseReattachTail = undefined;
1501
- if (mouseTailHold === undefined)
1502
- mouseTailHoldAt = Date.now();
1503
- mouseTailHold = (mouseTailHold ?? '') + token.value;
1504
- }
1505
1603
  else {
1506
- // Ordinary typing while a hold is pending: text that can never
1507
- // continue an SGR report proves the held report died. Discard the
1508
- // stale hold so it cannot merge the NEXT fragment into a phantom event.
1509
- mouseTailHold = undefined;
1510
- mouseTailHoldAt = undefined;
1511
- // #796 re-attach + post-flush reassembly: put the flushed introducer
1512
- // back, then let the one reply-shape authority decide. A fragment
1513
- // held from an earlier call is joined with this token first, so a
1514
- // tail that is itself split again (`[?61;4;6` then `;14;21;22c`) is
1515
- // reassembled instead of falling into the prompt in pieces. A claim
1604
+ // #1177 terminal-reply re-attach runs first (decision order D6:
1605
+ // reply before mouse): the introducer ESC may already have been
1606
+ // flushed, so this text token — joined with any held fragment — may
1607
+ // be the rest of a reply. The one shape authority
1608
+ // (`claimExpectedResponseHead`) decides completeness, and a claim
1516
1609
  // needs BOTH a pending query of the matching expected type and a
1517
1610
  // shape that can still complete into it; anything else keeps the
1518
1611
  // token literal (AC-3) and drops a stale fragment rather than
1519
1612
  // leaking protocol bytes.
1520
- const candidate = (terminalResponseReattachTail ?? '') + token.value;
1521
- const claimed = mayRecoverTerminalResponseTail
1522
- ? claimExpectedResponseHead(candidate, expectedResponseTypes)
1613
+ const replyCandidate = (terminalResponseReattachTail ?? '') + token.value;
1614
+ const claimedResponse = mayRecoverTerminalResponseTail
1615
+ ? claimExpectedResponseHead(replyCandidate, expectedResponseTypes)
1523
1616
  : undefined;
1524
- if (claimed) {
1617
+ if (claimedResponse) {
1525
1618
  terminalResponseReattachTail = undefined;
1619
+ // A completed reply is a protocol boundary: a held SGR head's
1620
+ // report is dead (same caliber as the sequence-token reply path).
1621
+ releaseHeldMouseHead();
1526
1622
  keys.push({
1527
1623
  kind: 'response',
1528
- sequence: '\x1b' + candidate.slice(0, claimed.consumed),
1529
- response: claimed.response,
1624
+ sequence: '\x1b' + replyCandidate.slice(0, claimedResponse.consumed),
1625
+ response: claimedResponse.response,
1530
1626
  });
1531
1627
  // Trailing bytes beyond the completed reply are ordinary input
1532
1628
  // (the terminal batched the tail with the next keystrokes).
1533
- const suffix = candidate.slice(claimed.consumed);
1629
+ const suffix = replyCandidate.slice(claimedResponse.consumed);
1534
1630
  if (suffix)
1535
1631
  tokenQueue.splice(qi + 1, 0, { type: 'text', value: suffix });
1536
1632
  }
1537
- else if (mayRecoverTerminalResponseTail &&
1538
- candidate.length <= TERMINAL_RESPONSE_MAX_LENGTH &&
1539
- expectsResponseType('\x1b' + candidate, expectedResponseTypes)) {
1540
- // Still an open expected reply prefix — hold it for the next call.
1541
- terminalResponseReattachTail = candidate;
1542
- }
1543
1633
  else {
1544
- // The held fragment (if any) cannot be completed; drop it and give
1545
- // the fresh bytes their own chance to start a reply prefix.
1546
- terminalResponseReattachTail = undefined;
1547
- if (mayRecoverTerminalResponseTail &&
1634
+ const replyStillOpen = mayRecoverTerminalResponseTail &&
1635
+ replyCandidate.length <= TERMINAL_RESPONSE_MAX_LENGTH &&
1636
+ expectsResponseType('\x1b' + replyCandidate, expectedResponseTypes);
1637
+ const freshReplyPrefix = mayRecoverTerminalResponseTail &&
1548
1638
  token.value.length <= TERMINAL_RESPONSE_MAX_LENGTH &&
1549
- expectsResponseType('\x1b' + token.value, expectedResponseTypes)) {
1639
+ expectsResponseType('\x1b' + token.value, expectedResponseTypes);
1640
+ if (replyStillOpen) {
1641
+ // Still an open expected reply prefix — hold it for the next
1642
+ // call. The reply shape proves any held mouse report is dead, so
1643
+ // release the old mouse hold before claiming the reply.
1644
+ releaseHeldMouseHead();
1645
+ terminalResponseReattachTail = replyCandidate;
1646
+ }
1647
+ else if (freshReplyPrefix) {
1648
+ // The held fragment (if any) cannot be completed; drop it and
1649
+ // give the fresh bytes their own chance to start a reply prefix.
1650
+ // Again the reply claim releases any old mouse hold.
1651
+ releaseHeldMouseHead();
1550
1652
  terminalResponseReattachTail = token.value;
1551
1653
  }
1552
1654
  else {
1553
- keys.push(parseKeypress(token.value));
1655
+ // SGR head family: claim a fresh head, extend an active hold, or
1656
+ // pass ordinary text through. `claimSgrHead` pairs shape with
1657
+ // evidence; a hold only survives while `hold + token` remains a
1658
+ // legal head prefix (SGR_MOUSE_HEAD_PREFIX_RE, grammar-locked to
1659
+ // SGR_MOUSE_RE), so text that cannot continue it proves the held
1660
+ // report died.
1661
+ terminalResponseReattachTail = undefined;
1662
+ const combined = (mouseTailHold ?? '') + token.value;
1663
+ const claim = claimSgrHead(token.value);
1664
+ const canExtend = mouseTailHold !== undefined &&
1665
+ SGR_MOUSE_HEAD_PREFIX_RE.test(combined);
1666
+ if (canExtend &&
1667
+ (mouseTailHoldReleasable !== true ||
1668
+ combined.length <= MOUSE_HEAD_HOLD_MAX_LENGTH)) {
1669
+ // Continuation (`<` after a bare `[`, digits/semicolons after
1670
+ // `[<`): keep the FIRST-capture deadline — flushes must not
1671
+ // renew it.
1672
+ mouseTailHold = combined;
1673
+ }
1674
+ else if (claim !== undefined &&
1675
+ (!claim.releasable ||
1676
+ token.value.length <= MOUSE_HEAD_HOLD_MAX_LENGTH)) {
1677
+ // Incomplete SGR head arriving as a text token (ConPTY/SSH
1678
+ // split the report mid-sequence and the flush timer already
1679
+ // released the buffered ESC prefix): hold it for the next
1680
+ // chunk instead of leaking protocol bytes into the prompt. A
1681
+ // fresh head REPLACES any stale hold — two reports never
1682
+ // concatenate — so the deadline restarts from this capture.
1683
+ // F-1: a gated old hold is RELEASED first so its bytes are
1684
+ // replayed in arrival order, not dropped.
1685
+ releaseHeldMouseHead();
1686
+ mouseTailHold = token.value;
1687
+ mouseTailHoldAt = now;
1688
+ mouseTailHoldReleasable = claim.releasable;
1689
+ }
1690
+ else {
1691
+ // The open report is dead (text that cannot continue it) or
1692
+ // the gated 64B bound is exceeded: a gated hold RELEASES its
1693
+ // bytes in arrival order (ADR-0007 D5) so no user input is
1694
+ // dropped; legacy holds keep the pre-gate silent discard.
1695
+ // This token then passes through as ordinary typing.
1696
+ releaseHeldMouseHead();
1697
+ keys.push(parseKeypress(token.value));
1698
+ }
1554
1699
  }
1555
1700
  }
1556
1701
  }
@@ -1613,13 +1758,13 @@ export function parseMultipleKeypresses(prevState, input = '') {
1613
1758
  win32Protocol.held = [];
1614
1759
  win32Protocol.sequence = '';
1615
1760
  }
1616
- // A held SGR mouse prefix that never completed is discarded by the
1617
- // deadline check at the top of this call — on flush AND on ordinary
1618
- // input alike (continuous input starves flush-only checks). Discarded
1619
- // silently, never emitted as text: protocol bytes that reach the prompt
1620
- // as text are exactly the leak this hold exists to prevent. Partial
1621
- // recovery of the coords is not worth one more branch — a mouse event
1622
- // with guessed terminators would dispatch phantom clicks.
1761
+ // A held SGR mouse head that never completed expires in the deadline check
1762
+ // at the top of this call — on flush AND on ordinary input alike
1763
+ // (continuous input starves flush-only checks). A gated hold is RELEASED as
1764
+ // ordinary keys there (ADR-0007 D5: delayed but never dropped); a legacy
1765
+ // shape-specific hold keeps the pre-gate silent discard. Partial recovery
1766
+ // of the coords is not attempted — a mouse event with guessed terminators
1767
+ // would dispatch phantom clicks.
1623
1768
  // The reply-prefix hold lives only while the tokenizer still retains a
1624
1769
  // reply-shaped prefix: completion, release or reset all end it, so the
1625
1770
  // NEXT hold captures its own first-capture deadline.
@@ -1668,8 +1813,17 @@ export function parseMultipleKeypresses(prevState, input = '') {
1668
1813
  win32AltHighSurrogate: win32Ctx.altHigh,
1669
1814
  win32Paste,
1670
1815
  win32Protocol,
1816
+ // The host gate rides along as well: App replaces its state with this
1817
+ // object on every read, and re-injects the latest evidence each call.
1818
+ mouseReportingActive: prevState.mouseReportingActive,
1819
+ lastMouseReportAt,
1671
1820
  mouseTailHold,
1672
1821
  mouseTailHoldAt,
1822
+ mouseTailHoldReleasable,
1823
+ // Parser-internal transport evidence: set by the read that buffered the
1824
+ // head, consumed by the next call (the flush that emits `ESC[`), then
1825
+ // cleared because that call feeds nothing.
1826
+ mouseHeadSingleRead,
1673
1827
  terminalResponseHoldAt,
1674
1828
  terminalResponseReattachTail,
1675
1829
  // A fresh lone-Escape flush re-arms the window; otherwise the carried
@@ -1,7 +1,7 @@
1
1
  import type { DOMElement } from './dom.js';
2
2
  import type { Rectangle } from './layout/geometry.js';
3
3
  import type Output from './output.js';
4
- import type { Screen } from './screen.js';
4
+ import { type Screen } from './screen.js';
5
5
  import { type StyledSegment } from './squash-text-nodes.js';
6
6
  import type { Color } from './styles.js';
7
7
  /** Reset the per-frame layout-shift flag. */
@@ -1 +1 @@
1
- {"version":3,"file":"render-node-to-output.d.ts","sourceRoot":"","sources":["../../../src/ink/render-node-to-output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"render-node-to-output.d.ts","sourceRoot":"","sources":["../../../src/ink/render-node-to-output.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ import getMaxWidth from './get-max-width.js';
5
5
  import { LayoutDisplay, LayoutEdge } from './layout/node.js';
6
6
  import { nodeCache, pendingClears, textPaintCache } from './node-cache.js';
7
7
  import renderBorder from './render-border.js';
8
+ import { countPaintedFlankColumns } from './screen.js';
8
9
  import { squashTextNodesToSegments, } from './squash-text-nodes.js';
9
10
  import { isXtermJs } from './terminal.js';
10
11
  import { terminalImageSourceFromAttributes } from './terminal-image.js';
@@ -35,6 +36,14 @@ export function resetLayoutShifted() {
35
36
  export function didLayoutShift() {
36
37
  return layoutShifted;
37
38
  }
39
+ /**
40
+ * How many painted columns may live outside a scroll container's x-range
41
+ * (within the shifted rows) before the DECSTBM fast path is rejected in
42
+ * favor of the box-clipped full path: the hardware scroll displaces those
43
+ * columns and the diff must write every displaced cell back. Blank margins
44
+ * and the 1-2 column gutter rail qualify; a sibling split column does not.
45
+ */
46
+ const DECSTBM_MAX_FLANK_COLUMNS = 4;
38
47
  let scrollHint = null;
39
48
  // Rects of position:absolute nodes from the PREVIOUS frame, used by
40
49
  // ScrollBox's blit+shift third-pass repair (see usage site). Recorded at
@@ -673,7 +682,7 @@ function renderNodeToOutput(node, output, options) {
673
682
  // The sibling-overlap check is load-bearing: Yoga's pixel-grid rounding
674
683
  // can give a box h=0 while still leaving a row for it (next sibling at
675
684
  // y+1, not y). HelpV2's third shortcuts column hits this — skipping
676
- // unconditionally drops "ctrl + z to suspend" from /help output.
685
+ // unconditionally drops its last row from /help output.
677
686
  if (height === 0 && siblingSharesY(node, yogaNode)) {
678
687
  nodeCache.set(node, { x, y, width, height, top: yogaTop, opaque: paintsOwnRect(node) });
679
688
  node.dirty = false;
@@ -1210,14 +1219,35 @@ function renderNodeToOutput(node, output, options) {
1210
1219
  const delta = contentCached.y - contentY;
1211
1220
  const regionTop = Math.floor(y + contentYoga.getComputedTop());
1212
1221
  const regionBottom = regionTop + innerHeight - 1;
1213
- if (cached?.y === y &&
1222
+ // DECSTBM + SU/SD scroll WHOLE terminal rows — ANSI has no
1223
+ // column-scoped hardware scroll — while this fast path's edge
1224
+ // repaint covers only the box's own x-range. The model-side
1225
+ // shift below is therefore COLUMN-SCOPED to the box: the flanks
1226
+ // keep their correct cells in next.screen, log-update simulates
1227
+ // the hardware scroll on the previous frame full-width, and the
1228
+ // shift op's full-width damage makes the frame diff compare the
1229
+ // flank cells and write them back to the terminal. (Before that
1230
+ // scoping the model shift was full-width too, so prev and next
1231
+ // agreed on the displaced flanks, nothing repaired them, and the
1232
+ // damage stuck — the reported "scrolling the agents panel breaks
1233
+ // the divider seam and the chat column".) The flank repair costs
1234
+ // O(painted flank cells), so the hardware path is only worth it
1235
+ // while the flanks are near-empty (blank page margins, the 1-2
1236
+ // column gutter rail); a wide painted flank (a sibling column
1237
+ // while split) takes the full path below, which repaints the box
1238
+ // clipped to its own bounds.
1239
+ const flankColumns = prevScreen
1240
+ ? countPaintedFlankColumns(prevScreen, regionTop, regionBottom, Math.floor(x), Math.floor(x) + Math.floor(width))
1241
+ : Number.MAX_SAFE_INTEGER;
1242
+ const inBoxScroll = cached?.y === y &&
1214
1243
  cached.height === height &&
1215
1244
  innerHeight > 0 &&
1216
- Math.abs(delta) < innerHeight) {
1245
+ Math.abs(delta) < innerHeight;
1246
+ if (inBoxScroll && flankColumns <= DECSTBM_MAX_FLANK_COLUMNS) {
1217
1247
  hint = { top: regionTop, bottom: regionBottom, delta };
1218
1248
  scrollHint = hint;
1219
1249
  }
1220
- else {
1250
+ else if (!inBoxScroll) {
1221
1251
  layoutShifted = true;
1222
1252
  }
1223
1253
  }
@@ -1270,7 +1300,9 @@ function renderNodeToOutput(node, output, options) {
1270
1300
  const { top, bottom, delta } = hint;
1271
1301
  const w = Math.floor(width);
1272
1302
  output.blit(prevScreen, Math.floor(x), top, w, bottom - top + 1);
1273
- output.shift(top, bottom, delta);
1303
+ // Column-scoped: see the gate comment above. The terminal still
1304
+ // scrolls whole rows; the diff repairs the flanks.
1305
+ output.shift(top, bottom, delta, Math.floor(x), w);
1274
1306
  // Edge rows: new content entering the viewport.
1275
1307
  const edgeTop = delta > 0 ? bottom - delta + 1 : top;
1276
1308
  const edgeBottom = delta > 0 ? bottom : top - delta - 1;