@askdkc/dsh-cli 0.11.3

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 (1978) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +321 -0
  3. package/bin/dsh-tui.js +1366 -0
  4. package/cordis.patch.yml +482 -0
  5. package/cordis.yml +250 -0
  6. package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -0
  7. package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -0
  8. package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -0
  9. package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -0
  10. package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -0
  11. package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -0
  12. package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -0
  13. package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -0
  14. package/dsh-ecosystem-spec/registry/README.md +14 -0
  15. package/dsh-ecosystem-spec/registry/contracts/decision-events-v1alpha1.json +13 -0
  16. package/dsh-ecosystem-spec/registry/contracts/scene-v1alpha1.json +13 -0
  17. package/dsh-ecosystem-spec/registry/contracts/settings-section-v1alpha1.json +13 -0
  18. package/dsh-ecosystem-spec/registry/contracts/tui-channel-v1alpha1.json +30 -0
  19. package/dsh-ecosystem-spec/registry/contracts/workspace-provider-v1alpha1.json +6 -0
  20. package/dsh-ecosystem-spec/registry/host-descriptor.tui.example.json +56 -0
  21. package/dsh-ecosystem-spec/registry/permissions-0.1.json +13 -0
  22. package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -0
  23. package/dsh-ecosystem-spec/schemas/conformance-claim.schema.json +15 -0
  24. package/dsh-ecosystem-spec/schemas/effect-ledger-record.schema.json +16 -0
  25. package/dsh-ecosystem-spec/schemas/host-descriptor.schema.json +26 -0
  26. package/lib/types/activityPrefs.d.ts +63 -0
  27. package/lib/types/activityPrefs.d.ts.map +1 -0
  28. package/lib/types/activityPrefs.js +126 -0
  29. package/lib/types/adapter/channel/actions.d.ts +17 -0
  30. package/lib/types/adapter/channel/actions.d.ts.map +1 -0
  31. package/lib/types/adapter/channel/actions.js +28 -0
  32. package/lib/types/adapter/channel/consumer.d.ts +34 -0
  33. package/lib/types/adapter/channel/consumer.d.ts.map +1 -0
  34. package/lib/types/adapter/channel/consumer.js +87 -0
  35. package/lib/types/adapter/channel/features.d.ts +12 -0
  36. package/lib/types/adapter/channel/features.d.ts.map +1 -0
  37. package/lib/types/adapter/channel/features.js +41 -0
  38. package/lib/types/adapter/channel/host-registry.d.ts +40 -0
  39. package/lib/types/adapter/channel/host-registry.d.ts.map +1 -0
  40. package/lib/types/adapter/channel/host-registry.js +120 -0
  41. package/lib/types/adapter/channel/index.d.ts +22 -0
  42. package/lib/types/adapter/channel/index.d.ts.map +1 -0
  43. package/lib/types/adapter/channel/index.js +21 -0
  44. package/lib/types/adapter/channel/internal-token.d.ts +12 -0
  45. package/lib/types/adapter/channel/internal-token.d.ts.map +1 -0
  46. package/lib/types/adapter/channel/internal-token.js +11 -0
  47. package/lib/types/adapter/channel/plugins.d.ts +17 -0
  48. package/lib/types/adapter/channel/plugins.d.ts.map +1 -0
  49. package/lib/types/adapter/channel/plugins.js +47 -0
  50. package/lib/types/adapter/channel/projection.d.ts +15 -0
  51. package/lib/types/adapter/channel/projection.d.ts.map +1 -0
  52. package/lib/types/adapter/channel/projection.js +59 -0
  53. package/lib/types/adapter/channel/provider.d.ts +52 -0
  54. package/lib/types/adapter/channel/provider.d.ts.map +1 -0
  55. package/lib/types/adapter/channel/provider.js +231 -0
  56. package/lib/types/adapter/channel/read-view.d.ts +4 -0
  57. package/lib/types/adapter/channel/read-view.d.ts.map +1 -0
  58. package/lib/types/adapter/channel/read-view.js +132 -0
  59. package/lib/types/adapter/channel/session-projection.d.ts +56 -0
  60. package/lib/types/adapter/channel/session-projection.d.ts.map +1 -0
  61. package/lib/types/adapter/channel/session-projection.js +249 -0
  62. package/lib/types/adapter/channel/state.d.ts +11 -0
  63. package/lib/types/adapter/channel/state.d.ts.map +1 -0
  64. package/lib/types/adapter/channel/state.js +57 -0
  65. package/lib/types/adapter/channel/transcript.d.ts +15 -0
  66. package/lib/types/adapter/channel/transcript.d.ts.map +1 -0
  67. package/lib/types/adapter/channel/transcript.js +22 -0
  68. package/lib/types/adapter/channel/ui-policy.d.ts +109 -0
  69. package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -0
  70. package/lib/types/adapter/channel/ui-policy.js +170 -0
  71. package/lib/types/adapter/channel/ui.d.ts +16 -0
  72. package/lib/types/adapter/channel/ui.d.ts.map +1 -0
  73. package/lib/types/adapter/channel/ui.js +173 -0
  74. package/lib/types/adapter/index.d.ts +20 -0
  75. package/lib/types/adapter/index.d.ts.map +1 -0
  76. package/lib/types/adapter/index.js +19 -0
  77. package/lib/types/adapter/kernel/contract-catalog.d.ts +12 -0
  78. package/lib/types/adapter/kernel/contract-catalog.d.ts.map +1 -0
  79. package/lib/types/adapter/kernel/contract-catalog.js +11 -0
  80. package/lib/types/adapter/kernel/diagnostics.d.ts +18 -0
  81. package/lib/types/adapter/kernel/diagnostics.d.ts.map +1 -0
  82. package/lib/types/adapter/kernel/diagnostics.js +16 -0
  83. package/lib/types/adapter/kernel/driver-types.d.ts +16 -0
  84. package/lib/types/adapter/kernel/driver-types.d.ts.map +1 -0
  85. package/lib/types/adapter/kernel/driver-types.js +8 -0
  86. package/lib/types/adapter/kernel/host-facade.d.ts +65 -0
  87. package/lib/types/adapter/kernel/host-facade.d.ts.map +1 -0
  88. package/lib/types/adapter/kernel/host-facade.js +216 -0
  89. package/lib/types/adapter/kernel/host-probe-access.d.ts +71 -0
  90. package/lib/types/adapter/kernel/host-probe-access.d.ts.map +1 -0
  91. package/lib/types/adapter/kernel/host-probe-access.js +121 -0
  92. package/lib/types/adapter/kernel/index.d.ts +20 -0
  93. package/lib/types/adapter/kernel/index.d.ts.map +1 -0
  94. package/lib/types/adapter/kernel/index.js +19 -0
  95. package/lib/types/adapter/kernel/kernel-runtime.d.ts +138 -0
  96. package/lib/types/adapter/kernel/kernel-runtime.d.ts.map +1 -0
  97. package/lib/types/adapter/kernel/kernel-runtime.js +572 -0
  98. package/lib/types/adapter/kernel/ledger.d.ts +55 -0
  99. package/lib/types/adapter/kernel/ledger.d.ts.map +1 -0
  100. package/lib/types/adapter/kernel/ledger.js +33 -0
  101. package/lib/types/adapter/kernel/legacy-facade.d.ts +22 -0
  102. package/lib/types/adapter/kernel/legacy-facade.d.ts.map +1 -0
  103. package/lib/types/adapter/kernel/legacy-facade.js +34 -0
  104. package/lib/types/adapter/kernel/lifecycle.d.ts +38 -0
  105. package/lib/types/adapter/kernel/lifecycle.d.ts.map +1 -0
  106. package/lib/types/adapter/kernel/lifecycle.js +53 -0
  107. package/lib/types/adapter/kernel/replay-isolation.d.ts +27 -0
  108. package/lib/types/adapter/kernel/replay-isolation.d.ts.map +1 -0
  109. package/lib/types/adapter/kernel/replay-isolation.js +45 -0
  110. package/lib/types/adapter/kernel/replay.d.ts +132 -0
  111. package/lib/types/adapter/kernel/replay.d.ts.map +1 -0
  112. package/lib/types/adapter/kernel/replay.js +428 -0
  113. package/lib/types/adapter/kernel/runtime-context.d.ts +15 -0
  114. package/lib/types/adapter/kernel/runtime-context.d.ts.map +1 -0
  115. package/lib/types/adapter/kernel/runtime-context.js +24 -0
  116. package/lib/types/adapter/kernel/runtime.d.ts +70 -0
  117. package/lib/types/adapter/kernel/runtime.d.ts.map +1 -0
  118. package/lib/types/adapter/kernel/runtime.js +327 -0
  119. package/lib/types/adapter/kernel/slices/channel.d.ts +3 -0
  120. package/lib/types/adapter/kernel/slices/channel.d.ts.map +1 -0
  121. package/lib/types/adapter/kernel/slices/channel.js +8 -0
  122. package/lib/types/adapter/kernel/slices/decisions.d.ts +3 -0
  123. package/lib/types/adapter/kernel/slices/decisions.d.ts.map +1 -0
  124. package/lib/types/adapter/kernel/slices/decisions.js +10 -0
  125. package/lib/types/adapter/kernel/slices/extensions.d.ts +8 -0
  126. package/lib/types/adapter/kernel/slices/extensions.d.ts.map +1 -0
  127. package/lib/types/adapter/kernel/slices/extensions.js +43 -0
  128. package/lib/types/adapter/kernel/slices/index.d.ts +19 -0
  129. package/lib/types/adapter/kernel/slices/index.d.ts.map +1 -0
  130. package/lib/types/adapter/kernel/slices/index.js +36 -0
  131. package/lib/types/adapter/kernel/slices/presentation.d.ts +3 -0
  132. package/lib/types/adapter/kernel/slices/presentation.d.ts.map +1 -0
  133. package/lib/types/adapter/kernel/slices/presentation.js +14 -0
  134. package/lib/types/adapter/kernel/slices/scenes.d.ts +3 -0
  135. package/lib/types/adapter/kernel/slices/scenes.d.ts.map +1 -0
  136. package/lib/types/adapter/kernel/slices/scenes.js +14 -0
  137. package/lib/types/adapter/kernel/slices/settings.d.ts +3 -0
  138. package/lib/types/adapter/kernel/slices/settings.d.ts.map +1 -0
  139. package/lib/types/adapter/kernel/slices/settings.js +12 -0
  140. package/lib/types/adapter/kernel/slices/types.d.ts +20 -0
  141. package/lib/types/adapter/kernel/slices/types.d.ts.map +1 -0
  142. package/lib/types/adapter/kernel/slices/types.js +12 -0
  143. package/lib/types/adapter/kernel/slices/workspace.d.ts +3 -0
  144. package/lib/types/adapter/kernel/slices/workspace.d.ts.map +1 -0
  145. package/lib/types/adapter/kernel/slices/workspace.js +16 -0
  146. package/lib/types/adapter/ports/channel-catalog.d.ts +90 -0
  147. package/lib/types/adapter/ports/channel-catalog.d.ts.map +1 -0
  148. package/lib/types/adapter/ports/channel-catalog.js +2 -0
  149. package/lib/types/adapter/ports/channel-display.d.ts +90 -0
  150. package/lib/types/adapter/ports/channel-display.d.ts.map +1 -0
  151. package/lib/types/adapter/ports/channel-display.js +2 -0
  152. package/lib/types/adapter/ports/channel-session.d.ts +229 -0
  153. package/lib/types/adapter/ports/channel-session.d.ts.map +1 -0
  154. package/lib/types/adapter/ports/channel-session.js +2 -0
  155. package/lib/types/adapter/ports/channel-settings.d.ts +279 -0
  156. package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -0
  157. package/lib/types/adapter/ports/channel-settings.js +1 -0
  158. package/lib/types/adapter/ports/channel-ui.d.ts +593 -0
  159. package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -0
  160. package/lib/types/adapter/ports/channel-ui.js +1 -0
  161. package/lib/types/adapter/ports/channel-view.d.ts +663 -0
  162. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -0
  163. package/lib/types/adapter/ports/channel-view.js +2 -0
  164. package/lib/types/adapter/ports/channel-workspace.d.ts +68 -0
  165. package/lib/types/adapter/ports/channel-workspace.d.ts.map +1 -0
  166. package/lib/types/adapter/ports/channel-workspace.js +2 -0
  167. package/lib/types/adapter/ports/channel.d.ts +148 -0
  168. package/lib/types/adapter/ports/channel.d.ts.map +1 -0
  169. package/lib/types/adapter/ports/channel.js +22 -0
  170. package/lib/types/adapter/ports/decisions.d.ts +18 -0
  171. package/lib/types/adapter/ports/decisions.d.ts.map +1 -0
  172. package/lib/types/adapter/ports/decisions.js +9 -0
  173. package/lib/types/adapter/ports/descriptor.d.ts +25 -0
  174. package/lib/types/adapter/ports/descriptor.d.ts.map +1 -0
  175. package/lib/types/adapter/ports/descriptor.js +11 -0
  176. package/lib/types/adapter/ports/extensions.d.ts +86 -0
  177. package/lib/types/adapter/ports/extensions.d.ts.map +1 -0
  178. package/lib/types/adapter/ports/extensions.js +9 -0
  179. package/lib/types/adapter/ports/index.d.ts +23 -0
  180. package/lib/types/adapter/ports/index.d.ts.map +1 -0
  181. package/lib/types/adapter/ports/index.js +14 -0
  182. package/lib/types/adapter/ports/owner.d.ts +19 -0
  183. package/lib/types/adapter/ports/owner.d.ts.map +1 -0
  184. package/lib/types/adapter/ports/owner.js +9 -0
  185. package/lib/types/adapter/ports/presentation.d.ts +81 -0
  186. package/lib/types/adapter/ports/presentation.d.ts.map +1 -0
  187. package/lib/types/adapter/ports/presentation.js +10 -0
  188. package/lib/types/adapter/ports/scenes.d.ts +24 -0
  189. package/lib/types/adapter/ports/scenes.d.ts.map +1 -0
  190. package/lib/types/adapter/ports/scenes.js +8 -0
  191. package/lib/types/adapter/ports/settings.d.ts +44 -0
  192. package/lib/types/adapter/ports/settings.d.ts.map +1 -0
  193. package/lib/types/adapter/ports/settings.js +9 -0
  194. package/lib/types/adapter/ports/workspace.d.ts +62 -0
  195. package/lib/types/adapter/ports/workspace.d.ts.map +1 -0
  196. package/lib/types/adapter/ports/workspace.js +8 -0
  197. package/lib/types/adapter/spec/index.d.ts +11 -0
  198. package/lib/types/adapter/spec/index.d.ts.map +1 -0
  199. package/lib/types/adapter/spec/index.js +10 -0
  200. package/lib/types/adapter/spec/profile.d.ts +10 -0
  201. package/lib/types/adapter/spec/profile.d.ts.map +1 -0
  202. package/lib/types/adapter/spec/profile.js +9 -0
  203. package/lib/types/adapter/spec/protocol-constants.d.ts +60 -0
  204. package/lib/types/adapter/spec/protocol-constants.d.ts.map +1 -0
  205. package/lib/types/adapter/spec/protocol-constants.js +129 -0
  206. package/lib/types/adapter/spec/tui-contributions.d.ts +18 -0
  207. package/lib/types/adapter/spec/tui-contributions.d.ts.map +1 -0
  208. package/lib/types/adapter/spec/tui-contributions.js +19 -0
  209. package/lib/types/adapter/standard/admission.d.ts +11 -0
  210. package/lib/types/adapter/standard/admission.d.ts.map +1 -0
  211. package/lib/types/adapter/standard/admission.js +10 -0
  212. package/lib/types/adapter/standard/descriptor.d.ts +74 -0
  213. package/lib/types/adapter/standard/descriptor.d.ts.map +1 -0
  214. package/lib/types/adapter/standard/descriptor.js +356 -0
  215. package/lib/types/adapter/standard/grants.d.ts +30 -0
  216. package/lib/types/adapter/standard/grants.d.ts.map +1 -0
  217. package/lib/types/adapter/standard/grants.js +219 -0
  218. package/lib/types/adapter/standard/index.d.ts +25 -0
  219. package/lib/types/adapter/standard/index.d.ts.map +1 -0
  220. package/lib/types/adapter/standard/index.js +24 -0
  221. package/lib/types/adapter/standard/negotiate.d.ts +11 -0
  222. package/lib/types/adapter/standard/negotiate.d.ts.map +1 -0
  223. package/lib/types/adapter/standard/negotiate.js +97 -0
  224. package/lib/types/adapter/standard/permission-scope.d.ts +27 -0
  225. package/lib/types/adapter/standard/permission-scope.d.ts.map +1 -0
  226. package/lib/types/adapter/standard/permission-scope.js +68 -0
  227. package/lib/types/adapter/standard/protocols.d.ts +12 -0
  228. package/lib/types/adapter/standard/protocols.d.ts.map +1 -0
  229. package/lib/types/adapter/standard/protocols.js +11 -0
  230. package/lib/types/adapter/standard/registry.d.ts +23 -0
  231. package/lib/types/adapter/standard/registry.d.ts.map +1 -0
  232. package/lib/types/adapter/standard/registry.js +240 -0
  233. package/lib/types/adapter/standard/schema-check.d.ts +17 -0
  234. package/lib/types/adapter/standard/schema-check.d.ts.map +1 -0
  235. package/lib/types/adapter/standard/schema-check.js +167 -0
  236. package/lib/types/adapter/standard/tui-extension.d.ts +25 -0
  237. package/lib/types/adapter/standard/tui-extension.d.ts.map +1 -0
  238. package/lib/types/adapter/standard/tui-extension.js +45 -0
  239. package/lib/types/adapter/standard/types.d.ts +108 -0
  240. package/lib/types/adapter/standard/types.d.ts.map +1 -0
  241. package/lib/types/adapter/standard/types.js +10 -0
  242. package/lib/types/adapter/standard/validate.d.ts +21 -0
  243. package/lib/types/adapter/standard/validate.d.ts.map +1 -0
  244. package/lib/types/adapter/standard/validate.js +139 -0
  245. package/lib/types/adapter/upstream/channel-driver.d.ts +22 -0
  246. package/lib/types/adapter/upstream/channel-driver.d.ts.map +1 -0
  247. package/lib/types/adapter/upstream/channel-driver.js +424 -0
  248. package/lib/types/adapter/upstream/decisions-driver.d.ts +15 -0
  249. package/lib/types/adapter/upstream/decisions-driver.d.ts.map +1 -0
  250. package/lib/types/adapter/upstream/decisions-driver.js +141 -0
  251. package/lib/types/adapter/upstream/detection.d.ts +26 -0
  252. package/lib/types/adapter/upstream/detection.d.ts.map +1 -0
  253. package/lib/types/adapter/upstream/detection.js +9 -0
  254. package/lib/types/adapter/upstream/driver.d.ts +50 -0
  255. package/lib/types/adapter/upstream/driver.d.ts.map +1 -0
  256. package/lib/types/adapter/upstream/driver.js +8 -0
  257. package/lib/types/adapter/upstream/extensions-driver.d.ts +24 -0
  258. package/lib/types/adapter/upstream/extensions-driver.d.ts.map +1 -0
  259. package/lib/types/adapter/upstream/extensions-driver.js +697 -0
  260. package/lib/types/adapter/upstream/host-descriptor-driver.d.ts +45 -0
  261. package/lib/types/adapter/upstream/host-descriptor-driver.d.ts.map +1 -0
  262. package/lib/types/adapter/upstream/host-descriptor-driver.js +606 -0
  263. package/lib/types/adapter/upstream/index.d.ts +18 -0
  264. package/lib/types/adapter/upstream/index.d.ts.map +1 -0
  265. package/lib/types/adapter/upstream/index.js +15 -0
  266. package/lib/types/adapter/upstream/presentation-driver.d.ts +17 -0
  267. package/lib/types/adapter/upstream/presentation-driver.d.ts.map +1 -0
  268. package/lib/types/adapter/upstream/presentation-driver.js +129 -0
  269. package/lib/types/adapter/upstream/scenes-driver.d.ts +18 -0
  270. package/lib/types/adapter/upstream/scenes-driver.d.ts.map +1 -0
  271. package/lib/types/adapter/upstream/scenes-driver.js +170 -0
  272. package/lib/types/adapter/upstream/settings-driver.d.ts +20 -0
  273. package/lib/types/adapter/upstream/settings-driver.d.ts.map +1 -0
  274. package/lib/types/adapter/upstream/settings-driver.js +173 -0
  275. package/lib/types/adapter/upstream/workspace-driver.d.ts +19 -0
  276. package/lib/types/adapter/upstream/workspace-driver.d.ts.map +1 -0
  277. package/lib/types/adapter/upstream/workspace-driver.js +198 -0
  278. package/lib/types/api.d.ts +7 -0
  279. package/lib/types/api.d.ts.map +1 -0
  280. package/lib/types/api.js +1 -0
  281. package/lib/types/bootstrap/state.d.ts +11 -0
  282. package/lib/types/bootstrap/state.d.ts.map +1 -0
  283. package/lib/types/bootstrap/state.js +10 -0
  284. package/lib/types/command-trees.d.ts +4 -0
  285. package/lib/types/command-trees.d.ts.map +1 -0
  286. package/lib/types/command-trees.js +4 -0
  287. package/lib/types/commands.d.ts +87 -0
  288. package/lib/types/commands.d.ts.map +1 -0
  289. package/lib/types/commands.js +218 -0
  290. package/lib/types/components/ActivityLine.d.ts +34 -0
  291. package/lib/types/components/ActivityLine.d.ts.map +1 -0
  292. package/lib/types/components/ActivityLine.js +39 -0
  293. package/lib/types/components/ActivityPicker.d.ts +16 -0
  294. package/lib/types/components/ActivityPicker.d.ts.map +1 -0
  295. package/lib/types/components/ActivityPicker.js +23 -0
  296. package/lib/types/components/AutoRecapRow.d.ts +23 -0
  297. package/lib/types/components/AutoRecapRow.d.ts.map +1 -0
  298. package/lib/types/components/AutoRecapRow.js +23 -0
  299. package/lib/types/components/BalanceReportRow.d.ts +24 -0
  300. package/lib/types/components/BalanceReportRow.d.ts.map +1 -0
  301. package/lib/types/components/BalanceReportRow.js +87 -0
  302. package/lib/types/components/BtwPanel.d.ts +16 -0
  303. package/lib/types/components/BtwPanel.d.ts.map +1 -0
  304. package/lib/types/components/BtwPanel.js +47 -0
  305. package/lib/types/components/Chat/JobCard.d.ts +23 -0
  306. package/lib/types/components/Chat/JobCard.d.ts.map +1 -0
  307. package/lib/types/components/Chat/JobCard.js +93 -0
  308. package/lib/types/components/Chat/SubagentMessage.d.ts +20 -0
  309. package/lib/types/components/Chat/SubagentMessage.d.ts.map +1 -0
  310. package/lib/types/components/Chat/SubagentMessage.js +83 -0
  311. package/lib/types/components/ColorPicker.d.ts +17 -0
  312. package/lib/types/components/ColorPicker.d.ts.map +1 -0
  313. package/lib/types/components/ColorPicker.js +20 -0
  314. package/lib/types/components/CommandSuggestions.d.ts +34 -0
  315. package/lib/types/components/CommandSuggestions.d.ts.map +1 -0
  316. package/lib/types/components/CommandSuggestions.js +61 -0
  317. package/lib/types/components/ContextBarView.d.ts +41 -0
  318. package/lib/types/components/ContextBarView.d.ts.map +1 -0
  319. package/lib/types/components/ContextBarView.js +50 -0
  320. package/lib/types/components/EffortChargeGlyph.d.ts +26 -0
  321. package/lib/types/components/EffortChargeGlyph.d.ts.map +1 -0
  322. package/lib/types/components/EffortChargeGlyph.js +70 -0
  323. package/lib/types/components/EffortInputBorder.d.ts +47 -0
  324. package/lib/types/components/EffortInputBorder.d.ts.map +1 -0
  325. package/lib/types/components/EffortInputBorder.js +90 -0
  326. package/lib/types/components/EffortSlider.d.ts +18 -0
  327. package/lib/types/components/EffortSlider.d.ts.map +1 -0
  328. package/lib/types/components/EffortSlider.js +19 -0
  329. package/lib/types/components/EffortTierBadge.d.ts +26 -0
  330. package/lib/types/components/EffortTierBadge.d.ts.map +1 -0
  331. package/lib/types/components/EffortTierBadge.js +97 -0
  332. package/lib/types/components/ExtensionDialog.d.ts +40 -0
  333. package/lib/types/components/ExtensionDialog.d.ts.map +1 -0
  334. package/lib/types/components/ExtensionDialog.js +253 -0
  335. package/lib/types/components/FileActionsPanel.d.ts +22 -0
  336. package/lib/types/components/FileActionsPanel.d.ts.map +1 -0
  337. package/lib/types/components/FileActionsPanel.js +28 -0
  338. package/lib/types/components/FileSuggestions.d.ts +18 -0
  339. package/lib/types/components/FileSuggestions.d.ts.map +1 -0
  340. package/lib/types/components/FileSuggestions.js +78 -0
  341. package/lib/types/components/GoalTodoPanel.d.ts +38 -0
  342. package/lib/types/components/GoalTodoPanel.d.ts.map +1 -0
  343. package/lib/types/components/GoalTodoPanel.js +131 -0
  344. package/lib/types/components/HelpMenu.d.ts +29 -0
  345. package/lib/types/components/HelpMenu.d.ts.map +1 -0
  346. package/lib/types/components/HelpMenu.js +39 -0
  347. package/lib/types/components/HistorySearchDialog.d.ts +18 -0
  348. package/lib/types/components/HistorySearchDialog.d.ts.map +1 -0
  349. package/lib/types/components/HistorySearchDialog.js +47 -0
  350. package/lib/types/components/ImagePreviewOverlay.d.ts +51 -0
  351. package/lib/types/components/ImagePreviewOverlay.d.ts.map +1 -0
  352. package/lib/types/components/ImagePreviewOverlay.js +269 -0
  353. package/lib/types/components/JobsPanel.d.ts +17 -0
  354. package/lib/types/components/JobsPanel.d.ts.map +1 -0
  355. package/lib/types/components/JobsPanel.js +111 -0
  356. package/lib/types/components/LangPicker.d.ts +14 -0
  357. package/lib/types/components/LangPicker.d.ts.map +1 -0
  358. package/lib/types/components/LangPicker.js +17 -0
  359. package/lib/types/components/LoadedContextPanel.d.ts +20 -0
  360. package/lib/types/components/LoadedContextPanel.d.ts.map +1 -0
  361. package/lib/types/components/LoadedContextPanel.js +32 -0
  362. package/lib/types/components/LogoV2.d.ts +48 -0
  363. package/lib/types/components/LogoV2.d.ts.map +1 -0
  364. package/lib/types/components/LogoV2.js +239 -0
  365. package/lib/types/components/Markdown.d.ts +46 -0
  366. package/lib/types/components/Markdown.d.ts.map +1 -0
  367. package/lib/types/components/Markdown.js +178 -0
  368. package/lib/types/components/MarkdownTable.d.ts +13 -0
  369. package/lib/types/components/MarkdownTable.d.ts.map +1 -0
  370. package/lib/types/components/MarkdownTable.js +155 -0
  371. package/lib/types/components/MermaidDiagram.d.ts +13 -0
  372. package/lib/types/components/MermaidDiagram.d.ts.map +1 -0
  373. package/lib/types/components/MermaidDiagram.js +61 -0
  374. package/lib/types/components/MessageList.d.ts +144 -0
  375. package/lib/types/components/MessageList.d.ts.map +1 -0
  376. package/lib/types/components/MessageList.js +1170 -0
  377. package/lib/types/components/MigratePicker.d.ts +30 -0
  378. package/lib/types/components/MigratePicker.d.ts.map +1 -0
  379. package/lib/types/components/MigratePicker.js +38 -0
  380. package/lib/types/components/ModelPicker.d.ts +42 -0
  381. package/lib/types/components/ModelPicker.d.ts.map +1 -0
  382. package/lib/types/components/ModelPicker.js +51 -0
  383. package/lib/types/components/OverlayAbove.d.ts +48 -0
  384. package/lib/types/components/OverlayAbove.d.ts.map +1 -0
  385. package/lib/types/components/OverlayAbove.js +98 -0
  386. package/lib/types/components/PageMargin.d.ts +58 -0
  387. package/lib/types/components/PageMargin.d.ts.map +1 -0
  388. package/lib/types/components/PageMargin.js +38 -0
  389. package/lib/types/components/PermissionsPicker.d.ts +20 -0
  390. package/lib/types/components/PermissionsPicker.d.ts.map +1 -0
  391. package/lib/types/components/PermissionsPicker.js +33 -0
  392. package/lib/types/components/PlanPicker.d.ts +15 -0
  393. package/lib/types/components/PlanPicker.d.ts.map +1 -0
  394. package/lib/types/components/PlanPicker.js +18 -0
  395. package/lib/types/components/PluginSceneBoundary.d.ts +31 -0
  396. package/lib/types/components/PluginSceneBoundary.d.ts.map +1 -0
  397. package/lib/types/components/PluginSceneBoundary.js +29 -0
  398. package/lib/types/components/PluginStatusViewBoundary.d.ts +26 -0
  399. package/lib/types/components/PluginStatusViewBoundary.d.ts.map +1 -0
  400. package/lib/types/components/PluginStatusViewBoundary.js +22 -0
  401. package/lib/types/components/PresetPicker.d.ts +20 -0
  402. package/lib/types/components/PresetPicker.d.ts.map +1 -0
  403. package/lib/types/components/PresetPicker.js +24 -0
  404. package/lib/types/components/PromptEditor.d.ts +48 -0
  405. package/lib/types/components/PromptEditor.d.ts.map +1 -0
  406. package/lib/types/components/PromptEditor.js +75 -0
  407. package/lib/types/components/PromptInput.d.ts +163 -0
  408. package/lib/types/components/PromptInput.d.ts.map +1 -0
  409. package/lib/types/components/PromptInput.js +3503 -0
  410. package/lib/types/components/RecapPanel.d.ts +25 -0
  411. package/lib/types/components/RecapPanel.d.ts.map +1 -0
  412. package/lib/types/components/RecapPanel.js +55 -0
  413. package/lib/types/components/RewindPicker.d.ts +37 -0
  414. package/lib/types/components/RewindPicker.d.ts.map +1 -0
  415. package/lib/types/components/RewindPicker.js +66 -0
  416. package/lib/types/components/ScrollbarGutter.d.ts +43 -0
  417. package/lib/types/components/ScrollbarGutter.d.ts.map +1 -0
  418. package/lib/types/components/ScrollbarGutter.js +197 -0
  419. package/lib/types/components/SearchBox.d.ts +24 -0
  420. package/lib/types/components/SearchBox.d.ts.map +1 -0
  421. package/lib/types/components/SearchBox.js +132 -0
  422. package/lib/types/components/Select.d.ts +29 -0
  423. package/lib/types/components/Select.d.ts.map +1 -0
  424. package/lib/types/components/Select.js +21 -0
  425. package/lib/types/components/SkillsPicker.d.ts +21 -0
  426. package/lib/types/components/SkillsPicker.d.ts.map +1 -0
  427. package/lib/types/components/SkillsPicker.js +52 -0
  428. package/lib/types/components/Spinner/GlimmerMessage.d.ts +16 -0
  429. package/lib/types/components/Spinner/GlimmerMessage.d.ts.map +1 -0
  430. package/lib/types/components/Spinner/GlimmerMessage.js +57 -0
  431. package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts +33 -0
  432. package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts.map +1 -0
  433. package/lib/types/components/Spinner/SpinnerAnimationRow.js +168 -0
  434. package/lib/types/components/Spinner/SpinnerGlyph.d.ts +16 -0
  435. package/lib/types/components/Spinner/SpinnerGlyph.d.ts.map +1 -0
  436. package/lib/types/components/Spinner/SpinnerGlyph.js +36 -0
  437. package/lib/types/components/Spinner/spinnerMode.d.ts +2 -0
  438. package/lib/types/components/Spinner/spinnerMode.d.ts.map +1 -0
  439. package/lib/types/components/Spinner/spinnerMode.js +1 -0
  440. package/lib/types/components/Spinner/spinnerUtils.d.ts +36 -0
  441. package/lib/types/components/Spinner/spinnerUtils.d.ts.map +1 -0
  442. package/lib/types/components/Spinner/spinnerUtils.js +94 -0
  443. package/lib/types/components/Spinner/useStalledAnimation.d.ts +16 -0
  444. package/lib/types/components/Spinner/useStalledAnimation.d.ts.map +1 -0
  445. package/lib/types/components/Spinner/useStalledAnimation.js +52 -0
  446. package/lib/types/components/SplitDiffView.d.ts +25 -0
  447. package/lib/types/components/SplitDiffView.d.ts.map +1 -0
  448. package/lib/types/components/SplitDiffView.js +279 -0
  449. package/lib/types/components/StreamingMarkdown.d.ts +6 -0
  450. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -0
  451. package/lib/types/components/StreamingMarkdown.js +279 -0
  452. package/lib/types/components/SubagentCard.d.ts +10 -0
  453. package/lib/types/components/SubagentCard.d.ts.map +1 -0
  454. package/lib/types/components/SubagentCard.js +39 -0
  455. package/lib/types/components/SubagentDashboard.d.ts +17 -0
  456. package/lib/types/components/SubagentDashboard.d.ts.map +1 -0
  457. package/lib/types/components/SubagentDashboard.js +58 -0
  458. package/lib/types/components/SubagentDetailScene.d.ts +16 -0
  459. package/lib/types/components/SubagentDetailScene.d.ts.map +1 -0
  460. package/lib/types/components/SubagentDetailScene.js +147 -0
  461. package/lib/types/components/SuggestionCard.d.ts +65 -0
  462. package/lib/types/components/SuggestionCard.d.ts.map +1 -0
  463. package/lib/types/components/SuggestionCard.js +77 -0
  464. package/lib/types/components/SyntaxText.d.ts +15 -0
  465. package/lib/types/components/SyntaxText.d.ts.map +1 -0
  466. package/lib/types/components/SyntaxText.js +34 -0
  467. package/lib/types/components/ThemePicker.d.ts +27 -0
  468. package/lib/types/components/ThemePicker.d.ts.map +1 -0
  469. package/lib/types/components/ThemePicker.js +55 -0
  470. package/lib/types/components/ThinkingToggle.d.ts +13 -0
  471. package/lib/types/components/ThinkingToggle.d.ts.map +1 -0
  472. package/lib/types/components/ThinkingToggle.js +25 -0
  473. package/lib/types/components/TimelineRail.d.ts +53 -0
  474. package/lib/types/components/TimelineRail.d.ts.map +1 -0
  475. package/lib/types/components/TimelineRail.js +197 -0
  476. package/lib/types/components/TipsPanel.d.ts +14 -0
  477. package/lib/types/components/TipsPanel.d.ts.map +1 -0
  478. package/lib/types/components/TipsPanel.js +37 -0
  479. package/lib/types/components/ToolUseLoader.d.ts +18 -0
  480. package/lib/types/components/ToolUseLoader.d.ts.map +1 -0
  481. package/lib/types/components/ToolUseLoader.js +51 -0
  482. package/lib/types/components/Tooltip.d.ts +67 -0
  483. package/lib/types/components/Tooltip.d.ts.map +1 -0
  484. package/lib/types/components/Tooltip.js +266 -0
  485. package/lib/types/components/TurnInterruptedRow.d.ts +6 -0
  486. package/lib/types/components/TurnInterruptedRow.d.ts.map +1 -0
  487. package/lib/types/components/TurnInterruptedRow.js +9 -0
  488. package/lib/types/components/Whale.d.ts +42 -0
  489. package/lib/types/components/Whale.d.ts.map +1 -0
  490. package/lib/types/components/Whale.js +108 -0
  491. package/lib/types/components/WorkingSpinner.d.ts +26 -0
  492. package/lib/types/components/WorkingSpinner.d.ts.map +1 -0
  493. package/lib/types/components/WorkingSpinner.js +67 -0
  494. package/lib/types/components/WorkspaceFlowPicker.d.ts +20 -0
  495. package/lib/types/components/WorkspaceFlowPicker.d.ts.map +1 -0
  496. package/lib/types/components/WorkspaceFlowPicker.js +21 -0
  497. package/lib/types/components/WorkspaceMenuPicker.d.ts +19 -0
  498. package/lib/types/components/WorkspaceMenuPicker.d.ts.map +1 -0
  499. package/lib/types/components/WorkspaceMenuPicker.js +19 -0
  500. package/lib/types/components/WorkspacePicker.d.ts +12 -0
  501. package/lib/types/components/WorkspacePicker.d.ts.map +1 -0
  502. package/lib/types/components/WorkspacePicker.js +13 -0
  503. package/lib/types/components/activityFrames.d.ts +23 -0
  504. package/lib/types/components/activityFrames.d.ts.map +1 -0
  505. package/lib/types/components/activityFrames.js +31 -0
  506. package/lib/types/components/approvals/ApprovalPanel.d.ts +24 -0
  507. package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -0
  508. package/lib/types/components/approvals/ApprovalPanel.js +53 -0
  509. package/lib/types/components/bigfont.d.ts +28 -0
  510. package/lib/types/components/bigfont.d.ts.map +1 -0
  511. package/lib/types/components/bigfont.js +91 -0
  512. package/lib/types/components/design-system/Byline.d.ts +14 -0
  513. package/lib/types/components/design-system/Byline.d.ts.map +1 -0
  514. package/lib/types/components/design-system/Byline.js +17 -0
  515. package/lib/types/components/design-system/Divider.d.ts +61 -0
  516. package/lib/types/components/design-system/Divider.d.ts.map +1 -0
  517. package/lib/types/components/design-system/Divider.js +115 -0
  518. package/lib/types/components/design-system/HintLine.d.ts +11 -0
  519. package/lib/types/components/design-system/HintLine.d.ts.map +1 -0
  520. package/lib/types/components/design-system/HintLine.js +14 -0
  521. package/lib/types/components/design-system/ListItem.d.ts +42 -0
  522. package/lib/types/components/design-system/ListItem.d.ts.map +1 -0
  523. package/lib/types/components/design-system/ListItem.js +84 -0
  524. package/lib/types/components/design-system/LoadingState.d.ts +19 -0
  525. package/lib/types/components/design-system/LoadingState.d.ts.map +1 -0
  526. package/lib/types/components/design-system/LoadingState.js +22 -0
  527. package/lib/types/components/design-system/Pane.d.ts +17 -0
  528. package/lib/types/components/design-system/Pane.d.ts.map +1 -0
  529. package/lib/types/components/design-system/Pane.js +15 -0
  530. package/lib/types/components/design-system/ProgressBar.d.ts +21 -0
  531. package/lib/types/components/design-system/ProgressBar.d.ts.map +1 -0
  532. package/lib/types/components/design-system/ProgressBar.js +26 -0
  533. package/lib/types/components/design-system/StatusIcon.d.ts +15 -0
  534. package/lib/types/components/design-system/StatusIcon.d.ts.map +1 -0
  535. package/lib/types/components/design-system/StatusIcon.js +20 -0
  536. package/lib/types/components/design-system/ThemeProvider.d.ts +21 -0
  537. package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -0
  538. package/lib/types/components/design-system/ThemeProvider.js +256 -0
  539. package/lib/types/components/design-system/ThemedBox.d.ts +60 -0
  540. package/lib/types/components/design-system/ThemedBox.d.ts.map +1 -0
  541. package/lib/types/components/design-system/ThemedBox.js +29 -0
  542. package/lib/types/components/design-system/ThemedText.d.ts +61 -0
  543. package/lib/types/components/design-system/ThemedText.d.ts.map +1 -0
  544. package/lib/types/components/design-system/ThemedText.js +42 -0
  545. package/lib/types/components/listWindow.d.ts +26 -0
  546. package/lib/types/components/listWindow.d.ts.map +1 -0
  547. package/lib/types/components/listWindow.js +47 -0
  548. package/lib/types/components/messages/AssistantTextMessage.d.ts +20 -0
  549. package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -0
  550. package/lib/types/components/messages/AssistantTextMessage.js +18 -0
  551. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +40 -0
  552. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -0
  553. package/lib/types/components/messages/AssistantThinkingMessage.js +84 -0
  554. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +72 -0
  555. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -0
  556. package/lib/types/components/messages/AssistantToolUseMessage.js +517 -0
  557. package/lib/types/components/messages/MessageMetadata.d.ts +14 -0
  558. package/lib/types/components/messages/MessageMetadata.d.ts.map +1 -0
  559. package/lib/types/components/messages/MessageMetadata.js +19 -0
  560. package/lib/types/components/messages/TranscriptImages.d.ts +21 -0
  561. package/lib/types/components/messages/TranscriptImages.d.ts.map +1 -0
  562. package/lib/types/components/messages/TranscriptImages.js +83 -0
  563. package/lib/types/components/messages/UserPromptMessage.d.ts +18 -0
  564. package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -0
  565. package/lib/types/components/messages/UserPromptMessage.js +28 -0
  566. package/lib/types/components/messages/imageInspection.d.ts +33 -0
  567. package/lib/types/components/messages/imageInspection.d.ts.map +1 -0
  568. package/lib/types/components/messages/imageInspection.js +107 -0
  569. package/lib/types/components/messages/originalImage.d.ts +5 -0
  570. package/lib/types/components/messages/originalImage.d.ts.map +1 -0
  571. package/lib/types/components/messages/originalImage.js +56 -0
  572. package/lib/types/components/messages/transcriptImageDecode.d.ts +9 -0
  573. package/lib/types/components/messages/transcriptImageDecode.d.ts.map +1 -0
  574. package/lib/types/components/messages/transcriptImageDecode.js +144 -0
  575. package/lib/types/components/messages/useImageInspection.d.ts +10 -0
  576. package/lib/types/components/messages/useImageInspection.d.ts.map +1 -0
  577. package/lib/types/components/messages/useImageInspection.js +91 -0
  578. package/lib/types/components/overlayBudget.d.ts +39 -0
  579. package/lib/types/components/overlayBudget.d.ts.map +1 -0
  580. package/lib/types/components/overlayBudget.js +43 -0
  581. package/lib/types/components/promptDraftCache.d.ts +102 -0
  582. package/lib/types/components/promptDraftCache.d.ts.map +1 -0
  583. package/lib/types/components/promptDraftCache.js +76 -0
  584. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +94 -0
  585. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -0
  586. package/lib/types/components/questions/AskUserQuestionPanel.js +527 -0
  587. package/lib/types/components/questions/PlanReviewPanel.d.ts +55 -0
  588. package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -0
  589. package/lib/types/components/questions/PlanReviewPanel.js +351 -0
  590. package/lib/types/components/questions/QuestionMinimizedBar.d.ts +12 -0
  591. package/lib/types/components/questions/QuestionMinimizedBar.d.ts.map +1 -0
  592. package/lib/types/components/questions/QuestionMinimizedBar.js +43 -0
  593. package/lib/types/components/sessions/SessionListRow.d.ts +58 -0
  594. package/lib/types/components/sessions/SessionListRow.d.ts.map +1 -0
  595. package/lib/types/components/sessions/SessionListRow.js +108 -0
  596. package/lib/types/components/sessions/SessionPreview.d.ts +25 -0
  597. package/lib/types/components/sessions/SessionPreview.d.ts.map +1 -0
  598. package/lib/types/components/sessions/SessionPreview.js +62 -0
  599. package/lib/types/components/sessions/WorkspaceListRow.d.ts +17 -0
  600. package/lib/types/components/sessions/WorkspaceListRow.d.ts.map +1 -0
  601. package/lib/types/components/sessions/WorkspaceListRow.js +27 -0
  602. package/lib/types/components/shimmer.d.ts +35 -0
  603. package/lib/types/components/shimmer.d.ts.map +1 -0
  604. package/lib/types/components/shimmer.js +43 -0
  605. package/lib/types/components/smoothReveal.d.ts +57 -0
  606. package/lib/types/components/smoothReveal.d.ts.map +1 -0
  607. package/lib/types/components/smoothReveal.js +305 -0
  608. package/lib/types/components/trajectory/HotspotView.d.ts +20 -0
  609. package/lib/types/components/trajectory/HotspotView.d.ts.map +1 -0
  610. package/lib/types/components/trajectory/HotspotView.js +89 -0
  611. package/lib/types/components/trajectory/Inspector.d.ts +31 -0
  612. package/lib/types/components/trajectory/Inspector.d.ts.map +1 -0
  613. package/lib/types/components/trajectory/Inspector.js +67 -0
  614. package/lib/types/components/trajectory/Ledger.d.ts +28 -0
  615. package/lib/types/components/trajectory/Ledger.d.ts.map +1 -0
  616. package/lib/types/components/trajectory/Ledger.js +130 -0
  617. package/lib/types/components/trajectory/MiniWake.d.ts +24 -0
  618. package/lib/types/components/trajectory/MiniWake.d.ts.map +1 -0
  619. package/lib/types/components/trajectory/MiniWake.js +99 -0
  620. package/lib/types/components/trajectory/WaveBand.d.ts +42 -0
  621. package/lib/types/components/trajectory/WaveBand.d.ts.map +1 -0
  622. package/lib/types/components/trajectory/WaveBand.js +150 -0
  623. package/lib/types/components/whaleFrames.d.ts +81 -0
  624. package/lib/types/components/whaleFrames.d.ts.map +1 -0
  625. package/lib/types/components/whaleFrames.js +768 -0
  626. package/lib/types/components/whaleIdle.d.ts +66 -0
  627. package/lib/types/components/whaleIdle.d.ts.map +1 -0
  628. package/lib/types/components/whaleIdle.js +174 -0
  629. package/lib/types/components/whaleLayers.d.ts +28 -0
  630. package/lib/types/components/whaleLayers.d.ts.map +1 -0
  631. package/lib/types/components/whaleLayers.js +90 -0
  632. package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts +49 -0
  633. package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts.map +1 -0
  634. package/lib/types/components/workspaces/HomeWorkspaceRow.js +50 -0
  635. package/lib/types/customTheme.d.ts +108 -0
  636. package/lib/types/customTheme.d.ts.map +1 -0
  637. package/lib/types/customTheme.js +281 -0
  638. package/lib/types/deepseekBalance.d.ts +19 -0
  639. package/lib/types/deepseekBalance.d.ts.map +1 -0
  640. package/lib/types/deepseekBalance.js +72 -0
  641. package/lib/types/deepseekPricing.d.ts +83 -0
  642. package/lib/types/deepseekPricing.d.ts.map +1 -0
  643. package/lib/types/deepseekPricing.js +140 -0
  644. package/lib/types/dsh-adapter/activity-store.d.ts +221 -0
  645. package/lib/types/dsh-adapter/activity-store.d.ts.map +1 -0
  646. package/lib/types/dsh-adapter/activity-store.js +359 -0
  647. package/lib/types/dsh-adapter/agent-view.d.ts +66 -0
  648. package/lib/types/dsh-adapter/agent-view.d.ts.map +1 -0
  649. package/lib/types/dsh-adapter/agent-view.js +153 -0
  650. package/lib/types/dsh-adapter/approvals.d.ts +225 -0
  651. package/lib/types/dsh-adapter/approvals.d.ts.map +1 -0
  652. package/lib/types/dsh-adapter/approvals.js +465 -0
  653. package/lib/types/dsh-adapter/bundled-presets.d.ts +10 -0
  654. package/lib/types/dsh-adapter/bundled-presets.d.ts.map +1 -0
  655. package/lib/types/dsh-adapter/bundled-presets.js +80 -0
  656. package/lib/types/dsh-adapter/channel/action-readiness.d.ts +20 -0
  657. package/lib/types/dsh-adapter/channel/action-readiness.d.ts.map +1 -0
  658. package/lib/types/dsh-adapter/channel/action-readiness.js +86 -0
  659. package/lib/types/dsh-adapter/channel/agent-view-projection.d.ts +64 -0
  660. package/lib/types/dsh-adapter/channel/agent-view-projection.d.ts.map +1 -0
  661. package/lib/types/dsh-adapter/channel/agent-view-projection.js +312 -0
  662. package/lib/types/dsh-adapter/channel/background-action.d.ts +41 -0
  663. package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -0
  664. package/lib/types/dsh-adapter/channel/background-action.js +110 -0
  665. package/lib/types/dsh-adapter/channel/binding-events.d.ts +67 -0
  666. package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -0
  667. package/lib/types/dsh-adapter/channel/binding-events.js +170 -0
  668. package/lib/types/dsh-adapter/channel/binding.d.ts +58 -0
  669. package/lib/types/dsh-adapter/channel/binding.d.ts.map +1 -0
  670. package/lib/types/dsh-adapter/channel/binding.js +287 -0
  671. package/lib/types/dsh-adapter/channel/command-completions.d.ts +29 -0
  672. package/lib/types/dsh-adapter/channel/command-completions.d.ts.map +1 -0
  673. package/lib/types/dsh-adapter/channel/command-completions.js +94 -0
  674. package/lib/types/dsh-adapter/channel/commands.d.ts +8 -0
  675. package/lib/types/dsh-adapter/channel/commands.d.ts.map +1 -0
  676. package/lib/types/dsh-adapter/channel/commands.js +9 -0
  677. package/lib/types/dsh-adapter/channel/compaction.d.ts +18 -0
  678. package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -0
  679. package/lib/types/dsh-adapter/channel/compaction.js +114 -0
  680. package/lib/types/dsh-adapter/channel/composer-images.d.ts +62 -0
  681. package/lib/types/dsh-adapter/channel/composer-images.d.ts.map +1 -0
  682. package/lib/types/dsh-adapter/channel/composer-images.js +316 -0
  683. package/lib/types/dsh-adapter/channel/composer-mentions.d.ts +15 -0
  684. package/lib/types/dsh-adapter/channel/composer-mentions.d.ts.map +1 -0
  685. package/lib/types/dsh-adapter/channel/composer-mentions.js +200 -0
  686. package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts +34 -0
  687. package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts.map +1 -0
  688. package/lib/types/dsh-adapter/channel/context-bookkeeping.js +31 -0
  689. package/lib/types/dsh-adapter/channel/decisions.d.ts +19 -0
  690. package/lib/types/dsh-adapter/channel/decisions.d.ts.map +1 -0
  691. package/lib/types/dsh-adapter/channel/decisions.js +90 -0
  692. package/lib/types/dsh-adapter/channel/emitter.d.ts +10 -0
  693. package/lib/types/dsh-adapter/channel/emitter.d.ts.map +1 -0
  694. package/lib/types/dsh-adapter/channel/emitter.js +71 -0
  695. package/lib/types/dsh-adapter/channel/external-commands.d.ts +31 -0
  696. package/lib/types/dsh-adapter/channel/external-commands.d.ts.map +1 -0
  697. package/lib/types/dsh-adapter/channel/external-commands.js +187 -0
  698. package/lib/types/dsh-adapter/channel/file-actions.d.ts +20 -0
  699. package/lib/types/dsh-adapter/channel/file-actions.d.ts.map +1 -0
  700. package/lib/types/dsh-adapter/channel/file-actions.js +45 -0
  701. package/lib/types/dsh-adapter/channel/ide-selection.d.ts +58 -0
  702. package/lib/types/dsh-adapter/channel/ide-selection.d.ts.map +1 -0
  703. package/lib/types/dsh-adapter/channel/ide-selection.js +226 -0
  704. package/lib/types/dsh-adapter/channel/input-actions.d.ts +13 -0
  705. package/lib/types/dsh-adapter/channel/input-actions.d.ts.map +1 -0
  706. package/lib/types/dsh-adapter/channel/input-actions.js +135 -0
  707. package/lib/types/dsh-adapter/channel/input-delivery.d.ts +42 -0
  708. package/lib/types/dsh-adapter/channel/input-delivery.d.ts.map +1 -0
  709. package/lib/types/dsh-adapter/channel/input-delivery.js +313 -0
  710. package/lib/types/dsh-adapter/channel/job-projection.d.ts +28 -0
  711. package/lib/types/dsh-adapter/channel/job-projection.d.ts.map +1 -0
  712. package/lib/types/dsh-adapter/channel/job-projection.js +150 -0
  713. package/lib/types/dsh-adapter/channel/lifetime-resources.d.ts +9 -0
  714. package/lib/types/dsh-adapter/channel/lifetime-resources.d.ts.map +1 -0
  715. package/lib/types/dsh-adapter/channel/lifetime-resources.js +33 -0
  716. package/lib/types/dsh-adapter/channel/loaded-context.d.ts +40 -0
  717. package/lib/types/dsh-adapter/channel/loaded-context.d.ts.map +1 -0
  718. package/lib/types/dsh-adapter/channel/loaded-context.js +62 -0
  719. package/lib/types/dsh-adapter/channel/local-actions.d.ts +54 -0
  720. package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -0
  721. package/lib/types/dsh-adapter/channel/local-actions.js +109 -0
  722. package/lib/types/dsh-adapter/channel/mentions.d.ts +29 -0
  723. package/lib/types/dsh-adapter/channel/mentions.d.ts.map +1 -0
  724. package/lib/types/dsh-adapter/channel/mentions.js +235 -0
  725. package/lib/types/dsh-adapter/channel/mode-actions.d.ts +30 -0
  726. package/lib/types/dsh-adapter/channel/mode-actions.d.ts.map +1 -0
  727. package/lib/types/dsh-adapter/channel/mode-actions.js +247 -0
  728. package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts +35 -0
  729. package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts.map +1 -0
  730. package/lib/types/dsh-adapter/channel/mode-permission-actions.js +199 -0
  731. package/lib/types/dsh-adapter/channel/mode-permission.d.ts +58 -0
  732. package/lib/types/dsh-adapter/channel/mode-permission.d.ts.map +1 -0
  733. package/lib/types/dsh-adapter/channel/mode-permission.js +240 -0
  734. package/lib/types/dsh-adapter/channel/mode-roster.d.ts +51 -0
  735. package/lib/types/dsh-adapter/channel/mode-roster.d.ts.map +1 -0
  736. package/lib/types/dsh-adapter/channel/mode-roster.js +119 -0
  737. package/lib/types/dsh-adapter/channel/model-actions.d.ts +49 -0
  738. package/lib/types/dsh-adapter/channel/model-actions.d.ts.map +1 -0
  739. package/lib/types/dsh-adapter/channel/model-actions.js +351 -0
  740. package/lib/types/dsh-adapter/channel/model-switch.d.ts +31 -0
  741. package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -0
  742. package/lib/types/dsh-adapter/channel/model-switch.js +116 -0
  743. package/lib/types/dsh-adapter/channel/notifications.d.ts +9 -0
  744. package/lib/types/dsh-adapter/channel/notifications.d.ts.map +1 -0
  745. package/lib/types/dsh-adapter/channel/notifications.js +24 -0
  746. package/lib/types/dsh-adapter/channel/owner.d.ts +18 -0
  747. package/lib/types/dsh-adapter/channel/owner.d.ts.map +1 -0
  748. package/lib/types/dsh-adapter/channel/owner.js +73 -0
  749. package/lib/types/dsh-adapter/channel/paths.d.ts +31 -0
  750. package/lib/types/dsh-adapter/channel/paths.d.ts.map +1 -0
  751. package/lib/types/dsh-adapter/channel/paths.js +147 -0
  752. package/lib/types/dsh-adapter/channel/permissions.d.ts +40 -0
  753. package/lib/types/dsh-adapter/channel/permissions.d.ts.map +1 -0
  754. package/lib/types/dsh-adapter/channel/permissions.js +187 -0
  755. package/lib/types/dsh-adapter/channel/preferences.d.ts +3 -0
  756. package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -0
  757. package/lib/types/dsh-adapter/channel/preferences.js +103 -0
  758. package/lib/types/dsh-adapter/channel/projection-helpers.d.ts +13 -0
  759. package/lib/types/dsh-adapter/channel/projection-helpers.d.ts.map +1 -0
  760. package/lib/types/dsh-adapter/channel/projection-helpers.js +63 -0
  761. package/lib/types/dsh-adapter/channel/projection.d.ts +44 -0
  762. package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -0
  763. package/lib/types/dsh-adapter/channel/projection.js +1031 -0
  764. package/lib/types/dsh-adapter/channel/reports.d.ts +32 -0
  765. package/lib/types/dsh-adapter/channel/reports.d.ts.map +1 -0
  766. package/lib/types/dsh-adapter/channel/reports.js +163 -0
  767. package/lib/types/dsh-adapter/channel/session-actions.d.ts +13 -0
  768. package/lib/types/dsh-adapter/channel/session-actions.d.ts.map +1 -0
  769. package/lib/types/dsh-adapter/channel/session-actions.js +29 -0
  770. package/lib/types/dsh-adapter/channel/session-adoption.d.ts +32 -0
  771. package/lib/types/dsh-adapter/channel/session-adoption.d.ts.map +1 -0
  772. package/lib/types/dsh-adapter/channel/session-adoption.js +36 -0
  773. package/lib/types/dsh-adapter/channel/session-fork.d.ts +19 -0
  774. package/lib/types/dsh-adapter/channel/session-fork.d.ts.map +1 -0
  775. package/lib/types/dsh-adapter/channel/session-fork.js +109 -0
  776. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +35 -0
  777. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -0
  778. package/lib/types/dsh-adapter/channel/session-live-adoption.js +64 -0
  779. package/lib/types/dsh-adapter/channel/session-metadata.d.ts +91 -0
  780. package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -0
  781. package/lib/types/dsh-adapter/channel/session-metadata.js +220 -0
  782. package/lib/types/dsh-adapter/channel/session-reset.d.ts +11 -0
  783. package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -0
  784. package/lib/types/dsh-adapter/channel/session-reset.js +43 -0
  785. package/lib/types/dsh-adapter/channel/session-resume.d.ts +65 -0
  786. package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -0
  787. package/lib/types/dsh-adapter/channel/session-resume.js +438 -0
  788. package/lib/types/dsh-adapter/channel/session-rewind.d.ts +19 -0
  789. package/lib/types/dsh-adapter/channel/session-rewind.d.ts.map +1 -0
  790. package/lib/types/dsh-adapter/channel/session-rewind.js +146 -0
  791. package/lib/types/dsh-adapter/channel/session-tree-actions.d.ts +19 -0
  792. package/lib/types/dsh-adapter/channel/session-tree-actions.d.ts.map +1 -0
  793. package/lib/types/dsh-adapter/channel/session-tree-actions.js +154 -0
  794. package/lib/types/dsh-adapter/channel/session-tree.d.ts +10 -0
  795. package/lib/types/dsh-adapter/channel/session-tree.d.ts.map +1 -0
  796. package/lib/types/dsh-adapter/channel/session-tree.js +503 -0
  797. package/lib/types/dsh-adapter/channel/settings-host.d.ts +4 -0
  798. package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -0
  799. package/lib/types/dsh-adapter/channel/settings-host.js +257 -0
  800. package/lib/types/dsh-adapter/channel/skill-catalog.d.ts +33 -0
  801. package/lib/types/dsh-adapter/channel/skill-catalog.d.ts.map +1 -0
  802. package/lib/types/dsh-adapter/channel/skill-catalog.js +215 -0
  803. package/lib/types/dsh-adapter/channel/state.d.ts +51 -0
  804. package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -0
  805. package/lib/types/dsh-adapter/channel/state.js +31 -0
  806. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +67 -0
  807. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -0
  808. package/lib/types/dsh-adapter/channel/subagent-projection.js +307 -0
  809. package/lib/types/dsh-adapter/channel/transcript.d.ts +73 -0
  810. package/lib/types/dsh-adapter/channel/transcript.d.ts.map +1 -0
  811. package/lib/types/dsh-adapter/channel/transcript.js +306 -0
  812. package/lib/types/dsh-adapter/channel/types.d.ts +167 -0
  813. package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -0
  814. package/lib/types/dsh-adapter/channel/types.js +1 -0
  815. package/lib/types/dsh-adapter/channel/usage.d.ts +13 -0
  816. package/lib/types/dsh-adapter/channel/usage.d.ts.map +1 -0
  817. package/lib/types/dsh-adapter/channel/usage.js +48 -0
  818. package/lib/types/dsh-adapter/channel/workspace-actions.d.ts +23 -0
  819. package/lib/types/dsh-adapter/channel/workspace-actions.d.ts.map +1 -0
  820. package/lib/types/dsh-adapter/channel/workspace-actions.js +96 -0
  821. package/lib/types/dsh-adapter/channel-facade-actions.d.ts +25 -0
  822. package/lib/types/dsh-adapter/channel-facade-actions.d.ts.map +1 -0
  823. package/lib/types/dsh-adapter/channel-facade-actions.js +55 -0
  824. package/lib/types/dsh-adapter/channel-scene-outlet.d.ts +6 -0
  825. package/lib/types/dsh-adapter/channel-scene-outlet.d.ts.map +1 -0
  826. package/lib/types/dsh-adapter/channel-scene-outlet.js +13 -0
  827. package/lib/types/dsh-adapter/channel-ui.d.ts +9 -0
  828. package/lib/types/dsh-adapter/channel-ui.d.ts.map +1 -0
  829. package/lib/types/dsh-adapter/channel-ui.js +128 -0
  830. package/lib/types/dsh-adapter/channel.d.ts +23 -0
  831. package/lib/types/dsh-adapter/channel.d.ts.map +1 -0
  832. package/lib/types/dsh-adapter/channel.js +999 -0
  833. package/lib/types/dsh-adapter/childStderr.d.ts +63 -0
  834. package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -0
  835. package/lib/types/dsh-adapter/childStderr.js +180 -0
  836. package/lib/types/dsh-adapter/command-attribution.d.ts +51 -0
  837. package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -0
  838. package/lib/types/dsh-adapter/command-attribution.js +93 -0
  839. package/lib/types/dsh-adapter/command-errors.d.ts +42 -0
  840. package/lib/types/dsh-adapter/command-errors.d.ts.map +1 -0
  841. package/lib/types/dsh-adapter/command-errors.js +63 -0
  842. package/lib/types/dsh-adapter/command-trees.d.ts +34 -0
  843. package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -0
  844. package/lib/types/dsh-adapter/command-trees.js +111 -0
  845. package/lib/types/dsh-adapter/compat/index.d.ts +29 -0
  846. package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -0
  847. package/lib/types/dsh-adapter/compat/index.js +28 -0
  848. package/lib/types/dsh-adapter/compat/liveSession.d.ts +79 -0
  849. package/lib/types/dsh-adapter/compat/liveSession.d.ts.map +1 -0
  850. package/lib/types/dsh-adapter/compat/liveSession.js +223 -0
  851. package/lib/types/dsh-adapter/compat/messages.d.ts +15 -0
  852. package/lib/types/dsh-adapter/compat/messages.d.ts.map +1 -0
  853. package/lib/types/dsh-adapter/compat/messages.js +15 -0
  854. package/lib/types/dsh-adapter/compat/persistence.d.ts +21 -0
  855. package/lib/types/dsh-adapter/compat/persistence.d.ts.map +1 -0
  856. package/lib/types/dsh-adapter/compat/persistence.js +17 -0
  857. package/lib/types/dsh-adapter/compat/sessionLog.d.ts +309 -0
  858. package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -0
  859. package/lib/types/dsh-adapter/compat/sessionLog.js +1177 -0
  860. package/lib/types/dsh-adapter/compat/settings.d.ts +35 -0
  861. package/lib/types/dsh-adapter/compat/settings.d.ts.map +1 -0
  862. package/lib/types/dsh-adapter/compat/settings.js +57 -0
  863. package/lib/types/dsh-adapter/compat/shell.d.ts +25 -0
  864. package/lib/types/dsh-adapter/compat/shell.d.ts.map +1 -0
  865. package/lib/types/dsh-adapter/compat/shell.js +11 -0
  866. package/lib/types/dsh-adapter/component-identity.d.ts +33 -0
  867. package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -0
  868. package/lib/types/dsh-adapter/component-identity.js +108 -0
  869. package/lib/types/dsh-adapter/contract.d.ts +91 -0
  870. package/lib/types/dsh-adapter/contract.d.ts.map +1 -0
  871. package/lib/types/dsh-adapter/contract.js +276 -0
  872. package/lib/types/dsh-adapter/credentialRefGuard.d.ts +40 -0
  873. package/lib/types/dsh-adapter/credentialRefGuard.d.ts.map +1 -0
  874. package/lib/types/dsh-adapter/credentialRefGuard.js +43 -0
  875. package/lib/types/dsh-adapter/decision-guard.d.ts +128 -0
  876. package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -0
  877. package/lib/types/dsh-adapter/decision-guard.js +460 -0
  878. package/lib/types/dsh-adapter/dialogs.d.ts +145 -0
  879. package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -0
  880. package/lib/types/dsh-adapter/dialogs.js +329 -0
  881. package/lib/types/dsh-adapter/effect-ledger.d.ts +96 -0
  882. package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -0
  883. package/lib/types/dsh-adapter/effect-ledger.js +290 -0
  884. package/lib/types/dsh-adapter/extension-events.d.ts +186 -0
  885. package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -0
  886. package/lib/types/dsh-adapter/extension-events.js +187 -0
  887. package/lib/types/dsh-adapter/extensions.d.ts +36 -0
  888. package/lib/types/dsh-adapter/extensions.d.ts.map +1 -0
  889. package/lib/types/dsh-adapter/extensions.js +51 -0
  890. package/lib/types/dsh-adapter/host-access.d.ts +37 -0
  891. package/lib/types/dsh-adapter/host-access.d.ts.map +1 -0
  892. package/lib/types/dsh-adapter/host-access.js +652 -0
  893. package/lib/types/dsh-adapter/host-grants.d.ts +23 -0
  894. package/lib/types/dsh-adapter/host-grants.d.ts.map +1 -0
  895. package/lib/types/dsh-adapter/host-grants.js +45 -0
  896. package/lib/types/dsh-adapter/ide-channel.d.ts +224 -0
  897. package/lib/types/dsh-adapter/ide-channel.d.ts.map +1 -0
  898. package/lib/types/dsh-adapter/ide-channel.js +556 -0
  899. package/lib/types/dsh-adapter/index.d.ts +151 -0
  900. package/lib/types/dsh-adapter/index.d.ts.map +1 -0
  901. package/lib/types/dsh-adapter/index.js +119 -0
  902. package/lib/types/dsh-adapter/inject-channel.d.ts +108 -0
  903. package/lib/types/dsh-adapter/inject-channel.d.ts.map +1 -0
  904. package/lib/types/dsh-adapter/inject-channel.js +247 -0
  905. package/lib/types/dsh-adapter/invariant.d.ts +20 -0
  906. package/lib/types/dsh-adapter/invariant.d.ts.map +1 -0
  907. package/lib/types/dsh-adapter/invariant.js +26 -0
  908. package/lib/types/dsh-adapter/jobs.d.ts +101 -0
  909. package/lib/types/dsh-adapter/jobs.d.ts.map +1 -0
  910. package/lib/types/dsh-adapter/jobs.js +177 -0
  911. package/lib/types/dsh-adapter/message-observer.d.ts +186 -0
  912. package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -0
  913. package/lib/types/dsh-adapter/message-observer.js +682 -0
  914. package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts +3 -0
  915. package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts.map +1 -0
  916. package/lib/types/dsh-adapter/migrate/adapters/claude-code.js +191 -0
  917. package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts +3 -0
  918. package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts.map +1 -0
  919. package/lib/types/dsh-adapter/migrate/adapters/codex.js +133 -0
  920. package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts +3 -0
  921. package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts.map +1 -0
  922. package/lib/types/dsh-adapter/migrate/adapters/grok-build.js +175 -0
  923. package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts +3 -0
  924. package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts.map +1 -0
  925. package/lib/types/dsh-adapter/migrate/adapters/omp.js +132 -0
  926. package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts +6 -0
  927. package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts.map +1 -0
  928. package/lib/types/dsh-adapter/migrate/adapters/scan.js +38 -0
  929. package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts +3 -0
  930. package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts.map +1 -0
  931. package/lib/types/dsh-adapter/migrate/adapters/zcode.js +107 -0
  932. package/lib/types/dsh-adapter/migrate/bin-path.d.ts +6 -0
  933. package/lib/types/dsh-adapter/migrate/bin-path.d.ts.map +1 -0
  934. package/lib/types/dsh-adapter/migrate/bin-path.js +30 -0
  935. package/lib/types/dsh-adapter/migrate/cli.d.ts +9 -0
  936. package/lib/types/dsh-adapter/migrate/cli.d.ts.map +1 -0
  937. package/lib/types/dsh-adapter/migrate/cli.js +105 -0
  938. package/lib/types/dsh-adapter/migrate/index.d.ts +29 -0
  939. package/lib/types/dsh-adapter/migrate/index.d.ts.map +1 -0
  940. package/lib/types/dsh-adapter/migrate/index.js +108 -0
  941. package/lib/types/dsh-adapter/migrate/picker.d.ts +64 -0
  942. package/lib/types/dsh-adapter/migrate/picker.d.ts.map +1 -0
  943. package/lib/types/dsh-adapter/migrate/picker.js +86 -0
  944. package/lib/types/dsh-adapter/migrate/recent-agents.d.ts +40 -0
  945. package/lib/types/dsh-adapter/migrate/recent-agents.d.ts.map +1 -0
  946. package/lib/types/dsh-adapter/migrate/recent-agents.js +100 -0
  947. package/lib/types/dsh-adapter/migrate/sessionize.d.ts +19 -0
  948. package/lib/types/dsh-adapter/migrate/sessionize.d.ts.map +1 -0
  949. package/lib/types/dsh-adapter/migrate/sessionize.js +101 -0
  950. package/lib/types/dsh-adapter/migrate/types.d.ts +52 -0
  951. package/lib/types/dsh-adapter/migrate/types.d.ts.map +1 -0
  952. package/lib/types/dsh-adapter/migrate/types.js +11 -0
  953. package/lib/types/dsh-adapter/migrate/uuid.d.ts +7 -0
  954. package/lib/types/dsh-adapter/migrate/uuid.d.ts.map +1 -0
  955. package/lib/types/dsh-adapter/migrate/uuid.js +25 -0
  956. package/lib/types/dsh-adapter/packaged-presets.d.ts +22 -0
  957. package/lib/types/dsh-adapter/packaged-presets.d.ts.map +1 -0
  958. package/lib/types/dsh-adapter/packaged-presets.js +94 -0
  959. package/lib/types/dsh-adapter/plugin-host.d.ts +205 -0
  960. package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -0
  961. package/lib/types/dsh-adapter/plugin-host.js +762 -0
  962. package/lib/types/dsh-adapter/plugin-storage.d.ts +118 -0
  963. package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -0
  964. package/lib/types/dsh-adapter/plugin-storage.js +536 -0
  965. package/lib/types/dsh-adapter/plugin.d.ts +70 -0
  966. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -0
  967. package/lib/types/dsh-adapter/plugin.js +2140 -0
  968. package/lib/types/dsh-adapter/plugins-info.d.ts +43 -0
  969. package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -0
  970. package/lib/types/dsh-adapter/plugins-info.js +293 -0
  971. package/lib/types/dsh-adapter/preset-resolution.d.ts +57 -0
  972. package/lib/types/dsh-adapter/preset-resolution.d.ts.map +1 -0
  973. package/lib/types/dsh-adapter/preset-resolution.js +52 -0
  974. package/lib/types/dsh-adapter/presets.d.ts +110 -0
  975. package/lib/types/dsh-adapter/presets.d.ts.map +1 -0
  976. package/lib/types/dsh-adapter/presets.js +161 -0
  977. package/lib/types/dsh-adapter/promptDebug.d.ts +4 -0
  978. package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -0
  979. package/lib/types/dsh-adapter/promptDebug.js +163 -0
  980. package/lib/types/dsh-adapter/providerGuard.d.ts +75 -0
  981. package/lib/types/dsh-adapter/providerGuard.d.ts.map +1 -0
  982. package/lib/types/dsh-adapter/providerGuard.js +104 -0
  983. package/lib/types/dsh-adapter/providerWizard.d.ts +42 -0
  984. package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -0
  985. package/lib/types/dsh-adapter/providerWizard.js +921 -0
  986. package/lib/types/dsh-adapter/questions-answerer.d.ts +51 -0
  987. package/lib/types/dsh-adapter/questions-answerer.d.ts.map +1 -0
  988. package/lib/types/dsh-adapter/questions-answerer.js +64 -0
  989. package/lib/types/dsh-adapter/questions.d.ts +130 -0
  990. package/lib/types/dsh-adapter/questions.d.ts.map +1 -0
  991. package/lib/types/dsh-adapter/questions.js +282 -0
  992. package/lib/types/dsh-adapter/recap.d.ts +41 -0
  993. package/lib/types/dsh-adapter/recap.d.ts.map +1 -0
  994. package/lib/types/dsh-adapter/recap.js +111 -0
  995. package/lib/types/dsh-adapter/renderers.d.ts +58 -0
  996. package/lib/types/dsh-adapter/renderers.d.ts.map +1 -0
  997. package/lib/types/dsh-adapter/renderers.js +198 -0
  998. package/lib/types/dsh-adapter/sanitize.d.ts +45 -0
  999. package/lib/types/dsh-adapter/sanitize.d.ts.map +1 -0
  1000. package/lib/types/dsh-adapter/sanitize.js +84 -0
  1001. package/lib/types/dsh-adapter/scenes.d.ts +87 -0
  1002. package/lib/types/dsh-adapter/scenes.d.ts.map +1 -0
  1003. package/lib/types/dsh-adapter/scenes.js +223 -0
  1004. package/lib/types/dsh-adapter/session-mount-heartbeat.d.ts +53 -0
  1005. package/lib/types/dsh-adapter/session-mount-heartbeat.d.ts.map +1 -0
  1006. package/lib/types/dsh-adapter/session-mount-heartbeat.js +100 -0
  1007. package/lib/types/dsh-adapter/sessionTree.d.ts +232 -0
  1008. package/lib/types/dsh-adapter/sessionTree.d.ts.map +1 -0
  1009. package/lib/types/dsh-adapter/sessionTree.js +984 -0
  1010. package/lib/types/dsh-adapter/sessions/digest.d.ts +54 -0
  1011. package/lib/types/dsh-adapter/sessions/digest.d.ts.map +1 -0
  1012. package/lib/types/dsh-adapter/sessions/digest.js +478 -0
  1013. package/lib/types/dsh-adapter/sessions/frames.d.ts +103 -0
  1014. package/lib/types/dsh-adapter/sessions/frames.d.ts.map +1 -0
  1015. package/lib/types/dsh-adapter/sessions/frames.js +263 -0
  1016. package/lib/types/dsh-adapter/sessions/header.d.ts +56 -0
  1017. package/lib/types/dsh-adapter/sessions/header.d.ts.map +1 -0
  1018. package/lib/types/dsh-adapter/sessions/header.js +85 -0
  1019. package/lib/types/dsh-adapter/sessions/index.d.ts +17 -0
  1020. package/lib/types/dsh-adapter/sessions/index.d.ts.map +1 -0
  1021. package/lib/types/dsh-adapter/sessions/index.js +15 -0
  1022. package/lib/types/dsh-adapter/sessions/list.d.ts +64 -0
  1023. package/lib/types/dsh-adapter/sessions/list.d.ts.map +1 -0
  1024. package/lib/types/dsh-adapter/sessions/list.js +331 -0
  1025. package/lib/types/dsh-adapter/sessions/recovery.d.ts +17 -0
  1026. package/lib/types/dsh-adapter/sessions/recovery.d.ts.map +1 -0
  1027. package/lib/types/dsh-adapter/sessions/recovery.js +109 -0
  1028. package/lib/types/dsh-adapter/sessions/store.d.ts +60 -0
  1029. package/lib/types/dsh-adapter/sessions/store.d.ts.map +1 -0
  1030. package/lib/types/dsh-adapter/sessions/store.js +221 -0
  1031. package/lib/types/dsh-adapter/sessions/types.d.ts +21 -0
  1032. package/lib/types/dsh-adapter/sessions/types.d.ts.map +1 -0
  1033. package/lib/types/dsh-adapter/sessions/types.js +1 -0
  1034. package/lib/types/dsh-adapter/settings-sections.d.ts +48 -0
  1035. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -0
  1036. package/lib/types/dsh-adapter/settings-sections.js +253 -0
  1037. package/lib/types/dsh-adapter/settingsEditor.d.ts +100 -0
  1038. package/lib/types/dsh-adapter/settingsEditor.d.ts.map +1 -0
  1039. package/lib/types/dsh-adapter/settingsEditor.js +238 -0
  1040. package/lib/types/dsh-adapter/sharp.d.ts +10 -0
  1041. package/lib/types/dsh-adapter/sharp.d.ts.map +1 -0
  1042. package/lib/types/dsh-adapter/sharp.js +59 -0
  1043. package/lib/types/dsh-adapter/shortcuts.d.ts +82 -0
  1044. package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -0
  1045. package/lib/types/dsh-adapter/shortcuts.js +252 -0
  1046. package/lib/types/dsh-adapter/sideQuestion.d.ts +36 -0
  1047. package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -0
  1048. package/lib/types/dsh-adapter/sideQuestion.js +59 -0
  1049. package/lib/types/dsh-adapter/status.d.ts +148 -0
  1050. package/lib/types/dsh-adapter/status.d.ts.map +1 -0
  1051. package/lib/types/dsh-adapter/status.js +435 -0
  1052. package/lib/types/dsh-adapter/subagents.d.ts +64 -0
  1053. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -0
  1054. package/lib/types/dsh-adapter/subagents.js +366 -0
  1055. package/lib/types/dsh-adapter/themes.d.ts +52 -0
  1056. package/lib/types/dsh-adapter/themes.d.ts.map +1 -0
  1057. package/lib/types/dsh-adapter/themes.js +307 -0
  1058. package/lib/types/dsh-adapter/toast.d.ts +80 -0
  1059. package/lib/types/dsh-adapter/toast.d.ts.map +1 -0
  1060. package/lib/types/dsh-adapter/toast.js +171 -0
  1061. package/lib/types/dsh-adapter/trajectory/aggregate.d.ts +47 -0
  1062. package/lib/types/dsh-adapter/trajectory/aggregate.d.ts.map +1 -0
  1063. package/lib/types/dsh-adapter/trajectory/aggregate.js +208 -0
  1064. package/lib/types/dsh-adapter/trajectory/guards.d.ts +196 -0
  1065. package/lib/types/dsh-adapter/trajectory/guards.d.ts.map +1 -0
  1066. package/lib/types/dsh-adapter/trajectory/guards.js +273 -0
  1067. package/lib/types/dsh-adapter/trajectory/index.d.ts +16 -0
  1068. package/lib/types/dsh-adapter/trajectory/index.d.ts.map +1 -0
  1069. package/lib/types/dsh-adapter/trajectory/index.js +15 -0
  1070. package/lib/types/dsh-adapter/trajectory/inspect.d.ts +40 -0
  1071. package/lib/types/dsh-adapter/trajectory/inspect.d.ts.map +1 -0
  1072. package/lib/types/dsh-adapter/trajectory/inspect.js +160 -0
  1073. package/lib/types/dsh-adapter/trajectory/projection.d.ts +146 -0
  1074. package/lib/types/dsh-adapter/trajectory/projection.d.ts.map +1 -0
  1075. package/lib/types/dsh-adapter/trajectory/projection.js +710 -0
  1076. package/lib/types/dsh-adapter/trajectory/types.d.ts +232 -0
  1077. package/lib/types/dsh-adapter/trajectory/types.d.ts.map +1 -0
  1078. package/lib/types/dsh-adapter/trajectory/types.js +70 -0
  1079. package/lib/types/dsh-adapter/trajectory/wave.d.ts +45 -0
  1080. package/lib/types/dsh-adapter/trajectory/wave.d.ts.map +1 -0
  1081. package/lib/types/dsh-adapter/trajectory/wave.js +210 -0
  1082. package/lib/types/dsh-adapter/transcript-images.d.ts +17 -0
  1083. package/lib/types/dsh-adapter/transcript-images.d.ts.map +1 -0
  1084. package/lib/types/dsh-adapter/transcript-images.js +96 -0
  1085. package/lib/types/dsh-adapter/types.d.ts +23 -0
  1086. package/lib/types/dsh-adapter/types.d.ts.map +1 -0
  1087. package/lib/types/dsh-adapter/types.js +1 -0
  1088. package/lib/types/dsh-adapter/workspace.d.ts +22 -0
  1089. package/lib/types/dsh-adapter/workspace.d.ts.map +1 -0
  1090. package/lib/types/dsh-adapter/workspace.js +16 -0
  1091. package/lib/types/dsh-adapter/workspaces.d.ts +125 -0
  1092. package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -0
  1093. package/lib/types/dsh-adapter/workspaces.js +543 -0
  1094. package/lib/types/effortPrefs.d.ts +48 -0
  1095. package/lib/types/effortPrefs.d.ts.map +1 -0
  1096. package/lib/types/effortPrefs.js +95 -0
  1097. package/lib/types/extensions.d.ts +18 -0
  1098. package/lib/types/extensions.d.ts.map +1 -0
  1099. package/lib/types/extensions.js +27 -0
  1100. package/lib/types/force-production-react.d.ts +1 -0
  1101. package/lib/types/force-production-react.d.ts.map +1 -0
  1102. package/lib/types/force-production-react.js +12 -0
  1103. package/lib/types/herdr.d.ts +28 -0
  1104. package/lib/types/herdr.d.ts.map +1 -0
  1105. package/lib/types/herdr.js +133 -0
  1106. package/lib/types/history.d.ts +39 -0
  1107. package/lib/types/history.d.ts.map +1 -0
  1108. package/lib/types/history.js +177 -0
  1109. package/lib/types/homePrefs.d.ts +15 -0
  1110. package/lib/types/homePrefs.d.ts.map +1 -0
  1111. package/lib/types/homePrefs.js +53 -0
  1112. package/lib/types/hooks/useBlink.d.ts +10 -0
  1113. package/lib/types/hooks/useBlink.d.ts.map +1 -0
  1114. package/lib/types/hooks/useBlink.js +19 -0
  1115. package/lib/types/hooks/useExternalVersion.d.ts +32 -0
  1116. package/lib/types/hooks/useExternalVersion.d.ts.map +1 -0
  1117. package/lib/types/hooks/useExternalVersion.js +53 -0
  1118. package/lib/types/hooks/useRevealVersion.d.ts +21 -0
  1119. package/lib/types/hooks/useRevealVersion.d.ts.map +1 -0
  1120. package/lib/types/hooks/useRevealVersion.js +33 -0
  1121. package/lib/types/hooks/useRuntimeThemeSnapshot.d.ts +10 -0
  1122. package/lib/types/hooks/useRuntimeThemeSnapshot.d.ts.map +1 -0
  1123. package/lib/types/hooks/useRuntimeThemeSnapshot.js +32 -0
  1124. package/lib/types/i18n.d.ts +4433 -0
  1125. package/lib/types/i18n.d.ts.map +1 -0
  1126. package/lib/types/i18n.js +1493 -0
  1127. package/lib/types/index.d.ts +3 -0
  1128. package/lib/types/index.d.ts.map +1 -0
  1129. package/lib/types/index.js +4 -0
  1130. package/lib/types/ink/Ansi.d.ts +9 -0
  1131. package/lib/types/ink/Ansi.d.ts.map +1 -0
  1132. package/lib/types/ink/Ansi.js +45 -0
  1133. package/lib/types/ink/bidi.d.ts +18 -0
  1134. package/lib/types/ink/bidi.d.ts.map +1 -0
  1135. package/lib/types/ink/bidi.js +119 -0
  1136. package/lib/types/ink/clearTerminal.d.ts +22 -0
  1137. package/lib/types/ink/clearTerminal.d.ts.map +1 -0
  1138. package/lib/types/ink/clearTerminal.js +72 -0
  1139. package/lib/types/ink/colorize.d.ts +43 -0
  1140. package/lib/types/ink/colorize.d.ts.map +1 -0
  1141. package/lib/types/ink/colorize.js +233 -0
  1142. package/lib/types/ink/components/AlternateScreen.d.ts +8 -0
  1143. package/lib/types/ink/components/AlternateScreen.d.ts.map +1 -0
  1144. package/lib/types/ink/components/AlternateScreen.js +29 -0
  1145. package/lib/types/ink/components/App.d.ts +149 -0
  1146. package/lib/types/ink/components/App.d.ts.map +1 -0
  1147. package/lib/types/ink/components/App.js +1027 -0
  1148. package/lib/types/ink/components/AppContext.d.ts +17 -0
  1149. package/lib/types/ink/components/AppContext.d.ts.map +1 -0
  1150. package/lib/types/ink/components/AppContext.js +12 -0
  1151. package/lib/types/ink/components/Box.d.ts +85 -0
  1152. package/lib/types/ink/components/Box.d.ts.map +1 -0
  1153. package/lib/types/ink/components/Box.js +22 -0
  1154. package/lib/types/ink/components/Button.d.ts +37 -0
  1155. package/lib/types/ink/components/Button.d.ts.map +1 -0
  1156. package/lib/types/ink/components/Button.js +23 -0
  1157. package/lib/types/ink/components/ClockContext.d.ts +17 -0
  1158. package/lib/types/ink/components/ClockContext.d.ts.map +1 -0
  1159. package/lib/types/ink/components/ClockContext.js +99 -0
  1160. package/lib/types/ink/components/CursorDeclarationContext.d.ts +30 -0
  1161. package/lib/types/ink/components/CursorDeclarationContext.d.ts.map +1 -0
  1162. package/lib/types/ink/components/CursorDeclarationContext.js +6 -0
  1163. package/lib/types/ink/components/ErrorOverview.d.ts +7 -0
  1164. package/lib/types/ink/components/ErrorOverview.d.ts.map +1 -0
  1165. package/lib/types/ink/components/ErrorOverview.js +49 -0
  1166. package/lib/types/ink/components/Image.d.ts +28 -0
  1167. package/lib/types/ink/components/Image.d.ts.map +1 -0
  1168. package/lib/types/ink/components/Image.js +44 -0
  1169. package/lib/types/ink/components/Link.d.ts +8 -0
  1170. package/lib/types/ink/components/Link.d.ts.map +1 -0
  1171. package/lib/types/ink/components/Link.js +7 -0
  1172. package/lib/types/ink/components/Newline.d.ts +7 -0
  1173. package/lib/types/ink/components/Newline.d.ts.map +1 -0
  1174. package/lib/types/ink/components/Newline.js +5 -0
  1175. package/lib/types/ink/components/NoSelect.d.ts +9 -0
  1176. package/lib/types/ink/components/NoSelect.d.ts.map +1 -0
  1177. package/lib/types/ink/components/NoSelect.js +6 -0
  1178. package/lib/types/ink/components/RawAnsi.d.ts +9 -0
  1179. package/lib/types/ink/components/RawAnsi.d.ts.map +1 -0
  1180. package/lib/types/ink/components/RawAnsi.js +7 -0
  1181. package/lib/types/ink/components/ScrollBox.d.ts +78 -0
  1182. package/lib/types/ink/components/ScrollBox.d.ts.map +1 -0
  1183. package/lib/types/ink/components/ScrollBox.js +309 -0
  1184. package/lib/types/ink/components/Spacer.d.ts +4 -0
  1185. package/lib/types/ink/components/Spacer.d.ts.map +1 -0
  1186. package/lib/types/ink/components/Spacer.js +6 -0
  1187. package/lib/types/ink/components/StdinContext.d.ts +32 -0
  1188. package/lib/types/ink/components/StdinContext.d.ts.map +1 -0
  1189. package/lib/types/ink/components/StdinContext.js +16 -0
  1190. package/lib/types/ink/components/TerminalFocusContext.d.ts +11 -0
  1191. package/lib/types/ink/components/TerminalFocusContext.d.ts.map +1 -0
  1192. package/lib/types/ink/components/TerminalFocusContext.js +11 -0
  1193. package/lib/types/ink/components/TerminalSizeContext.d.ts +6 -0
  1194. package/lib/types/ink/components/TerminalSizeContext.d.ts.map +1 -0
  1195. package/lib/types/ink/components/TerminalSizeContext.js +2 -0
  1196. package/lib/types/ink/components/Text.d.ts +64 -0
  1197. package/lib/types/ink/components/Text.d.ts.map +1 -0
  1198. package/lib/types/ink/components/Text.js +19 -0
  1199. package/lib/types/ink/constants.d.ts +12 -0
  1200. package/lib/types/ink/constants.d.ts.map +1 -0
  1201. package/lib/types/ink/constants.js +11 -0
  1202. package/lib/types/ink/cursor.d.ts +11 -0
  1203. package/lib/types/ink/cursor.d.ts.map +1 -0
  1204. package/lib/types/ink/cursor.js +1 -0
  1205. package/lib/types/ink/devtools.d.ts +7 -0
  1206. package/lib/types/ink/devtools.d.ts.map +1 -0
  1207. package/lib/types/ink/devtools.js +1 -0
  1208. package/lib/types/ink/dom.d.ts +194 -0
  1209. package/lib/types/ink/dom.d.ts.map +1 -0
  1210. package/lib/types/ink/dom.js +424 -0
  1211. package/lib/types/ink/events/click-event.d.ts +23 -0
  1212. package/lib/types/ink/events/click-event.d.ts.map +1 -0
  1213. package/lib/types/ink/events/click-event.js +33 -0
  1214. package/lib/types/ink/events/context-menu-event.d.ts +19 -0
  1215. package/lib/types/ink/events/context-menu-event.d.ts.map +1 -0
  1216. package/lib/types/ink/events/context-menu-event.js +20 -0
  1217. package/lib/types/ink/events/dispatcher.d.ts +63 -0
  1218. package/lib/types/ink/events/dispatcher.d.ts.map +1 -0
  1219. package/lib/types/ink/events/dispatcher.js +194 -0
  1220. package/lib/types/ink/events/drag-event.d.ts +44 -0
  1221. package/lib/types/ink/events/drag-event.d.ts.map +1 -0
  1222. package/lib/types/ink/events/drag-event.js +39 -0
  1223. package/lib/types/ink/events/emitter.d.ts +20 -0
  1224. package/lib/types/ink/events/emitter.d.ts.map +1 -0
  1225. package/lib/types/ink/events/emitter.js +43 -0
  1226. package/lib/types/ink/events/event-handlers.d.ts +65 -0
  1227. package/lib/types/ink/events/event-handlers.d.ts.map +1 -0
  1228. package/lib/types/ink/events/event-handlers.js +40 -0
  1229. package/lib/types/ink/events/event.d.ts +19 -0
  1230. package/lib/types/ink/events/event.d.ts.map +1 -0
  1231. package/lib/types/ink/events/event.js +22 -0
  1232. package/lib/types/ink/events/focus-event.d.ts +19 -0
  1233. package/lib/types/ink/events/focus-event.d.ts.map +1 -0
  1234. package/lib/types/ink/events/focus-event.js +21 -0
  1235. package/lib/types/ink/events/input-event.d.ts +72 -0
  1236. package/lib/types/ink/events/input-event.d.ts.map +1 -0
  1237. package/lib/types/ink/events/input-event.js +185 -0
  1238. package/lib/types/ink/events/keyboard-event.d.ts +40 -0
  1239. package/lib/types/ink/events/keyboard-event.d.ts.map +1 -0
  1240. package/lib/types/ink/events/keyboard-event.js +65 -0
  1241. package/lib/types/ink/events/paste-event.d.ts +11 -0
  1242. package/lib/types/ink/events/paste-event.d.ts.map +1 -0
  1243. package/lib/types/ink/events/paste-event.js +13 -0
  1244. package/lib/types/ink/events/pointer-event.d.ts +61 -0
  1245. package/lib/types/ink/events/pointer-event.d.ts.map +1 -0
  1246. package/lib/types/ink/events/pointer-event.js +61 -0
  1247. package/lib/types/ink/events/resize-event.d.ts +13 -0
  1248. package/lib/types/ink/events/resize-event.d.ts.map +1 -0
  1249. package/lib/types/ink/events/resize-event.js +16 -0
  1250. package/lib/types/ink/events/terminal-event.d.ts +112 -0
  1251. package/lib/types/ink/events/terminal-event.d.ts.map +1 -0
  1252. package/lib/types/ink/events/terminal-event.js +131 -0
  1253. package/lib/types/ink/events/terminal-focus-event.d.ts +21 -0
  1254. package/lib/types/ink/events/terminal-focus-event.d.ts.map +1 -0
  1255. package/lib/types/ink/events/terminal-focus-event.js +18 -0
  1256. package/lib/types/ink/events/wheel-event.d.ts +17 -0
  1257. package/lib/types/ink/events/wheel-event.d.ts.map +1 -0
  1258. package/lib/types/ink/events/wheel-event.js +20 -0
  1259. package/lib/types/ink/flush-tick.d.ts +26 -0
  1260. package/lib/types/ink/flush-tick.d.ts.map +1 -0
  1261. package/lib/types/ink/flush-tick.js +31 -0
  1262. package/lib/types/ink/focus.d.ts +74 -0
  1263. package/lib/types/ink/focus.d.ts.map +1 -0
  1264. package/lib/types/ink/focus.js +188 -0
  1265. package/lib/types/ink/frame.d.ts +128 -0
  1266. package/lib/types/ink/frame.d.ts.map +1 -0
  1267. package/lib/types/ink/frame.js +43 -0
  1268. package/lib/types/ink/geometry-trace.d.ts +51 -0
  1269. package/lib/types/ink/geometry-trace.d.ts.map +1 -0
  1270. package/lib/types/ink/geometry-trace.js +83 -0
  1271. package/lib/types/ink/get-max-width.d.ts +12 -0
  1272. package/lib/types/ink/get-max-width.d.ts.map +1 -0
  1273. package/lib/types/ink/get-max-width.js +12 -0
  1274. package/lib/types/ink/hit-test.d.ts +181 -0
  1275. package/lib/types/ink/hit-test.d.ts.map +1 -0
  1276. package/lib/types/ink/hit-test.js +540 -0
  1277. package/lib/types/ink/hooks/use-animation-frame.d.ts +27 -0
  1278. package/lib/types/ink/hooks/use-animation-frame.d.ts.map +1 -0
  1279. package/lib/types/ink/hooks/use-animation-frame.js +48 -0
  1280. package/lib/types/ink/hooks/use-app.d.ts +7 -0
  1281. package/lib/types/ink/hooks/use-app.d.ts.map +1 -0
  1282. package/lib/types/ink/hooks/use-app.js +7 -0
  1283. package/lib/types/ink/hooks/use-copy-on-select.d.ts +26 -0
  1284. package/lib/types/ink/hooks/use-copy-on-select.d.ts.map +1 -0
  1285. package/lib/types/ink/hooks/use-copy-on-select.js +54 -0
  1286. package/lib/types/ink/hooks/use-declared-cursor.d.ts +31 -0
  1287. package/lib/types/ink/hooks/use-declared-cursor.d.ts.map +1 -0
  1288. package/lib/types/ink/hooks/use-declared-cursor.js +65 -0
  1289. package/lib/types/ink/hooks/use-input.d.ts +41 -0
  1290. package/lib/types/ink/hooks/use-input.d.ts.map +1 -0
  1291. package/lib/types/ink/hooks/use-input.js +81 -0
  1292. package/lib/types/ink/hooks/use-interval.d.ts +23 -0
  1293. package/lib/types/ink/hooks/use-interval.d.ts.map +1 -0
  1294. package/lib/types/ink/hooks/use-interval.js +58 -0
  1295. package/lib/types/ink/hooks/use-search-highlight.d.ts +34 -0
  1296. package/lib/types/ink/hooks/use-search-highlight.d.ts.map +1 -0
  1297. package/lib/types/ink/hooks/use-search-highlight.js +35 -0
  1298. package/lib/types/ink/hooks/use-selection.d.ts +44 -0
  1299. package/lib/types/ink/hooks/use-selection.d.ts.map +1 -0
  1300. package/lib/types/ink/hooks/use-selection.js +64 -0
  1301. package/lib/types/ink/hooks/use-stdin.d.ts +8 -0
  1302. package/lib/types/ink/hooks/use-stdin.d.ts.map +1 -0
  1303. package/lib/types/ink/hooks/use-stdin.js +8 -0
  1304. package/lib/types/ink/hooks/use-tab-status.d.ts +18 -0
  1305. package/lib/types/ink/hooks/use-tab-status.d.ts.map +1 -0
  1306. package/lib/types/ink/hooks/use-tab-status.js +58 -0
  1307. package/lib/types/ink/hooks/use-terminal-focus.d.ts +11 -0
  1308. package/lib/types/ink/hooks/use-terminal-focus.d.ts.map +1 -0
  1309. package/lib/types/ink/hooks/use-terminal-focus.js +15 -0
  1310. package/lib/types/ink/hooks/use-terminal-images.d.ts +14 -0
  1311. package/lib/types/ink/hooks/use-terminal-images.d.ts.map +1 -0
  1312. package/lib/types/ink/hooks/use-terminal-images.js +22 -0
  1313. package/lib/types/ink/hooks/use-terminal-size.d.ts +6 -0
  1314. package/lib/types/ink/hooks/use-terminal-size.d.ts.map +1 -0
  1315. package/lib/types/ink/hooks/use-terminal-size.js +12 -0
  1316. package/lib/types/ink/hooks/use-terminal-title.d.ts +14 -0
  1317. package/lib/types/ink/hooks/use-terminal-title.d.ts.map +1 -0
  1318. package/lib/types/ink/hooks/use-terminal-title.js +30 -0
  1319. package/lib/types/ink/hooks/use-terminal-viewport.d.ts +32 -0
  1320. package/lib/types/ink/hooks/use-terminal-viewport.d.ts.map +1 -0
  1321. package/lib/types/ink/hooks/use-terminal-viewport.js +79 -0
  1322. package/lib/types/ink/ink.d.ts +571 -0
  1323. package/lib/types/ink/ink.d.ts.map +1 -0
  1324. package/lib/types/ink/ink.js +2818 -0
  1325. package/lib/types/ink/input-suppression.d.ts +20 -0
  1326. package/lib/types/ink/input-suppression.d.ts.map +1 -0
  1327. package/lib/types/ink/input-suppression.js +26 -0
  1328. package/lib/types/ink/instances.d.ts +10 -0
  1329. package/lib/types/ink/instances.d.ts.map +1 -0
  1330. package/lib/types/ink/instances.js +13 -0
  1331. package/lib/types/ink/kitty-graphics.d.ts +41 -0
  1332. package/lib/types/ink/kitty-graphics.d.ts.map +1 -0
  1333. package/lib/types/ink/kitty-graphics.js +229 -0
  1334. package/lib/types/ink/layout/engine.d.ts +7 -0
  1335. package/lib/types/ink/layout/engine.d.ts.map +1 -0
  1336. package/lib/types/ink/layout/engine.js +8 -0
  1337. package/lib/types/ink/layout/geometry.d.ts +86 -0
  1338. package/lib/types/ink/layout/geometry.d.ts.map +1 -0
  1339. package/lib/types/ink/layout/geometry.js +95 -0
  1340. package/lib/types/ink/layout/node.d.ts +153 -0
  1341. package/lib/types/ink/layout/node.d.ts.map +1 -0
  1342. package/lib/types/ink/layout/node.js +72 -0
  1343. package/lib/types/ink/layout/yoga.d.ts +70 -0
  1344. package/lib/types/ink/layout/yoga.d.ts.map +1 -0
  1345. package/lib/types/ink/layout/yoga.js +252 -0
  1346. package/lib/types/ink/line-width-cache.d.ts +9 -0
  1347. package/lib/types/ink/line-width-cache.d.ts.map +1 -0
  1348. package/lib/types/ink/line-width-cache.js +45 -0
  1349. package/lib/types/ink/log-update.d.ts +57 -0
  1350. package/lib/types/ink/log-update.d.ts.map +1 -0
  1351. package/lib/types/ink/log-update.js +1000 -0
  1352. package/lib/types/ink/measure-element.d.ts +19 -0
  1353. package/lib/types/ink/measure-element.d.ts.map +1 -0
  1354. package/lib/types/ink/measure-element.js +10 -0
  1355. package/lib/types/ink/measure-text.d.ts +13 -0
  1356. package/lib/types/ink/measure-text.d.ts.map +1 -0
  1357. package/lib/types/ink/measure-text.js +38 -0
  1358. package/lib/types/ink/node-cache.d.ts +54 -0
  1359. package/lib/types/ink/node-cache.d.ts.map +1 -0
  1360. package/lib/types/ink/node-cache.js +45 -0
  1361. package/lib/types/ink/optimizer.d.ts +18 -0
  1362. package/lib/types/ink/optimizer.d.ts.map +1 -0
  1363. package/lib/types/ink/optimizer.js +83 -0
  1364. package/lib/types/ink/output.d.ts +300 -0
  1365. package/lib/types/ink/output.d.ts.map +1 -0
  1366. package/lib/types/ink/output.js +1205 -0
  1367. package/lib/types/ink/parse-keypress.d.ts +217 -0
  1368. package/lib/types/ink/parse-keypress.d.ts.map +1 -0
  1369. package/lib/types/ink/parse-keypress.js +1550 -0
  1370. package/lib/types/ink/reconciler.d.ts +43 -0
  1371. package/lib/types/ink/reconciler.d.ts.map +1 -0
  1372. package/lib/types/ink/reconciler.js +414 -0
  1373. package/lib/types/ink/render-border.d.ts +41 -0
  1374. package/lib/types/ink/render-border.d.ts.map +1 -0
  1375. package/lib/types/ink/render-border.js +159 -0
  1376. package/lib/types/ink/render-node-to-output.d.ts +199 -0
  1377. package/lib/types/ink/render-node-to-output.d.ts.map +1 -0
  1378. package/lib/types/ink/render-node-to-output.js +1758 -0
  1379. package/lib/types/ink/render-to-screen.d.ts +65 -0
  1380. package/lib/types/ink/render-to-screen.d.ts.map +1 -0
  1381. package/lib/types/ink/render-to-screen.js +189 -0
  1382. package/lib/types/ink/renderer.d.ts +34 -0
  1383. package/lib/types/ink/renderer.d.ts.map +1 -0
  1384. package/lib/types/ink/renderer.js +181 -0
  1385. package/lib/types/ink/root.d.ts +109 -0
  1386. package/lib/types/ink/root.d.ts.map +1 -0
  1387. package/lib/types/ink/root.js +96 -0
  1388. package/lib/types/ink/screen.d.ts +545 -0
  1389. package/lib/types/ink/screen.d.ts.map +1 -0
  1390. package/lib/types/ink/screen.js +1607 -0
  1391. package/lib/types/ink/selection.d.ts +529 -0
  1392. package/lib/types/ink/selection.d.ts.map +1 -0
  1393. package/lib/types/ink/selection.js +1292 -0
  1394. package/lib/types/ink/sixel-codec.d.ts +41 -0
  1395. package/lib/types/ink/sixel-codec.d.ts.map +1 -0
  1396. package/lib/types/ink/sixel-codec.js +128 -0
  1397. package/lib/types/ink/sixel-graphics.d.ts +74 -0
  1398. package/lib/types/ink/sixel-graphics.d.ts.map +1 -0
  1399. package/lib/types/ink/sixel-graphics.js +498 -0
  1400. package/lib/types/ink/sixel-worker.d.ts +2 -0
  1401. package/lib/types/ink/sixel-worker.d.ts.map +1 -0
  1402. package/lib/types/ink/sixel-worker.js +12 -0
  1403. package/lib/types/ink/squash-text-nodes.d.ts +30 -0
  1404. package/lib/types/ink/squash-text-nodes.d.ts.map +1 -0
  1405. package/lib/types/ink/squash-text-nodes.js +63 -0
  1406. package/lib/types/ink/stringWidth.d.ts +3 -0
  1407. package/lib/types/ink/stringWidth.d.ts.map +1 -0
  1408. package/lib/types/ink/stringWidth.js +248 -0
  1409. package/lib/types/ink/styles.d.ts +346 -0
  1410. package/lib/types/ink/styles.d.ts.map +1 -0
  1411. package/lib/types/ink/styles.js +307 -0
  1412. package/lib/types/ink/supports-hyperlinks.d.ts +20 -0
  1413. package/lib/types/ink/supports-hyperlinks.d.ts.map +1 -0
  1414. package/lib/types/ink/supports-hyperlinks.js +44 -0
  1415. package/lib/types/ink/tabstops.d.ts +10 -0
  1416. package/lib/types/ink/tabstops.d.ts.map +1 -0
  1417. package/lib/types/ink/tabstops.js +47 -0
  1418. package/lib/types/ink/terminal-focus-state.d.ts +35 -0
  1419. package/lib/types/ink/terminal-focus-state.d.ts.map +1 -0
  1420. package/lib/types/ink/terminal-focus-state.js +57 -0
  1421. package/lib/types/ink/terminal-image-protocol.d.ts +4 -0
  1422. package/lib/types/ink/terminal-image-protocol.d.ts.map +1 -0
  1423. package/lib/types/ink/terminal-image-protocol.js +8 -0
  1424. package/lib/types/ink/terminal-image.d.ts +102 -0
  1425. package/lib/types/ink/terminal-image.d.ts.map +1 -0
  1426. package/lib/types/ink/terminal-image.js +223 -0
  1427. package/lib/types/ink/terminal-querier.d.ts +203 -0
  1428. package/lib/types/ink/terminal-querier.d.ts.map +1 -0
  1429. package/lib/types/ink/terminal-querier.js +286 -0
  1430. package/lib/types/ink/terminal.d.ts +192 -0
  1431. package/lib/types/ink/terminal.d.ts.map +1 -0
  1432. package/lib/types/ink/terminal.js +436 -0
  1433. package/lib/types/ink/termio/ansi.d.ts +75 -0
  1434. package/lib/types/ink/termio/ansi.d.ts.map +1 -0
  1435. package/lib/types/ink/termio/ansi.js +79 -0
  1436. package/lib/types/ink/termio/csi.d.ts +263 -0
  1437. package/lib/types/ink/termio/csi.d.ts.map +1 -0
  1438. package/lib/types/ink/termio/csi.js +367 -0
  1439. package/lib/types/ink/termio/dec.d.ts +61 -0
  1440. package/lib/types/ink/termio/dec.d.ts.map +1 -0
  1441. package/lib/types/ink/termio/dec.js +76 -0
  1442. package/lib/types/ink/termio/esc.d.ts +15 -0
  1443. package/lib/types/ink/termio/esc.d.ts.map +1 -0
  1444. package/lib/types/ink/termio/esc.js +57 -0
  1445. package/lib/types/ink/termio/osc.d.ts +198 -0
  1446. package/lib/types/ink/termio/osc.d.ts.map +1 -0
  1447. package/lib/types/ink/termio/osc.js +475 -0
  1448. package/lib/types/ink/termio/parser.d.ts +46 -0
  1449. package/lib/types/ink/termio/parser.d.ts.map +1 -0
  1450. package/lib/types/ink/termio/parser.js +366 -0
  1451. package/lib/types/ink/termio/sgr.d.ts +17 -0
  1452. package/lib/types/ink/termio/sgr.d.ts.map +1 -0
  1453. package/lib/types/ink/termio/sgr.js +300 -0
  1454. package/lib/types/ink/termio/tokenize.d.ts +56 -0
  1455. package/lib/types/ink/termio/tokenize.d.ts.map +1 -0
  1456. package/lib/types/ink/termio/tokenize.js +290 -0
  1457. package/lib/types/ink/termio/types.d.ts +211 -0
  1458. package/lib/types/ink/termio/types.d.ts.map +1 -0
  1459. package/lib/types/ink/termio/types.js +68 -0
  1460. package/lib/types/ink/termio.d.ts +25 -0
  1461. package/lib/types/ink/termio.d.ts.map +1 -0
  1462. package/lib/types/ink/termio.js +24 -0
  1463. package/lib/types/ink/timeline-rail.d.ts +134 -0
  1464. package/lib/types/ink/timeline-rail.d.ts.map +1 -0
  1465. package/lib/types/ink/timeline-rail.js +175 -0
  1466. package/lib/types/ink/transcript-highlight.d.ts +25 -0
  1467. package/lib/types/ink/transcript-highlight.d.ts.map +1 -0
  1468. package/lib/types/ink/transcript-highlight.js +82 -0
  1469. package/lib/types/ink/truncateToWidth.d.ts +7 -0
  1470. package/lib/types/ink/truncateToWidth.d.ts.map +1 -0
  1471. package/lib/types/ink/truncateToWidth.js +18 -0
  1472. package/lib/types/ink/update-overflow-guard.d.ts +62 -0
  1473. package/lib/types/ink/update-overflow-guard.d.ts.map +1 -0
  1474. package/lib/types/ink/update-overflow-guard.js +164 -0
  1475. package/lib/types/ink/useTerminalNotification.d.ts +45 -0
  1476. package/lib/types/ink/useTerminalNotification.d.ts.map +1 -0
  1477. package/lib/types/ink/useTerminalNotification.js +70 -0
  1478. package/lib/types/ink/warn.d.ts +7 -0
  1479. package/lib/types/ink/warn.d.ts.map +1 -0
  1480. package/lib/types/ink/warn.js +15 -0
  1481. package/lib/types/ink/widest-line.d.ts +7 -0
  1482. package/lib/types/ink/widest-line.d.ts.map +1 -0
  1483. package/lib/types/ink/widest-line.js +19 -0
  1484. package/lib/types/ink/wrap-text.d.ts +10 -0
  1485. package/lib/types/ink/wrap-text.d.ts.map +1 -0
  1486. package/lib/types/ink/wrap-text.js +103 -0
  1487. package/lib/types/ink/wrapAnsi.d.ts +17 -0
  1488. package/lib/types/ink/wrapAnsi.d.ts.map +1 -0
  1489. package/lib/types/ink/wrapAnsi.js +38 -0
  1490. package/lib/types/jsx-runtime.d.ts +2 -0
  1491. package/lib/types/jsx-runtime.d.ts.map +1 -0
  1492. package/lib/types/jsx-runtime.js +13 -0
  1493. package/lib/types/migrationPrefs.d.ts +60 -0
  1494. package/lib/types/migrationPrefs.d.ts.map +1 -0
  1495. package/lib/types/migrationPrefs.js +97 -0
  1496. package/lib/types/minimalMode.d.ts +13 -0
  1497. package/lib/types/minimalMode.d.ts.map +1 -0
  1498. package/lib/types/minimalMode.js +17 -0
  1499. package/lib/types/modelGroups.d.ts +72 -0
  1500. package/lib/types/modelGroups.d.ts.map +1 -0
  1501. package/lib/types/modelGroups.js +97 -0
  1502. package/lib/types/modelPrefs.d.ts +37 -0
  1503. package/lib/types/modelPrefs.d.ts.map +1 -0
  1504. package/lib/types/modelPrefs.js +66 -0
  1505. package/lib/types/modelRecents.d.ts +39 -0
  1506. package/lib/types/modelRecents.d.ts.map +1 -0
  1507. package/lib/types/modelRecents.js +97 -0
  1508. package/lib/types/modelRoute.d.ts +87 -0
  1509. package/lib/types/modelRoute.d.ts.map +1 -0
  1510. package/lib/types/modelRoute.js +125 -0
  1511. package/lib/types/native-ts/yoga-layout/enums.d.ts +183 -0
  1512. package/lib/types/native-ts/yoga-layout/enums.d.ts.map +1 -0
  1513. package/lib/types/native-ts/yoga-layout/enums.js +150 -0
  1514. package/lib/types/native-ts/yoga-layout/index.d.ts +804 -0
  1515. package/lib/types/native-ts/yoga-layout/index.d.ts.map +1 -0
  1516. package/lib/types/native-ts/yoga-layout/index.js +2614 -0
  1517. package/lib/types/oauth.d.ts +15 -0
  1518. package/lib/types/oauth.d.ts.map +1 -0
  1519. package/lib/types/oauth.js +14 -0
  1520. package/lib/types/plugin-host.d.ts +14 -0
  1521. package/lib/types/plugin-host.d.ts.map +1 -0
  1522. package/lib/types/plugin-host.js +19 -0
  1523. package/lib/types/presetPrefs.d.ts +30 -0
  1524. package/lib/types/presetPrefs.d.ts.map +1 -0
  1525. package/lib/types/presetPrefs.js +66 -0
  1526. package/lib/types/reload.d.ts +109 -0
  1527. package/lib/types/reload.d.ts.map +1 -0
  1528. package/lib/types/reload.js +118 -0
  1529. package/lib/types/scenes.d.ts +4 -0
  1530. package/lib/types/scenes.d.ts.map +1 -0
  1531. package/lib/types/scenes.js +4 -0
  1532. package/lib/types/screens/Chat.d.ts +82 -0
  1533. package/lib/types/screens/Chat.d.ts.map +1 -0
  1534. package/lib/types/screens/Chat.js +4299 -0
  1535. package/lib/types/screens/SessionSupervisor.d.ts +84 -0
  1536. package/lib/types/screens/SessionSupervisor.d.ts.map +1 -0
  1537. package/lib/types/screens/SessionSupervisor.js +350 -0
  1538. package/lib/types/screens/SessionTree.d.ts +27 -0
  1539. package/lib/types/screens/SessionTree.d.ts.map +1 -0
  1540. package/lib/types/screens/SessionTree.js +583 -0
  1541. package/lib/types/screens/Settings.d.ts +22 -0
  1542. package/lib/types/screens/Settings.d.ts.map +1 -0
  1543. package/lib/types/screens/Settings.js +592 -0
  1544. package/lib/types/screens/StatusLine.d.ts +48 -0
  1545. package/lib/types/screens/StatusLine.d.ts.map +1 -0
  1546. package/lib/types/screens/StatusLine.js +453 -0
  1547. package/lib/types/screens/StatusMetrics.d.ts +176 -0
  1548. package/lib/types/screens/StatusMetrics.d.ts.map +1 -0
  1549. package/lib/types/screens/StatusMetrics.js +372 -0
  1550. package/lib/types/screens/TrajectoryScene.d.ts +16 -0
  1551. package/lib/types/screens/TrajectoryScene.d.ts.map +1 -0
  1552. package/lib/types/screens/TrajectoryScene.js +374 -0
  1553. package/lib/types/screens/chatOverlay.d.ts +267 -0
  1554. package/lib/types/screens/chatOverlay.d.ts.map +1 -0
  1555. package/lib/types/screens/chatOverlay.js +132 -0
  1556. package/lib/types/screens/sessionSupervisor/model.d.ts +83 -0
  1557. package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -0
  1558. package/lib/types/screens/sessionSupervisor/model.js +69 -0
  1559. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts +120 -0
  1560. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -0
  1561. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +639 -0
  1562. package/lib/types/sessionHistory.d.ts +59 -0
  1563. package/lib/types/sessionHistory.d.ts.map +1 -0
  1564. package/lib/types/sessionHistory.js +223 -0
  1565. package/lib/types/sessionModes.d.ts +83 -0
  1566. package/lib/types/sessionModes.d.ts.map +1 -0
  1567. package/lib/types/sessionModes.js +141 -0
  1568. package/lib/types/sessionMounts.d.ts +272 -0
  1569. package/lib/types/sessionMounts.d.ts.map +1 -0
  1570. package/lib/types/sessionMounts.js +706 -0
  1571. package/lib/types/sessionPins.d.ts +33 -0
  1572. package/lib/types/sessionPins.d.ts.map +1 -0
  1573. package/lib/types/sessionPins.js +181 -0
  1574. package/lib/types/sessions/format.d.ts +125 -0
  1575. package/lib/types/sessions/format.d.ts.map +1 -0
  1576. package/lib/types/sessions/format.js +276 -0
  1577. package/lib/types/sessions/resumeFailure.d.ts +38 -0
  1578. package/lib/types/sessions/resumeFailure.d.ts.map +1 -0
  1579. package/lib/types/sessions/resumeFailure.js +58 -0
  1580. package/lib/types/sessions/view.d.ts +162 -0
  1581. package/lib/types/sessions/view.d.ts.map +1 -0
  1582. package/lib/types/sessions/view.js +350 -0
  1583. package/lib/types/settings-sections.d.ts +4 -0
  1584. package/lib/types/settings-sections.d.ts.map +1 -0
  1585. package/lib/types/settings-sections.js +4 -0
  1586. package/lib/types/terminal-utils/cliHighlight.d.ts +20 -0
  1587. package/lib/types/terminal-utils/cliHighlight.d.ts.map +1 -0
  1588. package/lib/types/terminal-utils/cliHighlight.js +53 -0
  1589. package/lib/types/terminal-utils/figures.d.ts +26 -0
  1590. package/lib/types/terminal-utils/figures.d.ts.map +1 -0
  1591. package/lib/types/terminal-utils/figures.js +36 -0
  1592. package/lib/types/terminal-utils/format.d.ts +35 -0
  1593. package/lib/types/terminal-utils/format.d.ts.map +1 -0
  1594. package/lib/types/terminal-utils/format.js +63 -0
  1595. package/lib/types/terminal-utils/hash.d.ts +25 -0
  1596. package/lib/types/terminal-utils/hash.d.ts.map +1 -0
  1597. package/lib/types/terminal-utils/hash.js +41 -0
  1598. package/lib/types/terminal-utils/hyperlink.d.ts +27 -0
  1599. package/lib/types/terminal-utils/hyperlink.d.ts.map +1 -0
  1600. package/lib/types/terminal-utils/hyperlink.js +70 -0
  1601. package/lib/types/terminal-utils/markdown.d.ts +58 -0
  1602. package/lib/types/terminal-utils/markdown.d.ts.map +1 -0
  1603. package/lib/types/terminal-utils/markdown.js +441 -0
  1604. package/lib/types/terminal-utils/mermaid.d.ts +44 -0
  1605. package/lib/types/terminal-utils/mermaid.d.ts.map +1 -0
  1606. package/lib/types/terminal-utils/mermaid.js +83 -0
  1607. package/lib/types/terminal-utils/sessionColors.d.ts +27 -0
  1608. package/lib/types/terminal-utils/sessionColors.d.ts.map +1 -0
  1609. package/lib/types/terminal-utils/sessionColors.js +39 -0
  1610. package/lib/types/terminal-utils/spinnerVerbs.d.ts +3 -0
  1611. package/lib/types/terminal-utils/spinnerVerbs.d.ts.map +1 -0
  1612. package/lib/types/terminal-utils/spinnerVerbs.js +21 -0
  1613. package/lib/types/terminal-utils/syntaxRuns.d.ts +16 -0
  1614. package/lib/types/terminal-utils/syntaxRuns.d.ts.map +1 -0
  1615. package/lib/types/terminal-utils/syntaxRuns.js +79 -0
  1616. package/lib/types/terminal-utils/syntaxTheme.d.ts +12 -0
  1617. package/lib/types/terminal-utils/syntaxTheme.d.ts.map +1 -0
  1618. package/lib/types/terminal-utils/syntaxTheme.js +76 -0
  1619. package/lib/types/theme.d.ts +201 -0
  1620. package/lib/types/theme.d.ts.map +1 -0
  1621. package/lib/types/theme.js +525 -0
  1622. package/lib/types/themeCatalog.d.ts +36 -0
  1623. package/lib/types/themeCatalog.d.ts.map +1 -0
  1624. package/lib/types/themeCatalog.js +159 -0
  1625. package/lib/types/themePrefs.d.ts +28 -0
  1626. package/lib/types/themePrefs.d.ts.map +1 -0
  1627. package/lib/types/themePrefs.js +59 -0
  1628. package/lib/types/tips.d.ts +30 -0
  1629. package/lib/types/tips.d.ts.map +1 -0
  1630. package/lib/types/tips.js +899 -0
  1631. package/lib/types/trajectory/effortIgnition.d.ts +66 -0
  1632. package/lib/types/trajectory/effortIgnition.d.ts.map +1 -0
  1633. package/lib/types/trajectory/effortIgnition.js +142 -0
  1634. package/lib/types/trajectory/format.d.ts +100 -0
  1635. package/lib/types/trajectory/format.d.ts.map +1 -0
  1636. package/lib/types/trajectory/format.js +213 -0
  1637. package/lib/types/trajectory/motion.d.ts +99 -0
  1638. package/lib/types/trajectory/motion.d.ts.map +1 -0
  1639. package/lib/types/trajectory/motion.js +143 -0
  1640. package/lib/types/trajectory/query.d.ts +83 -0
  1641. package/lib/types/trajectory/query.d.ts.map +1 -0
  1642. package/lib/types/trajectory/query.js +187 -0
  1643. package/lib/types/trajectoryPrefs.d.ts +36 -0
  1644. package/lib/types/trajectoryPrefs.d.ts.map +1 -0
  1645. package/lib/types/trajectoryPrefs.js +65 -0
  1646. package/lib/types/tuiDisplayPrefs.d.ts +49 -0
  1647. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -0
  1648. package/lib/types/tuiDisplayPrefs.js +168 -0
  1649. package/lib/types/ui.d.ts +29 -0
  1650. package/lib/types/ui.d.ts.map +1 -0
  1651. package/lib/types/ui.js +25 -0
  1652. package/lib/types/update.d.ts +550 -0
  1653. package/lib/types/update.d.ts.map +1 -0
  1654. package/lib/types/update.js +1751 -0
  1655. package/lib/types/utils/clipboard.d.ts +122 -0
  1656. package/lib/types/utils/clipboard.d.ts.map +1 -0
  1657. package/lib/types/utils/clipboard.js +577 -0
  1658. package/lib/types/utils/credentials.d.ts +13 -0
  1659. package/lib/types/utils/credentials.d.ts.map +1 -0
  1660. package/lib/types/utils/credentials.js +41 -0
  1661. package/lib/types/utils/debug.d.ts +18 -0
  1662. package/lib/types/utils/debug.d.ts.map +1 -0
  1663. package/lib/types/utils/debug.js +37 -0
  1664. package/lib/types/utils/earlyInput.d.ts +6 -0
  1665. package/lib/types/utils/earlyInput.d.ts.map +1 -0
  1666. package/lib/types/utils/earlyInput.js +5 -0
  1667. package/lib/types/utils/env.d.ts +8 -0
  1668. package/lib/types/utils/env.d.ts.map +1 -0
  1669. package/lib/types/utils/env.js +7 -0
  1670. package/lib/types/utils/envUtils.d.ts +8 -0
  1671. package/lib/types/utils/envUtils.d.ts.map +1 -0
  1672. package/lib/types/utils/envUtils.js +13 -0
  1673. package/lib/types/utils/execFileNoThrow.d.ts +17 -0
  1674. package/lib/types/utils/execFileNoThrow.d.ts.map +1 -0
  1675. package/lib/types/utils/execFileNoThrow.js +65 -0
  1676. package/lib/types/utils/externalEditor.d.ts +116 -0
  1677. package/lib/types/utils/externalEditor.d.ts.map +1 -0
  1678. package/lib/types/utils/externalEditor.js +270 -0
  1679. package/lib/types/utils/fileSuggestions.d.ts +12 -0
  1680. package/lib/types/utils/fileSuggestions.d.ts.map +1 -0
  1681. package/lib/types/utils/fileSuggestions.js +40 -0
  1682. package/lib/types/utils/fileTarget.d.ts +46 -0
  1683. package/lib/types/utils/fileTarget.d.ts.map +1 -0
  1684. package/lib/types/utils/fileTarget.js +178 -0
  1685. package/lib/types/utils/fold-long-lines.d.ts +38 -0
  1686. package/lib/types/utils/fold-long-lines.d.ts.map +1 -0
  1687. package/lib/types/utils/fold-long-lines.js +91 -0
  1688. package/lib/types/utils/fullscreen.d.ts +7 -0
  1689. package/lib/types/utils/fullscreen.d.ts.map +1 -0
  1690. package/lib/types/utils/fullscreen.js +9 -0
  1691. package/lib/types/utils/imageResize.d.ts +90 -0
  1692. package/lib/types/utils/imageResize.d.ts.map +1 -0
  1693. package/lib/types/utils/imageResize.js +272 -0
  1694. package/lib/types/utils/intl.d.ts +7 -0
  1695. package/lib/types/utils/intl.d.ts.map +1 -0
  1696. package/lib/types/utils/intl.js +9 -0
  1697. package/lib/types/utils/keymap.d.ts +138 -0
  1698. package/lib/types/utils/keymap.d.ts.map +1 -0
  1699. package/lib/types/utils/keymap.js +351 -0
  1700. package/lib/types/utils/loaded-context.d.ts +25 -0
  1701. package/lib/types/utils/loaded-context.d.ts.map +1 -0
  1702. package/lib/types/utils/loaded-context.js +72 -0
  1703. package/lib/types/utils/log.d.ts +7 -0
  1704. package/lib/types/utils/log.d.ts.map +1 -0
  1705. package/lib/types/utils/log.js +9 -0
  1706. package/lib/types/utils/mentions.d.ts +53 -0
  1707. package/lib/types/utils/mentions.d.ts.map +1 -0
  1708. package/lib/types/utils/mentions.js +133 -0
  1709. package/lib/types/utils/modifiers.d.ts +43 -0
  1710. package/lib/types/utils/modifiers.d.ts.map +1 -0
  1711. package/lib/types/utils/modifiers.js +45 -0
  1712. package/lib/types/utils/narration.d.ts +11 -0
  1713. package/lib/types/utils/narration.d.ts.map +1 -0
  1714. package/lib/types/utils/narration.js +16 -0
  1715. package/lib/types/utils/openExternal.d.ts +50 -0
  1716. package/lib/types/utils/openExternal.d.ts.map +1 -0
  1717. package/lib/types/utils/openExternal.js +170 -0
  1718. package/lib/types/utils/pastedImagePath.d.ts +51 -0
  1719. package/lib/types/utils/pastedImagePath.d.ts.map +1 -0
  1720. package/lib/types/utils/pastedImagePath.js +194 -0
  1721. package/lib/types/utils/paths.d.ts +16 -0
  1722. package/lib/types/utils/paths.d.ts.map +1 -0
  1723. package/lib/types/utils/paths.js +19 -0
  1724. package/lib/types/utils/semver.d.ts +9 -0
  1725. package/lib/types/utils/semver.d.ts.map +1 -0
  1726. package/lib/types/utils/semver.js +24 -0
  1727. package/lib/types/utils/shellQuote.d.ts +14 -0
  1728. package/lib/types/utils/shellQuote.d.ts.map +1 -0
  1729. package/lib/types/utils/shellQuote.js +39 -0
  1730. package/lib/types/utils/sliceAnsi.d.ts +12 -0
  1731. package/lib/types/utils/sliceAnsi.d.ts.map +1 -0
  1732. package/lib/types/utils/sliceAnsi.js +79 -0
  1733. package/lib/types/utils/truncateMiddle.d.ts +9 -0
  1734. package/lib/types/utils/truncateMiddle.d.ts.map +1 -0
  1735. package/lib/types/utils/truncateMiddle.js +28 -0
  1736. package/lib/types/utils/urlGuard.d.ts +28 -0
  1737. package/lib/types/utils/urlGuard.d.ts.map +1 -0
  1738. package/lib/types/utils/urlGuard.js +21 -0
  1739. package/lib/types/utils/workspaceRoot.d.ts +21 -0
  1740. package/lib/types/utils/workspaceRoot.d.ts.map +1 -0
  1741. package/lib/types/utils/workspaceRoot.js +47 -0
  1742. package/lib/types/working-activity.d.ts +32 -0
  1743. package/lib/types/working-activity.d.ts.map +1 -0
  1744. package/lib/types/working-activity.js +38 -0
  1745. package/lib/types/workspaces.d.ts +5 -0
  1746. package/lib/types/workspaces.d.ts.map +1 -0
  1747. package/lib/types/workspaces.js +4 -0
  1748. package/node_modules/@askdkc/dsh-auth/LICENSE +21 -0
  1749. package/node_modules/@askdkc/dsh-auth/README.ja.md +164 -0
  1750. package/node_modules/@askdkc/dsh-auth/README.md +163 -0
  1751. package/node_modules/@askdkc/dsh-auth/cordis.patch.yml +11 -0
  1752. package/node_modules/@askdkc/dsh-auth/dsh-plugin.json +44 -0
  1753. package/node_modules/@askdkc/dsh-auth/lib/command.d.ts +14 -0
  1754. package/node_modules/@askdkc/dsh-auth/lib/command.js +70 -0
  1755. package/node_modules/@askdkc/dsh-auth/lib/credentials.d.ts +63 -0
  1756. package/node_modules/@askdkc/dsh-auth/lib/credentials.js +204 -0
  1757. package/node_modules/@askdkc/dsh-auth/lib/custom-profiles.d.ts +26 -0
  1758. package/node_modules/@askdkc/dsh-auth/lib/custom-profiles.js +142 -0
  1759. package/node_modules/@askdkc/dsh-auth/lib/index.d.ts +96 -0
  1760. package/node_modules/@askdkc/dsh-auth/lib/index.js +263 -0
  1761. package/node_modules/@askdkc/dsh-auth/lib/interaction.d.ts +68 -0
  1762. package/node_modules/@askdkc/dsh-auth/lib/interaction.js +193 -0
  1763. package/node_modules/@askdkc/dsh-auth/lib/nous-oauth.d.ts +5 -0
  1764. package/node_modules/@askdkc/dsh-auth/lib/nous-oauth.js +112 -0
  1765. package/node_modules/@askdkc/dsh-auth/lib/opener.d.ts +32 -0
  1766. package/node_modules/@askdkc/dsh-auth/lib/opener.js +101 -0
  1767. package/node_modules/@askdkc/dsh-auth/lib/pi-ai.d.ts +23 -0
  1768. package/node_modules/@askdkc/dsh-auth/lib/pi-ai.js +27 -0
  1769. package/node_modules/@askdkc/dsh-auth/lib/profiles.d.ts +45 -0
  1770. package/node_modules/@askdkc/dsh-auth/lib/profiles.js +110 -0
  1771. package/node_modules/@askdkc/dsh-auth/lib/service.d.ts +80 -0
  1772. package/node_modules/@askdkc/dsh-auth/lib/service.js +224 -0
  1773. package/node_modules/@askdkc/dsh-auth/package.json +70 -0
  1774. package/node_modules/@dsh-std/command/CHANGELOG.md +8 -0
  1775. package/node_modules/@dsh-std/command/LICENSE +21 -0
  1776. package/node_modules/@dsh-std/command/README.md +26 -0
  1777. package/node_modules/@dsh-std/command/README.zh.md +28 -0
  1778. package/node_modules/@dsh-std/command/lib/index.d.ts +144 -0
  1779. package/node_modules/@dsh-std/command/lib/index.d.ts.map +1 -0
  1780. package/node_modules/@dsh-std/command/lib/index.js +252 -0
  1781. package/node_modules/@dsh-std/command/lib/index.js.map +1 -0
  1782. package/node_modules/@dsh-std/command/package.json +22 -0
  1783. package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  1784. package/node_modules/@dsh-std/connection/LICENSE +21 -0
  1785. package/node_modules/@dsh-std/connection/README.md +42 -0
  1786. package/node_modules/@dsh-std/connection/README.zh.md +42 -0
  1787. package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  1788. package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  1789. package/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  1790. package/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  1791. package/node_modules/@dsh-std/connection/lib/index.js +158 -0
  1792. package/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  1793. package/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  1794. package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  1795. package/node_modules/@dsh-std/connection/lib/memory.js +258 -0
  1796. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  1797. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  1798. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  1799. package/node_modules/@dsh-std/connection/package.json +20 -0
  1800. package/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  1801. package/node_modules/@dsh-std/core/LICENSE +21 -0
  1802. package/node_modules/@dsh-std/core/README.md +13 -0
  1803. package/node_modules/@dsh-std/core/README.zh.md +13 -0
  1804. package/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  1805. package/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  1806. package/node_modules/@dsh-std/core/lib/index.js +424 -0
  1807. package/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  1808. package/node_modules/@dsh-std/core/package.json +21 -0
  1809. package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
  1810. package/node_modules/@dsh-std/manifest/LICENSE +21 -0
  1811. package/node_modules/@dsh-std/manifest/README.md +5 -0
  1812. package/node_modules/@dsh-std/manifest/README.zh.md +5 -0
  1813. package/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
  1814. package/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
  1815. package/node_modules/@dsh-std/manifest/lib/index.js +625 -0
  1816. package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
  1817. package/node_modules/@dsh-std/manifest/package.json +20 -0
  1818. package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
  1819. package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -0
  1820. package/node_modules/@dsh-std/messages/LICENSE +21 -0
  1821. package/node_modules/@dsh-std/messages/README.md +5 -0
  1822. package/node_modules/@dsh-std/messages/README.zh.md +7 -0
  1823. package/node_modules/@dsh-std/messages/lib/index.d.ts +50 -0
  1824. package/node_modules/@dsh-std/messages/lib/index.d.ts.map +1 -0
  1825. package/node_modules/@dsh-std/messages/lib/index.js +151 -0
  1826. package/node_modules/@dsh-std/messages/lib/index.js.map +1 -0
  1827. package/node_modules/@dsh-std/messages/package.json +20 -0
  1828. package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -0
  1829. package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
  1830. package/node_modules/@dsh-std/presentation/LICENSE +21 -0
  1831. package/node_modules/@dsh-std/presentation/README.md +27 -0
  1832. package/node_modules/@dsh-std/presentation/README.zh.md +29 -0
  1833. package/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
  1834. package/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
  1835. package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
  1836. package/node_modules/@dsh-std/presentation/lib/index.d.ts +262 -0
  1837. package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
  1838. package/node_modules/@dsh-std/presentation/lib/index.js +550 -0
  1839. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
  1840. package/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
  1841. package/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
  1842. package/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
  1843. package/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
  1844. package/node_modules/@dsh-std/presentation/package.json +25 -0
  1845. package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -0
  1846. package/node_modules/@dsh-std/storage/LICENSE +21 -0
  1847. package/node_modules/@dsh-std/storage/README.md +5 -0
  1848. package/node_modules/@dsh-std/storage/README.zh.md +7 -0
  1849. package/node_modules/@dsh-std/storage/lib/index.d.ts +48 -0
  1850. package/node_modules/@dsh-std/storage/lib/index.d.ts.map +1 -0
  1851. package/node_modules/@dsh-std/storage/lib/index.js +104 -0
  1852. package/node_modules/@dsh-std/storage/lib/index.js.map +1 -0
  1853. package/node_modules/@dsh-std/storage/package.json +20 -0
  1854. package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -0
  1855. package/package.json +492 -0
  1856. package/presets/liangshen/.dsh-tui-managed.json +5 -0
  1857. package/presets/liangshen/agent.cordis.yml +425 -0
  1858. package/presets/liangshen/compaction-epoch.mjs +83 -0
  1859. package/presets/liangshen/custom-bash.mjs +301 -0
  1860. package/presets/liangshen/instruction-hint.mjs +190 -0
  1861. package/presets/liangshen/preset.yml +3 -0
  1862. package/presets/liangshen/session-events.mjs +8 -0
  1863. package/presets/liangshen/skill-search.mjs +141 -0
  1864. package/presets/liangshen/tool-bootstrap.mjs +300 -0
  1865. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  1866. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -0
  1867. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -0
  1868. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -0
  1869. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  1870. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  1871. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  1872. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  1873. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js +158 -0
  1874. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  1875. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  1876. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  1877. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +258 -0
  1878. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  1879. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  1880. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  1881. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -0
  1882. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  1883. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -0
  1884. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -0
  1885. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -0
  1886. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  1887. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  1888. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js +424 -0
  1889. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  1890. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -0
  1891. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
  1892. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -0
  1893. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -0
  1894. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -0
  1895. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
  1896. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
  1897. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js +625 -0
  1898. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
  1899. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -0
  1900. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
  1901. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
  1902. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -0
  1903. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -0
  1904. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -0
  1905. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
  1906. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
  1907. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
  1908. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts +262 -0
  1909. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
  1910. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +550 -0
  1911. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
  1912. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
  1913. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
  1914. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
  1915. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
  1916. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +25 -0
  1917. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  1918. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -0
  1919. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -0
  1920. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -0
  1921. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  1922. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  1923. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js +424 -0
  1924. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  1925. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -0
  1926. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  1927. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -0
  1928. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -0
  1929. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -0
  1930. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  1931. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  1932. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js +424 -0
  1933. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  1934. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -0
  1935. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  1936. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -0
  1937. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -0
  1938. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -0
  1939. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  1940. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  1941. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js +424 -0
  1942. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  1943. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -0
  1944. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  1945. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -0
  1946. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -0
  1947. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -0
  1948. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  1949. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  1950. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  1951. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  1952. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js +158 -0
  1953. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  1954. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  1955. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  1956. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +258 -0
  1957. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  1958. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  1959. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  1960. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -0
  1961. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  1962. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -0
  1963. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -0
  1964. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -0
  1965. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  1966. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  1967. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js +424 -0
  1968. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  1969. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -0
  1970. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  1971. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -0
  1972. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -0
  1973. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -0
  1974. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  1975. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  1976. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js +424 -0
  1977. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  1978. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -0
@@ -0,0 +1,3503 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import stripAnsi from 'strip-ansi';
4
+ import { constants as fsConstants } from 'node:fs';
5
+ import { open, unlink } from 'node:fs/promises';
6
+ import { basename, resolve } from 'node:path';
7
+ import { t } from '../i18n.js';
8
+ import { Box, Text, useInput, useTerminalSize, useTheme } from '../ui.js';
9
+ import { EffortChargeGlyph } from './EffortChargeGlyph.js';
10
+ import { EffortInputBorder } from './EffortInputBorder.js';
11
+ import { EffortTierBadge } from './EffortTierBadge.js';
12
+ import { isLightThemeActive } from '../theme.js';
13
+ import { sessionColorHex } from '../terminal-utils/sessionColors.js';
14
+ import { useDeclaredCursor } from '../ink/hooks/use-declared-cursor.js';
15
+ import { TerminalWriteContext } from '../ink/useTerminalNotification.js';
16
+ import { setClipboard } from '../ink/termio/osc.js';
17
+ import { noteAuxNumber } from '../ink/geometry-trace.js';
18
+ import instances from '../ink/instances.js';
19
+ import { stringWidth } from '../ink/stringWidth.js';
20
+ import { truncateToWidth } from '../ink/truncateToWidth.js';
21
+ import { getGraphemeSegmenter } from '../utils/intl.js';
22
+ import { formatClipboardInsert, readClipboard } from '../utils/clipboard.js';
23
+ import { imagePathMediaType, parsePastedImagePath, stageClipboardFilePaths } from '../utils/pastedImagePath.js';
24
+ import { editInExternalEditor } from '../utils/externalEditor.js';
25
+ import { setPromptEditorNode, EditorButton } from './PromptEditor.js';
26
+ import { isHiddenCommandName, parseCommandName } from '../commands.js';
27
+ import { appendHistory, HISTORY_LIMIT, loadHistoryOldestFirst } from '../history.js';
28
+ import { mentionAtCaret } from '../utils/mentions.js';
29
+ import { preserveSelection } from '../utils/fileSuggestions.js';
30
+ import { isMod } from '../utils/modifiers.js';
31
+ import { actionMatches } from '../utils/keymap.js';
32
+ import { CommandSuggestions } from './CommandSuggestions.js';
33
+ import { FileSuggestions } from './FileSuggestions.js';
34
+ import { HelpMenu } from './HelpMenu.js';
35
+ import { OverlayAbove } from './OverlayAbove.js';
36
+ import { SuggestionCard, cardContentWidth } from './SuggestionCard.js';
37
+ import { filterLiveImageBindings, isUsableDraftSnapshot, resolveBindingGeneration, } from './promptDraftCache.js';
38
+ /**
39
+ * Visible text of the session-entry control at the head of the input row:
40
+ * U+2338 APL FUNCTIONAL SYMBOL QUAD COLON plus a separator space.
41
+ *
42
+ * The glyph is chosen for ONE property above all others: the layout model and
43
+ * the terminal cell table must agree on how many columns it occupies. `\u2338`
44
+ * is a plain single-cell symbol with no emoji presentation, so
45
+ * `stringWidth` and the terminal both say 1 + 1 = 2 and
46
+ * {@link HOME_BUTTON_COLS} can be derived rather than guessed.
47
+ *
48
+ * The emoji house (`U+1F3E0`) was tried and rejected on this exact ground: it
49
+ * costs the terminal ONE cell while `stringWidth` charges the row TWO, and
50
+ * appending VARIATION SELECTOR-15 (text presentation) does not change either
51
+ * number. That standing one-column disagreement put every caret-relative
52
+ * column in the composer off by one, so no offset compensation made it work.
53
+ */
54
+ const HOME_BUTTON_TEXT = '⌸ ';
55
+ const HOME_BUTTON_COLS = stringWidth(HOME_BUTTON_TEXT);
56
+ /**
57
+ * Paste fold with a visible preview and no black box:
58
+ * a paste that leaves the input this big folds into a one-line chip
59
+ * showing the line/char count PLUS the first line of content. Hover peeks
60
+ * at the full text (window pinned to the head); clicking the chip — or
61
+ * the `▾` prefix on the first row while expanded — toggles the fold; Esc
62
+ * or any editing key unfolds first. Enter still submits the FULL text:
63
+ * folding never drops data.
64
+ */
65
+ const FOLD_MIN_LINES = 6;
66
+ const FOLD_MIN_CHARS = 600;
67
+ const isBigInput = (text) => text.split('\n').length >= FOLD_MIN_LINES || text.length >= FOLD_MIN_CHARS;
68
+ /**
69
+ * Editable prompt text must have one stable source-to-screen geometry. The
70
+ * renderer interprets ANSI as zero-width styling and expands tabs relative to
71
+ * global tab stops; keeping either in `value` would let wrapping/click mapping
72
+ * count different cells and could split an escape sequence during selection.
73
+ * Strip terminal controls and expand tabs at ingress while preserving newlines.
74
+ */
75
+ const EDITABLE_CONTROL = /[\u0000-\u0009\u000b-\u001f\u007f]/u;
76
+ /** Normalize editable text so no terminal control characters remain in state. */
77
+ function sanitizeEditableText(text) {
78
+ // Fast path for ordinary and multi-line drafts: newline is intentionally
79
+ // absent from the probe, so a large clean paste returns without regex work.
80
+ if (!EDITABLE_CONTROL.test(text))
81
+ return text;
82
+ return stripAnsi(text)
83
+ .replace(/\r\n?/gu, '\n')
84
+ .replace(/\t/gu, ' ')
85
+ .replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/gu, '');
86
+ }
87
+ const COMPOSER_IMAGE_TOKEN = /\[Image #\d+\]/gu;
88
+ /** Format label for one image media type, matching the image preview card's
89
+ * title (`JPEG`, `PNG`, `WEBP`, `GIF`). */
90
+ const mediaTypeLabel = (mediaType) => mediaType.replace(/^image\//u, '').replace(/\+xml$/u, '').toUpperCase();
91
+ /** Every `[Image #N]` in `text`, in order. */
92
+ function imageTokenSpans(text) {
93
+ const spans = [];
94
+ for (const match of text.matchAll(COMPOSER_IMAGE_TOKEN)) {
95
+ const start = match.index ?? 0;
96
+ spans.push({ start, end: start + match[0].length, token: match[0] });
97
+ }
98
+ return spans;
99
+ }
100
+ /** The span whose interior (exclusive of both edges) contains `offset`. */
101
+ function imageTokenAround(spans, offset) {
102
+ return spans.find(span => span.start < offset && offset < span.end);
103
+ }
104
+ /**
105
+ * A caret never rests inside a staged token: an offset in a span's interior
106
+ * moves to the edge `prefer` names — `'start'` (the token becomes the caret
107
+ * cluster), `'end'`, or whichever is nearer.
108
+ */
109
+ function snapOffImageToken(spans, offset, prefer) {
110
+ const span = imageTokenAround(spans, offset);
111
+ if (span === undefined)
112
+ return offset;
113
+ if (prefer === 'start')
114
+ return span.start;
115
+ if (prefer === 'end')
116
+ return span.end;
117
+ return offset - span.start < span.end - offset ? span.start : span.end;
118
+ }
119
+ /** Expand a deletion or selection to include every staged token it touches. */
120
+ function expandImageTokenRange(spans, start, end) {
121
+ return {
122
+ start: snapOffImageToken(spans, start, 'start'),
123
+ end: snapOffImageToken(spans, end, 'end'),
124
+ };
125
+ }
126
+ /** Capabilities referenced by `text`, in first occurrence order. A raw token
127
+ * restored from disk/history has no sidecar entry and therefore stays inert. */
128
+ export function composerImageRefsForText(text, stagedByToken) {
129
+ const refs = [];
130
+ const seen = new Set();
131
+ for (const match of text.matchAll(COMPOSER_IMAGE_TOKEN)) {
132
+ const token = match[0];
133
+ if (seen.has(token))
134
+ continue;
135
+ seen.add(token);
136
+ const stageId = stagedByToken.get(token);
137
+ if (stageId !== undefined)
138
+ refs.push({ token, stageId });
139
+ }
140
+ return refs;
141
+ }
142
+ /** Read one regular file through one descriptor, bounded to `maxBytes + 1`.
143
+ * The extra byte detects a file that grows after fstat; a short read detects
144
+ * shrinkage. This avoids stat(path) → readFile(path)'s path-swap TOCTOU and
145
+ * never allocates from an untrusted size before the profile limit is checked. */
146
+ async function readBoundedRegularFile(path, maxBytes) {
147
+ // O_NONBLOCK keeps a pasted FIFO/device path from parking the UI before
148
+ // fstat can reject it; regular-file reads are unchanged.
149
+ const file = await open(path, fsConstants.O_RDONLY | fsConstants.O_NONBLOCK);
150
+ try {
151
+ const info = await file.stat();
152
+ if (!info.isFile())
153
+ throw new Error(`${basename(path)} is not a regular file`);
154
+ if (info.size > maxBytes)
155
+ throw new Error(`image exceeds this profile's per-image size limit`);
156
+ const data = Buffer.allocUnsafe(info.size + 1);
157
+ let offset = 0;
158
+ while (offset < data.byteLength) {
159
+ const { bytesRead } = await file.read(data, offset, data.byteLength - offset, offset);
160
+ if (bytesRead === 0)
161
+ break;
162
+ offset += bytesRead;
163
+ }
164
+ if (offset !== info.size)
165
+ throw new Error(`${basename(path)} changed while it was being read`);
166
+ return data.subarray(0, offset);
167
+ }
168
+ finally {
169
+ await file.close();
170
+ }
171
+ }
172
+ /** Index of the word boundary at or before `cursor` (readline alt+b). */
173
+ function wordBoundaryLeft(text, cursor) {
174
+ let index = cursor;
175
+ while (index > 0 && /\s/.test(text[index - 1]))
176
+ index--;
177
+ while (index > 0 && !/\s/.test(text[index - 1]))
178
+ index--;
179
+ return index;
180
+ }
181
+ /** Index of the word boundary after `cursor` (readline alt+f). */
182
+ function wordBoundaryRight(text, cursor) {
183
+ const length = text.length;
184
+ let index = cursor;
185
+ while (index < length && !/\s/.test(text[index]))
186
+ index++;
187
+ while (index < length && /\s/.test(text[index]))
188
+ index++;
189
+ return index;
190
+ }
191
+ // --- vim normal-mode helpers -----------------------------------------------
192
+ // `/vim` 编辑模式的 normal 键位几何:行/词移动与删除目标。空白分词
193
+ // (不区分 vim 的 word/WORD),对输入框场景足够且行为直观。
194
+ /** Offset of the current line's first character. */
195
+ function vimLineStart(text, cursor) {
196
+ return text.lastIndexOf('\n', cursor - 1) + 1;
197
+ }
198
+ /** Offset of the current line's last character (exclusive, no '\n'). */
199
+ function vimLineEnd(text, cursor) {
200
+ const next = text.indexOf('\n', cursor);
201
+ return next === -1 ? text.length : next;
202
+ }
203
+ /** Offset of the line's first non-whitespace character (`^`). */
204
+ function vimLineFirstNonBlank(text, cursor) {
205
+ const start = vimLineStart(text, cursor);
206
+ const end = vimLineEnd(text, cursor);
207
+ let i = start;
208
+ while (i < end && /\s/.test(text[i]))
209
+ i++;
210
+ return i;
211
+ }
212
+ /** Next word start (`w`): skip the rest of the current word, then leading
213
+ * whitespace. Whitespace-delimited, vim-style. */
214
+ function vimWordForward(text, cursor) {
215
+ const len = text.length;
216
+ let i = cursor;
217
+ if (i < len && !/\s/.test(text[i])) {
218
+ while (i < len && !/\s/.test(text[i]))
219
+ i++;
220
+ }
221
+ while (i < len && /\s/.test(text[i]))
222
+ i++;
223
+ return i;
224
+ }
225
+ /** Previous word start (`b`): from inside a word, its own start; from
226
+ * whitespace, the preceding word's start. */
227
+ function vimWordBackward(text, cursor) {
228
+ let i = cursor;
229
+ while (i > 0 && /\s/.test(text[i - 1]))
230
+ i--;
231
+ while (i > 0 && !/\s/.test(text[i - 1]))
232
+ i--;
233
+ return i;
234
+ }
235
+ /** End of the current word (`dw`): the whitespace boundary after `cursor`. */
236
+ function vimWordEnd(text, cursor) {
237
+ const len = text.length;
238
+ let i = cursor;
239
+ while (i < len && !/\s/.test(text[i]))
240
+ i++;
241
+ return i;
242
+ }
243
+ // --- grapheme-cluster geometry ---------------------------------------------
244
+ // The caret, editing keys, and wrapping MUST agree on one text unit. Mixing
245
+ // UTF-16 code units (arrows/backspace), code points (wrap), and display
246
+ // cells (stringWidth) lets the caret land inside a surrogate pair or a ZWJ
247
+ // emoji — the inverted caret then shows half a glyph, Backspace deletes
248
+ // half a character, and `line.slice()` splits clusters. All offsets below
249
+ // are UTF-16 indices snapped to grapheme boundaries via the shared
250
+ // Intl.Segmenter (utils/intl.ts).
251
+ /** Ascending grapheme boundary offsets of `text` (starts at 0, ends at
252
+ * `text.length`). Empty text yields `[0]`. */
253
+ function graphemeBoundaries(text) {
254
+ const bounds = [0];
255
+ for (const { index, segment } of getGraphemeSegmenter().segment(text)) {
256
+ const end = index + segment.length;
257
+ if (end > bounds[bounds.length - 1])
258
+ bounds.push(end);
259
+ }
260
+ return bounds;
261
+ }
262
+ /** Largest grapheme boundary `<= offset` (clamped into the text). Snaps a
263
+ * cursor that landed mid-cluster back onto a boundary. */
264
+ function boundaryAtOrBefore(bounds, offset) {
265
+ let lo = 0;
266
+ let hi = bounds.length - 1;
267
+ let ans = bounds[0];
268
+ while (lo <= hi) {
269
+ const mid = (lo + hi) >> 1;
270
+ if (bounds[mid] <= offset) {
271
+ ans = bounds[mid];
272
+ lo = mid + 1;
273
+ }
274
+ else {
275
+ hi = mid - 1;
276
+ }
277
+ }
278
+ return ans;
279
+ }
280
+ /** Largest grapheme boundary strictly before `offset` (0 when none). */
281
+ function previousGraphemeBoundary(bounds, offset) {
282
+ let lo = 0;
283
+ let hi = bounds.length - 1;
284
+ let ans = 0;
285
+ while (lo <= hi) {
286
+ const mid = (lo + hi) >> 1;
287
+ if (bounds[mid] < offset) {
288
+ ans = bounds[mid];
289
+ lo = mid + 1;
290
+ }
291
+ else {
292
+ hi = mid - 1;
293
+ }
294
+ }
295
+ return ans;
296
+ }
297
+ /** Smallest grapheme boundary strictly after `offset` (text.length when
298
+ * none). Returns `offset` unchanged when it already is the last boundary. */
299
+ function nextGraphemeBoundary(bounds, offset) {
300
+ let lo = 0;
301
+ let hi = bounds.length - 1;
302
+ let ans = bounds[hi] ?? 0;
303
+ while (lo <= hi) {
304
+ const mid = (lo + hi) >> 1;
305
+ if (bounds[mid] > offset) {
306
+ ans = bounds[mid];
307
+ hi = mid - 1;
308
+ }
309
+ else {
310
+ lo = mid + 1;
311
+ }
312
+ }
313
+ return ans;
314
+ }
315
+ /** Snap an arbitrary UTF-16 offset onto a grapheme boundary of `text`,
316
+ * clamping into range. The safety net under every cursor write. */
317
+ function normalizeCursorOffset(text, offset) {
318
+ const clamped = Math.max(0, Math.min(offset, text.length));
319
+ return boundaryAtOrBefore(graphemeBoundaries(text), clamped);
320
+ }
321
+ /**
322
+ * The empty input deliberately shows NO placeholder text: terminal emulators
323
+ * paint the IME preedit (pinyin) at the physical cursor, which the app parks
324
+ * on the caret's cell, and the app receives no input events while a
325
+ * composition is active (Windows Terminal suppresses key events during TSF
326
+ * composition) — so it can never hide a placeholder in time. Keeping the row
327
+ * blank while empty is what guarantees the preedit has nothing to overlay.
328
+ */
329
+ /** Max input rows before the visible viewport starts scrolling; the box keeps
330
+ * a stable height. */
331
+ const MAX_VISIBLE_LINES = 5;
332
+ /**
333
+ * Fixed chrome rows around the expanded editor's text area: round border
334
+ * (top+bottom), the title row, the status row, and the button row. The
335
+ * editor viewport gets `terminalRows - this` rows.
336
+ */
337
+ const EDITOR_CHROME_ROWS = 5;
338
+ /**
339
+ * Double-click self-detection window: two clicks within this many ms and
340
+ * one cell (in either axis) of each other count as a double-click and
341
+ * select the word under the pointer. The drag protocol resets the ink
342
+ * multi-click chain on every press inside a drag target (the value box
343
+ * carries onDragStart), so the prompt detects the double-click itself.
344
+ */
345
+ const DOUBLE_CLICK_MS = 500;
346
+ /**
347
+ * dsh-TUI prompt input: rounded border box (top+bottom borders
348
+ * only), `❯ ` prompt char (dimmed while a turn is working), the text with a
349
+ * block cursor at the cursor position, and above it the slash-command /
350
+ * file-completion suggestion card (SuggestionCard: rounded panel with the
351
+ * selected row behind a `❯` pointer in the theme's `suggestion` color).
352
+ *
353
+ * Empty input: a solid block caret on a blank cell and nothing else — no
354
+ * placeholder text, so the terminal-painted IME preedit (pinyin) at the
355
+ * parked cursor can never be overlaid on anything.
356
+ *
357
+ * Multi-line: Shift+Enter inserts a newline; ↑/↓ move between lines while
358
+ * the input spans multiple lines (history/command selection otherwise); the
359
+ * visible window scrolls to keep the caret row on screen past
360
+ * MAX_VISIBLE_LINES. Enter submits, backspace/delete edit, ←/→ move the
361
+ * cursor, Tab completes the selected command, Ctrl+G opens the draft in the
362
+ * external editor ($VISUAL/$EDITOR), Escape clears (or closes the help
363
+ * menu), `?` toggles the help menu. Windows ConPTY pipelines deliver
364
+ * whole lines with the Enter key lost: a trailing CR/LF in the input marks
365
+ * a complete line to submit.
366
+ *
367
+ * Enter submits immediately even while the model is streaming — as a STEER
368
+ * (Codex/pi semantics): the message is injected at the next step boundary
369
+ * of the running turn and the agent continues without aborting; Tab instead
370
+ * queues the message for after the turn (followup). Both appear in a
371
+ * pending preview above the input until delivered. Alt+Up pulls the last
372
+ * pending message back for editing; Esc (with pending messages while
373
+ * working) interrupts the turn and delivers them right away; Ctrl+Enter
374
+ * aborts the turn and sends the current input immediately.
375
+ */
376
+ export function PromptInput({ channel, suspended = false, draftCache, helpOpen, onToggleHelp, onRunCommand, selectionActive, fillText, onFillConsumed, onRewindRequest, onBackgroundRequest, onOpenSessions, backgroundAgentsNeedingInput, controllerRef, onCaretImage, caretPreviewOpen = false, onDismissCaretPreview, }) {
377
+ const [themeName] = useTheme();
378
+ // Raw stdout writer for OSC 52 clipboard writes (selection copy) — must
379
+ // bypass the frame pipeline; null outside a mounted Ink App.
380
+ const writeRaw = React.useContext(TerminalWriteContext);
381
+ // The composer owns its text in local state, so it starts EMPTY and adopts
382
+ // whatever draft the owner stored in a MOUNT-TIME effect below. Reading the
383
+ // store in this initializer instead looks equivalent and is not: a non-empty
384
+ // first frame leaves `repro-resume-position` red — resuming a session parks
385
+ // the transcript mid-history instead of pinning it to the newest message.
386
+ // Adopting after mount keeps the first frame identical to a fresh composer
387
+ // while still handing the draft back.
388
+ const [value, setValue] = React.useState('');
389
+ const [cursor, setCursor] = React.useState(0);
390
+ /**
391
+ * Adopt the owner's draft ONCE, after mount.
392
+ *
393
+ * This is where a screen swap gives the draft back: the slot outlives this
394
+ * component, so a remount picks up what the user had written — text, caret,
395
+ * the image bindings behind the visible `[Image #N]` tokens, and the edit
396
+ * state around them (fold chip, fullscreen editor, vim mode).
397
+ *
398
+ * It runs as an effect rather than as the `useState` initial value on
399
+ * purpose. A composer whose FIRST frame is already non-empty moves the
400
+ * transcript's restored scroll position (`repro-resume-position`); adopting
401
+ * after the first commit keeps that frame identical to a fresh composer. The
402
+ * slot is consumed here, and the composer never writes to it while mounted,
403
+ * so the empty first value cannot overwrite the draft before this reads it.
404
+ */
405
+ const adoptDraft = React.useRef(true);
406
+ React.useEffect(() => {
407
+ if (draftCache === undefined || !adoptDraft.current)
408
+ return;
409
+ adoptDraft.current = false;
410
+ const snapshot = draftCache.current;
411
+ draftCache.current = null;
412
+ if (!isUsableDraftSnapshot(snapshot, String(channel.agentId), resolveBindingGeneration(channel)))
413
+ return;
414
+ const text = snapshot.value;
415
+ // Carried edit state, restored ahead of the text: the chip, the
416
+ // fullscreen editor and the vim mode/submode come back with the draft —
417
+ // and they come back even with NO text, because they are modes rather
418
+ // than content. Fold ranges are safe by the CAPTURE invariant, not by
419
+ // restore order: a snapshot's block, when set, always sits inside the
420
+ // snapshot's own text (setInput keeps or drops it atomically), and at
421
+ // mount the caret is 0 so updateFoldBlock's caret-drag clamp cannot fire
422
+ // here. The transient state around them — editor scroll, vim undo stack,
423
+ // selection — does not come back.
424
+ updateFoldBlock(snapshot.foldBlock);
425
+ expandedRef.current = snapshot.expanded;
426
+ setExpanded(snapshot.expanded);
427
+ vimEnabledRef.current = snapshot.vimEnabled;
428
+ setVimEnabled(snapshot.vimEnabled);
429
+ vimInsertRef.current = snapshot.vimInsert;
430
+ setVimInsert(snapshot.vimInsert);
431
+ if (text === '')
432
+ return;
433
+ const restoredCursor = normalizeCursorOffset(text, snapshot.cursor);
434
+ replaceDraftImages(filterLiveImageBindings(snapshot.images, stageId => channel.hasStagedImage?.(stageId) === true).map(([token, stageId]) => ({ token, stageId })));
435
+ valueRef.current = text;
436
+ cursorRef.current = restoredCursor;
437
+ setValue(text);
438
+ setCursor(restoredCursor);
439
+ }, [draftCache]);
440
+ /**
441
+ * Mouse text selection: UTF-16 offsets [start, end) in `value`, snapped
442
+ * to grapheme boundaries, start ≤ end. Null = no selection. Created by
443
+ * drag, Shift+click extension and double-click word select; consumed by
444
+ * Backspace/Delete/typing; Esc clears it without touching the text.
445
+ * With a fold block the range always stays inside the head or the tail
446
+ * (it never crosses the chip row — clamped on every write).
447
+ */
448
+ const [selection, setSelection] = React.useState(null);
449
+ const selectionRef = React.useRef(null);
450
+ /** Anchor offset of the in-flight drag gesture (set by dragstart). */
451
+ const dragAnchorRef = React.useRef(null);
452
+ /** Double-click self-detection: last click's timestamp/screen cell. */
453
+ const lastClickAtRef = React.useRef(0);
454
+ const lastClickColRef = React.useRef(-1);
455
+ const lastClickRowRef = React.useRef(-1);
456
+ /**
457
+ * vim editing mode (`/vim` toggle): when on, Esc switches the prompt to
458
+ * its NORMAL submode where bare keys are vim keys instead of text, and
459
+ * i/a/o (…) return to INSERT. Enabled in insert mode so the transition
460
+ * is seamless; the mode is session-scoped (not persisted).
461
+ */
462
+ const [vimEnabled, setVimEnabled] = React.useState(false);
463
+ /** Insert submode (false = vim NORMAL). */
464
+ const [vimInsert, setVimInsert] = React.useState(true);
465
+ const vimEnabledRef = React.useRef(false);
466
+ const vimInsertRef = React.useRef(true);
467
+ vimEnabledRef.current = vimEnabled;
468
+ vimInsertRef.current = vimInsert;
469
+ /** Undo owns the draft's image bindings as well as its text and caret. */
470
+ const vimUndoRef = React.useRef([]);
471
+ /** Pending vim operator: `d` pressed, awaiting its second key. */
472
+ const vimPendingRef = React.useRef('');
473
+ /**
474
+ * Fold block: the [start, end) span of `value` that renders as
475
+ * a one-line chip while the text around it stays fully editable. Created
476
+ * by a big paste; only an EXPLICIT expand (chip/card click, Esc) or
477
+ * delete removes it — typing NEVER unfolds the block.
478
+ */
479
+ const [foldBlock, setFoldBlock] = React.useState(null);
480
+ /** Synchronous mirror used by batched keys, controller clear, and mouse drag. */
481
+ const foldBlockRef = React.useRef(null);
482
+ /**
483
+ * Fullscreen draft editor (`expandEditor`, default Ctrl+Shift+E, or the
484
+ * ✎ affordance at the end of the input row). While expanded the SAME
485
+ * editing state renders into the PromptEditorLayer cover (published via
486
+ * setPromptEditorNode each render): Enter inserts a newline, Ctrl+Enter
487
+ * submits, Esc collapses. The fold chip is bypassed (full text shown).
488
+ */
489
+ const [expanded, setExpanded] = React.useState(false);
490
+ const expandedRef = React.useRef(false);
491
+ /** First visible row of the expanded viewport (merged with caret-follow
492
+ * during render; wheel events advance it and tick a re-render). */
493
+ const expandedScrollRef = React.useRef(0);
494
+ /**
495
+ * Free-scroll latch: wheel browsing parks the viewport anywhere; the
496
+ * caret-follow merge skips while it is set, and the next real caret move
497
+ * (typing, arrows, click) re-engages following (GUI-editor semantics).
498
+ */
499
+ const editorFreeScrollRef = React.useRef(false);
500
+ const prevCaretLineRef = React.useRef(-1);
501
+ const [, setExpandedTick] = React.useState(0);
502
+ const prevExpandedRef = React.useRef(false);
503
+ /**
504
+ * Feature gate (settings `dsh-tui.expandEditor`, on by default; a mock
505
+ * channel without the field also reads as on). Off hides the ✎
506
+ * affordance and refuses the shortcut — the editor cannot open.
507
+ */
508
+ const expandEnabled = channel.expandEditor !== false;
509
+ /** Latest expanded viewport metrics for the useInput wheel branch. */
510
+ const editorViewportRef = React.useRef(null);
511
+ /** Hover state of the ⤢/✎ expand affordance in the input row. */
512
+ const [expandHovered, setExpandHovered] = React.useState(false);
513
+ /** Hover state of the ⌂ session-list affordance at the head of the row. */
514
+ const [homeHovered, setHomeHovered] = React.useState(false);
515
+ /** Pointer over the input box (drives the hover peek card). */
516
+ const [hovered, setHovered] = React.useState(false);
517
+ /** 120ms grace so the pointer crossing the input border row from the
518
+ * chip up onto the peek card never flickers the card. */
519
+ const hoverLeaveTimerRef = React.useRef(null);
520
+ const hoverEnter = React.useCallback(() => {
521
+ if (hoverLeaveTimerRef.current) {
522
+ clearTimeout(hoverLeaveTimerRef.current);
523
+ hoverLeaveTimerRef.current = null;
524
+ }
525
+ setHovered(true);
526
+ }, []);
527
+ const hoverLeave = React.useCallback(() => {
528
+ if (hoverLeaveTimerRef.current)
529
+ clearTimeout(hoverLeaveTimerRef.current);
530
+ hoverLeaveTimerRef.current = setTimeout(() => setHovered(false), 120);
531
+ }, []);
532
+ const valueRef = React.useRef(value);
533
+ const cursorRef = React.useRef(cursor);
534
+ const history = React.useRef([]);
535
+ const historyIndex = React.useRef(-1);
536
+ const historyDraft = React.useRef({ text: '', images: [] });
537
+ /** The persisted history is read lazily, once per mount (see seedHistory). */
538
+ const historySeeded = React.useRef(false);
539
+ /** Visible `[Image #N]` labels are presentation only; this sidecar carries
540
+ * the non-reusable capability for the current draft. History/rewind text
541
+ * restored without this map can never bind to a later image by accident. */
542
+ const draftImagesRef = React.useRef(new Map());
543
+ const draftImagesGenerationRef = React.useRef(channel.stagedImageGeneration?.() ?? 0);
544
+ /** Session generation fences one agent transcript; revision fences one
545
+ * logical composer draft inside that session. Ordinary typing deliberately
546
+ * keeps the revision so an async paste lands at the live caret, while any
547
+ * whole-draft replacement revokes the old continuation. */
548
+ const draftRevisionRef = React.useRef(0);
549
+ /** Unlike draftRevision (whole-draft replacement only), this advances on
550
+ * every text mutation so an async command can never clear a draft that was
551
+ * edited away and later changed back to the same bytes. */
552
+ const inputEditSequenceRef = React.useRef(0);
553
+ /** One registry command may own a draft at a time. Keeping the draft
554
+ * visible during admission must not make a second Enter dispatch it twice. */
555
+ const pendingCommandRef = React.useRef(null);
556
+ const nextImageNumberRef = React.useRef(1);
557
+ /** Serialize image staging started in one draft so consecutive terminal
558
+ * drops keep input order even when storage settles out of order. A new
559
+ * logical draft receives a fresh chain and never waits on old-session I/O. */
560
+ const imageStageChainRef = React.useRef(Promise.resolve());
561
+ const advanceDraftRevision = () => {
562
+ draftRevisionRef.current += 1;
563
+ imageStageChainRef.current = Promise.resolve();
564
+ };
565
+ const detachDraftImages = () => {
566
+ advanceDraftRevision();
567
+ draftImagesRef.current.clear();
568
+ clearVimUndo();
569
+ };
570
+ const stageIdIsRetained = (stageId) => {
571
+ for (const current of draftImagesRef.current.values()) {
572
+ if (current === stageId)
573
+ return true;
574
+ }
575
+ return vimUndoRef.current.some(entry => entry.images.some(image => image.stageId === stageId))
576
+ || history.current.some(entry => entry.images.some(image => image.stageId === stageId))
577
+ || historyDraft.current.images.some(image => image.stageId === stageId)
578
+ || channel.pending.some(item => item.images?.some(image => image.stageId === stageId) === true);
579
+ };
580
+ const discardUnretainedImages = (stageIds) => {
581
+ for (const stageId of new Set(stageIds)) {
582
+ if (!stageIdIsRetained(stageId))
583
+ channel.discardStagedImage(stageId);
584
+ }
585
+ };
586
+ const clearVimUndo = () => {
587
+ const previous = vimUndoRef.current;
588
+ vimUndoRef.current = [];
589
+ discardUnretainedImages(previous.flatMap(entry => entry.images.map(image => image.stageId)));
590
+ };
591
+ const discardDraftImages = () => {
592
+ advanceDraftRevision();
593
+ const stageIds = [...draftImagesRef.current.values()];
594
+ clearVimUndo();
595
+ draftImagesRef.current.clear();
596
+ discardUnretainedImages(stageIds);
597
+ };
598
+ const replaceDraftImages = (images) => {
599
+ const previous = [...draftImagesRef.current.values()];
600
+ draftImagesRef.current.clear();
601
+ for (const ref of images) {
602
+ if (channel.hasStagedImage?.(ref.stageId) === true) {
603
+ draftImagesRef.current.set(ref.token, ref.stageId);
604
+ }
605
+ }
606
+ discardUnretainedImages(previous);
607
+ };
608
+ const syncImageGeneration = () => {
609
+ const generation = channel.stagedImageGeneration?.() ?? 0;
610
+ if (draftImagesGenerationRef.current !== generation) {
611
+ // The channel has already cleared every old-generation capability.
612
+ // Only detach the UI sidecar; calling discard would be redundant.
613
+ vimUndoRef.current = [];
614
+ detachDraftImages();
615
+ draftImagesGenerationRef.current = generation;
616
+ // Presentation numbering is session-local like the old channel-owned
617
+ // sequence. Any stale token still visible in the retained draft is
618
+ // skipped by bindStagedImage, so resetting cannot recreate an alias.
619
+ nextImageNumberRef.current = 1;
620
+ }
621
+ return generation;
622
+ };
623
+ const captureDraftImageLease = () => ({
624
+ generation: syncImageGeneration(),
625
+ revision: draftRevisionRef.current,
626
+ });
627
+ const draftImageLeaseIsCurrent = (lease) => syncImageGeneration() === lease.generation
628
+ && draftRevisionRef.current === lease.revision;
629
+ // Channel emits on every session replacement. Clear the sidecar during
630
+ // that render while leaving the user's visible draft untouched; any raw
631
+ // tokens become explicit stale placeholders instead of aliases.
632
+ syncImageGeneration();
633
+ valueRef.current = value;
634
+ cursorRef.current = cursor;
635
+ // Nothing is written to the owner's draft slot here — see the unmount
636
+ // hand-off below. A commit-time write would run BEFORE the restore effect
637
+ // has consumed the slot, so the composer's own first (empty) value would
638
+ // erase the draft it just came back for.
639
+ // Publish the live controller (fresh closure over `value` every render).
640
+ // A prompt-slot panel withdraws the handle in the same commit: external
641
+ // injection must not append/submit a hidden command draft while it waits
642
+ // for a decision. clear() mirrors the double-tap-Esc clear.
643
+ React.useLayoutEffect(() => {
644
+ if (!controllerRef)
645
+ return;
646
+ if (suspended) {
647
+ controllerRef.current = null;
648
+ return;
649
+ }
650
+ controllerRef.current = {
651
+ hasText: () => value.length > 0,
652
+ text: () => valueRef.current,
653
+ previewImages: () => composerImageRefsForText(valueRef.current, draftImagesRef.current).flatMap(ref => {
654
+ const image = channel.stagedImage(ref.stageId);
655
+ return image === undefined ? [] : [{ image, title: ref.token.slice(1, -1) }];
656
+ }),
657
+ clear: () => {
658
+ if (valueRef.current !== '')
659
+ inputEditSequenceRef.current += 1;
660
+ valueRef.current = '';
661
+ cursorRef.current = 0;
662
+ selectionRef.current = null;
663
+ discardDraftImages();
664
+ foldBlockRef.current = null;
665
+ dragAnchorRef.current = null;
666
+ lastClickAtRef.current = 0;
667
+ lastClickColRef.current = -1;
668
+ lastClickRowRef.current = -1;
669
+ // Chat's idle Ctrl+C clear also withdraws the fullscreen editor —
670
+ // the draft it was editing is gone, the cover must not linger.
671
+ expandedRef.current = false;
672
+ setSelection(null);
673
+ setFoldBlock(null);
674
+ setExpanded(false);
675
+ setValue('');
676
+ setCursor(0);
677
+ },
678
+ append: (text) => {
679
+ const previous = valueRef.current;
680
+ const next = sanitizeEditableText(previous + text);
681
+ if (next !== previous)
682
+ inputEditSequenceRef.current += 1;
683
+ valueRef.current = next;
684
+ cursorRef.current = next.length;
685
+ setValue(next);
686
+ setCursor(next.length);
687
+ return next;
688
+ },
689
+ consumeSelectionCopy: () => {
690
+ const sel = selectionRef.current;
691
+ if (!sel)
692
+ return false;
693
+ const text = valueRef.current.slice(sel.start, sel.end);
694
+ void setClipboard(text).then(raw => {
695
+ if (raw)
696
+ writeRaw?.(raw);
697
+ });
698
+ // The selection stays: copy never clears it (Esc/typing/delete do).
699
+ return true;
700
+ },
701
+ toggleVim: () => {
702
+ const next = !vimEnabledRef.current;
703
+ vimEnabledRef.current = next;
704
+ setVimEnabled(next);
705
+ // Every toggle lands in INSERT: a fresh vim user keeps typing
706
+ // normally until they press Esc for the first time. Turning the
707
+ // mode off also clears the undo stack — a later re-enable must
708
+ // never `u` its way back past edits made while vim was off.
709
+ vimInsertRef.current = true;
710
+ setVimInsert(true);
711
+ vimPendingRef.current = '';
712
+ clearVimUndo();
713
+ return next;
714
+ },
715
+ vimActive: () => vimEnabledRef.current,
716
+ };
717
+ return () => {
718
+ controllerRef.current = null;
719
+ };
720
+ });
721
+ const [selectedCommand, setSelectedCommand] = React.useState(0);
722
+ // ctrl+r history fill: replace the input when a new fill arrives, then
723
+ // tell the caller to clear it.
724
+ const lastFill = React.useRef(null);
725
+ React.useLayoutEffect(() => {
726
+ if (fillText && fillText !== lastFill.current) {
727
+ lastFill.current = fillText;
728
+ syncImageGeneration();
729
+ discardDraftImages();
730
+ updateFoldBlock(null);
731
+ setInput(fillText);
732
+ onFillConsumed?.();
733
+ }
734
+ }, [fillText, onFillConsumed]);
735
+ // Double-tap Esc to clear.
736
+ const escPendingRef = React.useRef(false);
737
+ const escTimerRef = React.useRef(null);
738
+ /** True while a clipboard paste read is in flight (ignore repeat keys). */
739
+ const clipboardBusyRef = React.useRef(false);
740
+ /** True while the external editor owns the terminal (editor-key round-trip). */
741
+ const editorBusyRef = React.useRef(false);
742
+ /** Enter dedupe window: cmd pipelines can deliver one Enter as `\r`+`\n`. */
743
+ const lastEnterAtRef = React.useRef(0);
744
+ React.useEffect(() => {
745
+ return () => {
746
+ if (escTimerRef.current)
747
+ clearTimeout(escTimerRef.current);
748
+ if (hoverLeaveTimerRef.current)
749
+ clearTimeout(hoverLeaveTimerRef.current);
750
+ /**
751
+ * Hand the draft to the owner's slot as this component goes away.
752
+ *
753
+ * This is the ONLY write to that slot, and it belongs here: it happens at
754
+ * the instant a screen replaces the composer, so it can neither race the
755
+ * restore effect nor change the transcript's first frame.
756
+ *
757
+ * `advanceDraftRevision` invalidates any image read/stage still in
758
+ * flight, so a late continuation cannot bind a capability into a composer
759
+ * that no longer exists. `clearVimUndo` releases the capabilities that
760
+ * only the undo stack was holding: they are not part of the draft, and
761
+ * nothing will ever restore them once this composer is gone.
762
+ *
763
+ * The stageIds the DRAFT holds are deliberately NOT revoked — they are
764
+ * part of the snapshot the slot now keeps, and the restore filters out
765
+ * whatever the channel revoked in the meantime. Revoking them here is why
766
+ * an image draft used to come back as inert text.
767
+ */
768
+ advanceDraftRevision();
769
+ clearVimUndo();
770
+ const images = [...draftImagesRef.current.entries()]
771
+ .map(([token, stageId]) => [token, stageId]);
772
+ draftImagesRef.current.clear();
773
+ if (draftCache === undefined) {
774
+ discardUnretainedImages(images.map(image => image[1]));
775
+ return;
776
+ }
777
+ const text = valueRef.current;
778
+ // The edit state rides along even with nothing typed: vim mode and the
779
+ // fullscreen editor are MODES the user turned on, not content, and an
780
+ // empty composer must not drop them (`text === ''` alone used to skip
781
+ // the snapshot entirely, losing the vim badge on a round trip with an
782
+ // empty composer).
783
+ const editState = foldBlockRef.current !== null || expandedRef.current
784
+ || vimEnabledRef.current;
785
+ if (text === '' && images.length === 0 && !editState) {
786
+ draftCache.current = null;
787
+ return;
788
+ }
789
+ draftCache.current = {
790
+ ownerAgentId: String(channel.agentId),
791
+ bindingGeneration: resolveBindingGeneration(channel),
792
+ value: text,
793
+ cursor: cursorRef.current,
794
+ foldBlock: foldBlockRef.current,
795
+ expanded: expandedRef.current,
796
+ vimEnabled: vimEnabledRef.current,
797
+ vimInsert: vimInsertRef.current,
798
+ images,
799
+ };
800
+ };
801
+ }, []);
802
+ const { columns, rows: terminalRows } = useTerminalSize();
803
+ React.useEffect(() => {
804
+ // PromptInput self-detects double-clicks because its drag target resets
805
+ // App's global chain. Geometry changed across resize, so the same screen
806
+ // cell no longer identifies the same grapheme.
807
+ lastClickAtRef.current = 0;
808
+ lastClickColRef.current = -1;
809
+ lastClickRowRef.current = -1;
810
+ }, [columns, terminalRows]);
811
+ const helpScrollRef = React.useRef(null);
812
+ // Help viewport budget: the overlay anchors at the composer's top edge
813
+ // (OverlayAbove bottom:'100%') and grows UP, so its budget is the space
814
+ // ABOVE that anchor — smallest on an empty session, where the whale
815
+ // splash (~15 rows) sits between the screen top and the composer
816
+ // (terminalRows minus chrome only applies once the transcript fills the
817
+ // viewport). Take the conservative intersection: 15 rows of viewport (16
818
+ // with the hint + margin) fits the empty-session anchor on the default
819
+ // layout at any terminal size, and the renderer's bottom-anchored
820
+ // clipping for absolute overlays (no negative-y clamp) then never has
821
+ // to eat the overlay's FIRST rows — the shortcut-column headers. The
822
+ // command registry scrolls inside the viewport, so a taller terminal
823
+ // loses nothing functional. (PR #446; restored after the picker
824
+ // snapshot's cherry-pick resurrected the old formula.)
825
+ const helpViewportHeight = Math.max(3, Math.min(terminalRows - 7, 15));
826
+ const suggestions = value.startsWith('/') ? channel.commandCompletions(value) : [];
827
+ const overlayOpen = suggestions.length > 0 &&
828
+ !expanded &&
829
+ !helpOpen &&
830
+ !selectionActive &&
831
+ !value.includes('\n');
832
+ // `@` file completion (issue #15): the trigger is the mention token at the
833
+ // CARET, so `@` works mid-message (`看看 @src/a.ts 这个`), not only when it
834
+ // is the input's first character. The cwd listing loads when the trigger
835
+ // appears.
836
+ const [fileMatches, setFileMatches] = React.useState([]);
837
+ const [fileSelected, setFileSelected] = React.useState(0);
838
+ const mention = mentionAtCaret(value, cursor);
839
+ const atTrigger = mention !== undefined;
840
+ const fileRequestId = React.useRef(0);
841
+ const selectedFile = fileMatches[fileSelected];
842
+ React.useEffect(() => {
843
+ const requestId = ++fileRequestId.current;
844
+ if (!mention) {
845
+ setFileMatches([]);
846
+ setFileSelected(0);
847
+ return;
848
+ }
849
+ const previous = selectedFile;
850
+ // Deps key on `mention.query` (and trigger on/off) only: cursor movement
851
+ // within the same token must NOT refetch, and `selectedFile`/`fileSelected`
852
+ // are read as their render-time values only to seed selection preservation.
853
+ // eslint-disable-next-line react-hooks/exhaustive-deps
854
+ void channel.listFileCandidates(mention.query, { topK: 50 }).then(next => {
855
+ if (requestId !== fileRequestId.current)
856
+ return;
857
+ setFileMatches(next);
858
+ setFileSelected(preserveSelection(previous, next, fileSelected));
859
+ });
860
+ }, [channel, mention?.query, atTrigger]);
861
+ // Esc dismisses the overlay for the token being edited (it reopens once the
862
+ // text changes); it must NOT clear a mid-message input.
863
+ const fileEscRef = React.useRef(-1);
864
+ React.useEffect(() => {
865
+ fileEscRef.current = -1;
866
+ }, [value]);
867
+ const fileOverlayOpen = fileMatches.length > 0 &&
868
+ !expanded &&
869
+ !helpOpen &&
870
+ !selectionActive &&
871
+ fileEscRef.current !== mention?.start;
872
+ /**
873
+ * The `[Image #N]` tokens of `text` that carry a live draft capability.
874
+ * These are atomic: the caret never rests inside one, ←/→ step over the
875
+ * whole token, Backspace at its end / Delete at its start remove it whole,
876
+ * a selection never cuts it, and it renders as a chip (the whole token is
877
+ * the caret cluster when the caret sits at its start). A raw token typed
878
+ * or restored without a capability is ordinary text.
879
+ */
880
+ const boundImageSpans = (text) => imageTokenSpans(text).filter(span => draftImagesRef.current.has(span.token));
881
+ /** Move the caret to `offset`, snapped off any token interior. */
882
+ const placeCaret = (offset, prefer) => {
883
+ const snapped = snapOffImageToken(boundImageSpans(valueRef.current), offset, prefer);
884
+ cursorRef.current = snapped;
885
+ setCursor(snapped);
886
+ };
887
+ /**
888
+ * The staged image the caret is on: the token whose start is the caret —
889
+ * exactly when the whole token is the caret cluster and inverts. The
890
+ * caret sitting just after a token is not "on" it (the token is plain
891
+ * there), so no preview. Undefined for a raw or stale token.
892
+ */
893
+ const caretImageAt = (text, offset) => {
894
+ const span = boundImageSpans(text).find(s => s.start === offset);
895
+ if (span === undefined)
896
+ return undefined;
897
+ const stageId = draftImagesRef.current.get(span.token);
898
+ const image = stageId === undefined ? undefined : channel.stagedImage(stageId);
899
+ return image === undefined ? undefined : { image, title: span.token.slice(1, -1) };
900
+ };
901
+ const onCaretImageRef = React.useRef(onCaretImage);
902
+ onCaretImageRef.current = onCaretImage;
903
+ const lastCaretImageRef = React.useRef({ image: undefined, title: undefined });
904
+ /** Tell the caller which staged image the caret is on. `'caret'` reports
905
+ * only changes; `'click'` always reports (see onCaretImage). "Same image"
906
+ * is the attachment id plus the token, not facade identity: this runs
907
+ * after every commit and the caller stores what it reports, so an
908
+ * identity-only difference would re-render the caller forever (#885). */
909
+ const reportCaretImage = (reason) => {
910
+ const report = onCaretImageRef.current;
911
+ if (report === undefined)
912
+ return;
913
+ const found = suspended ? undefined : caretImageAt(valueRef.current, cursorRef.current);
914
+ const last = lastCaretImageRef.current;
915
+ if (reason === 'caret' && last.image?.id === found?.image.id && last.title === found?.title)
916
+ return;
917
+ lastCaretImageRef.current = { image: found?.image, title: found?.title };
918
+ report(found?.image, found?.title, reason);
919
+ };
920
+ // After every commit: the caret, the text and the staged map are all
921
+ // settled by then, and a no-change report is skipped.
922
+ React.useEffect(() => { reportCaretImage('caret'); });
923
+ React.useEffect(() => () => {
924
+ if (lastCaretImageRef.current.image !== undefined) {
925
+ onCaretImageRef.current?.(undefined, undefined, 'caret');
926
+ }
927
+ }, []);
928
+ /** Fold-block state + a synchronous mirror (setInput reads the ref).
929
+ * Creating a block also drags a caret that sits inside it out to the
930
+ * block's end (the block is atomic; typing continues after it). */
931
+ const updateFoldBlock = (block) => {
932
+ foldBlockRef.current = block;
933
+ setFoldBlock(block);
934
+ if (block) {
935
+ const c = cursorRef.current;
936
+ if (c > block.start && c < block.end) {
937
+ cursorRef.current = block.end;
938
+ setCursor(block.end);
939
+ }
940
+ }
941
+ };
942
+ const setInput = (next, cursorOffset = next.length) => {
943
+ // Apply the same ingress normalization to fills/history/editor results as
944
+ // to paste. Map the requested caret through the sanitized prefix so an
945
+ // ANSI sequence removed before it cannot leave the caret past the text.
946
+ const sanitizedCursor = sanitizeEditableText(next.slice(0, cursorOffset)).length;
947
+ next = sanitizeEditableText(next);
948
+ cursorOffset = sanitizedCursor;
949
+ const prev = valueRef.current;
950
+ const prevCursor = cursorRef.current;
951
+ const block = foldBlockRef.current;
952
+ // Normalize onto a grapheme boundary (also clamps into range): every
953
+ // caller passes a caret they believe is on a character edge — paste
954
+ // merges, history fills, and IME composition can still hand back an
955
+ // offset inside a surrogate pair or combining cluster.
956
+ let offset = normalizeCursorOffset(next, cursorOffset);
957
+ if (block) {
958
+ // Fold block is atomic: the caret never lands INSIDE [start, end).
959
+ if (offset > block.start && offset < block.end) {
960
+ offset = offset - block.start < block.end - offset ? block.start : block.end;
961
+ }
962
+ // Every real edit happens AT the caret, so a block that starts at or
963
+ // after the caret shifts with the value delta; one fully past the
964
+ // caret is untouched. Whole-value replacements (fill/history/editor)
965
+ // clear the block explicitly at their call sites.
966
+ const delta = next.length - prev.length;
967
+ let start = block.start;
968
+ let end = block.end;
969
+ if (prevCursor <= block.start) {
970
+ start += delta;
971
+ end += delta;
972
+ }
973
+ start = Math.max(0, Math.min(start, next.length));
974
+ end = Math.max(start, Math.min(end, next.length));
975
+ if (start >= end)
976
+ updateFoldBlock(null);
977
+ else if (start !== block.start || end !== block.end)
978
+ updateFoldBlock({ start, end });
979
+ }
980
+ // Staged `[Image #N]` tokens are atomic: a caret that would land inside
981
+ // one continues in its direction of travel (←/word-left/↑ → the token's
982
+ // start, →/word-right/↓ → its end); with no travel, the nearer edge.
983
+ offset = snapOffImageToken(boundImageSpans(next), offset, offset < prevCursor ? 'start' : offset > prevCursor ? 'end' : 'nearest');
984
+ // The synchronous mirrors are what batch-dispatched events (one stdin
985
+ // read → several keys, no render in between) read on their next turn.
986
+ if (next !== prev)
987
+ inputEditSequenceRef.current += 1;
988
+ valueRef.current = next;
989
+ cursorRef.current = offset;
990
+ // Deleting a visible token revokes its capability. Re-typing the same
991
+ // label later must stay inert; only a fresh paste may mint a new binding.
992
+ for (const [token, stageId] of draftImagesRef.current) {
993
+ if (next.includes(token))
994
+ continue;
995
+ draftImagesRef.current.delete(token);
996
+ if (!stageIdIsRetained(stageId))
997
+ channel.discardStagedImage(stageId);
998
+ }
999
+ // Every real edit drops the selection: its offsets describe the OLD
1000
+ // text. Selection-consuming callers (delete/replace) read it first.
1001
+ selectionRef.current = null;
1002
+ setSelection(null);
1003
+ setValue(next);
1004
+ setCursor(offset);
1005
+ };
1006
+ const deleteInputRange = (start, end) => {
1007
+ if (start >= end)
1008
+ return;
1009
+ const text = valueRef.current;
1010
+ const range = expandImageTokenRange(boundImageSpans(text), start, end);
1011
+ setInput(text.slice(0, range.start) + text.slice(range.end), range.start);
1012
+ };
1013
+ /**
1014
+ * Write the selection [start, end) (snapped to grapheme boundaries,
1015
+ * start ≤ end); a degenerate range clears it. With a fold block the
1016
+ * range is clamped into the side that holds `start` — the block is
1017
+ * atomic and a selection may never cross the chip row.
1018
+ */
1019
+ const updateSelection = (start, end) => {
1020
+ const text = valueRef.current;
1021
+ const anchor = normalizeCursorOffset(text, start);
1022
+ let lo = normalizeCursorOffset(text, Math.min(start, end));
1023
+ let hi = normalizeCursorOffset(text, Math.max(start, end));
1024
+ const block = foldBlockRef.current;
1025
+ if (block) {
1026
+ // Clamp by the ORIGINAL anchor side, not sorted `lo`: for a reverse
1027
+ // tail→head drag, `lo` is in the head even though the gesture belongs
1028
+ // to the tail. Both selection and caret must stay on the anchor side.
1029
+ if (anchor <= block.start) {
1030
+ hi = Math.min(hi, block.start);
1031
+ }
1032
+ else {
1033
+ lo = Math.max(lo, block.end);
1034
+ hi = Math.max(hi, block.end);
1035
+ }
1036
+ }
1037
+ // A selection never cuts a staged token: an edge inside one grows
1038
+ // outward to cover the whole token.
1039
+ const range = expandImageTokenRange(boundImageSpans(text), lo, hi);
1040
+ lo = range.start;
1041
+ hi = range.end;
1042
+ if (lo >= hi) {
1043
+ selectionRef.current = null;
1044
+ setSelection(null);
1045
+ }
1046
+ else {
1047
+ selectionRef.current = { start: lo, end: hi };
1048
+ setSelection({ start: lo, end: hi });
1049
+ }
1050
+ };
1051
+ /** Drop the selection without touching text or caret. */
1052
+ const clearSelection = () => {
1053
+ selectionRef.current = null;
1054
+ setSelection(null);
1055
+ };
1056
+ /**
1057
+ * Accept the selected file suggestion: replace ONLY the mention token at
1058
+ * the caret (prefix/suffix text survives), quoting whitespace paths. A
1059
+ * directory inserts `@dir/` without a trailing space so completion
1060
+ * continues into it; a file completes the token with a space. A typed
1061
+ * `#L12-14` suffix is NOT part of the replacement — completion ends at
1062
+ * `pathEnd` so the line range survives acceptance (issue #359).
1063
+ */
1064
+ const acceptFile = (candidate) => {
1065
+ if (!mention)
1066
+ return;
1067
+ const file = candidate.path;
1068
+ const body = /\s/.test(file) ? `@"${file}"` : `@${file}`;
1069
+ // A typed `#L12-14` suffix rides along AFTER the completed body (before
1070
+ // the trailing space) — quoting a whitespace path must not detach it.
1071
+ const suffix = mention.pathEnd === undefined ? '' : value.slice(mention.pathEnd, mention.end);
1072
+ const insert = candidate.kind === 'directory' ? `${body}${suffix}` : `${body}${suffix} `;
1073
+ const next = value.slice(0, mention.start) + insert + value.slice(mention.end);
1074
+ setInput(next, mention.start + insert.length);
1075
+ setFileSelected(0);
1076
+ };
1077
+ const imageRefsFor = (text) => {
1078
+ syncImageGeneration();
1079
+ return composerImageRefsForText(text, draftImagesRef.current);
1080
+ };
1081
+ /**
1082
+ * Warn once when the text carries an `[Image #N]` placeholder that will
1083
+ * not attach an image: unbound in this draft (history, rewind, typed) or
1084
+ * bound to a staging the channel has since dropped. Channel routes
1085
+ * (submit, steer, registry commands) warn on their own; this covers the
1086
+ * lines the screen consumes locally, where the text is otherwise dropped
1087
+ * without a word.
1088
+ */
1089
+ const warnStaleImageTokens = (text, images) => {
1090
+ const live = new Set(images
1091
+ .filter(image => channel.stagedImage(image.stageId) !== undefined)
1092
+ .map(image => image.token));
1093
+ for (const match of text.matchAll(COMPOSER_IMAGE_TOKEN)) {
1094
+ if (live.has(match[0]))
1095
+ continue;
1096
+ channel.notify(t('input-image-token-stale', { token: match[0] }), { color: 'warning', timeoutMs: 5000 });
1097
+ return;
1098
+ }
1099
+ };
1100
+ /**
1101
+ * Seed the walk with the persisted history (issue #986). `↑`/`↓` used to
1102
+ * see only what this process submitted, so a restart lost every earlier
1103
+ * entry. Seeding before the first push keeps ONE chronological list —
1104
+ * persisted entries first, this run's submits behind them — instead of two
1105
+ * lists to merge at recall time. Restored text carries no image capability
1106
+ * (the file stores text only), which is also what keeps a recalled entry
1107
+ * from binding to a later staged image by accident.
1108
+ */
1109
+ const seedHistory = () => {
1110
+ if (historySeeded.current)
1111
+ return;
1112
+ historySeeded.current = true;
1113
+ history.current = loadHistoryOldestFirst().map(entry => ({ text: entry.text, images: [] }));
1114
+ historyIndex.current = -1;
1115
+ };
1116
+ const rememberHistory = (text, images) => {
1117
+ // Both entries into the walk (a submit and ↑) must see the persisted
1118
+ // prefix, so seed here rather than merging two lists later.
1119
+ seedHistory();
1120
+ history.current.push({
1121
+ text,
1122
+ images: images.map(image => ({ ...image })),
1123
+ });
1124
+ if (history.current.length > HISTORY_LIMIT)
1125
+ history.current.shift();
1126
+ historyIndex.current = -1;
1127
+ void appendHistory(text);
1128
+ };
1129
+ const clearDeliveredDraft = () => {
1130
+ syncImageGeneration();
1131
+ // Delivery captured the opaque refs and history retains them; only the
1132
+ // editable-draft binding is ending here.
1133
+ detachDraftImages();
1134
+ setInput('', 0);
1135
+ setSelectedCommand(0);
1136
+ setFileSelected(0);
1137
+ };
1138
+ const sameImageRefs = (left, right) => left.length === right.length && left.every((image, index) => image.token === right[index]?.token && image.stageId === right[index]?.stageId);
1139
+ /** `!`/`!!` are host shell routes, not model messages. They have no image
1140
+ * grammar, so reject before history/clear just like a non-image command. */
1141
+ const shellImagesUnsupported = (text, images) => {
1142
+ if (images.length === 0 || !text.startsWith('!'))
1143
+ return false;
1144
+ channel.notify(t('shell-images-unsupported'), { color: 'warning', timeoutMs: 4000 });
1145
+ return true;
1146
+ };
1147
+ const restoreDraftImages = (entry) => {
1148
+ syncImageGeneration();
1149
+ advanceDraftRevision();
1150
+ replaceDraftImages(entry.images);
1151
+ clearVimUndo();
1152
+ };
1153
+ const submitText = (text, notice) => {
1154
+ const trimmed = text.trim();
1155
+ if (!trimmed)
1156
+ return;
1157
+ const images = imageRefsFor(trimmed);
1158
+ if (shellImagesUnsupported(trimmed, images))
1159
+ return;
1160
+ rememberHistory(trimmed, images);
1161
+ clearDeliveredDraft();
1162
+ channel.submit(trimmed, images);
1163
+ if (notice) {
1164
+ channel.notify(notice, { timeoutMs: 2500 });
1165
+ }
1166
+ else if (channel.working) {
1167
+ // While the model is streaming, the message joins the DSH inbox and is
1168
+ // processed after the current turn — say so, or it looks "lost".
1169
+ channel.notify(t('input-sent-after-turn'), { timeoutMs: 2500 });
1170
+ }
1171
+ };
1172
+ /**
1173
+ * Enter while the model is working = STEER (Codex/pi semantics): the
1174
+ * message is injected at the next step boundary of the RUNNING turn and
1175
+ * the agent continues without aborting — the "immediate" send.
1176
+ */
1177
+ const steerSend = (text) => {
1178
+ const trimmed = text.trim();
1179
+ if (!trimmed)
1180
+ return;
1181
+ const images = imageRefsFor(trimmed);
1182
+ rememberHistory(trimmed, images);
1183
+ clearDeliveredDraft();
1184
+ channel.steer(trimmed, images);
1185
+ channel.notify(t('input-interrupted-next'), { timeoutMs: 2500 });
1186
+ };
1187
+ /**
1188
+ * Tab while the model is working = plain queue (followup): the message
1189
+ * waits for the running turn to end, then is processed in order.
1190
+ */
1191
+ const queueSend = (text) => {
1192
+ const trimmed = text.trim();
1193
+ if (!trimmed)
1194
+ return;
1195
+ const images = imageRefsFor(trimmed);
1196
+ if (shellImagesUnsupported(trimmed, images))
1197
+ return;
1198
+ rememberHistory(trimmed, images);
1199
+ clearDeliveredDraft();
1200
+ channel.submit(trimmed, images);
1201
+ channel.notify(t('input-queued-after-turn'), { timeoutMs: 2500 });
1202
+ };
1203
+ /**
1204
+ * Alt+Up: pull the last pending message back into the input for editing
1205
+ * (never interrupts the running turn). Refused when the running dsh-agent
1206
+ * cannot withdraw inbox messages (released package without the inbox API).
1207
+ */
1208
+ const pullBackLast = () => {
1209
+ const item = channel.pending[channel.pending.length - 1];
1210
+ if (!item)
1211
+ return;
1212
+ if (!channel.removePending(item.id)) {
1213
+ channel.notify(t('input-cannot-retract'), { color: 'warning', timeoutMs: 2500 });
1214
+ return;
1215
+ }
1216
+ restoreDraftImages({
1217
+ text: item.text,
1218
+ images: item.images ?? [],
1219
+ });
1220
+ setInput(item.text);
1221
+ updateFoldBlock(null);
1222
+ setSelectedCommand(0);
1223
+ setFileSelected(0);
1224
+ channel.notify(t('input-retracted'), { timeoutMs: 2000 });
1225
+ };
1226
+ /**
1227
+ * Withdraw the queued copy of the text `↑` just recalled (issue #986): the
1228
+ * message is still parked in the inbox, so editing it and sending again
1229
+ * would run the same text twice. Alt+Up withdraws explicitly; walking the
1230
+ * history to the same text has to land in the same place. The newest match
1231
+ * wins — `↑` walks newest-first and the queue is FIFO. A message the
1232
+ * running turn already claimed cannot be withdrawn, and saying so beats
1233
+ * pretending it was.
1234
+ */
1235
+ const retractRecalledCopy = (text) => {
1236
+ let target;
1237
+ for (const item of channel.pending) {
1238
+ if (item.text === text)
1239
+ target = item;
1240
+ }
1241
+ if (target === undefined)
1242
+ return;
1243
+ if (channel.removePending(target.id)) {
1244
+ channel.notify(t('input-retracted'), { timeoutMs: 2000 });
1245
+ }
1246
+ else {
1247
+ channel.notify(t('input-cannot-retract'), { color: 'warning', timeoutMs: 2500 });
1248
+ }
1249
+ };
1250
+ /**
1251
+ * Ctrl+Enter: abort the running turn and send the input immediately — the
1252
+ * model stops what it is doing and starts on this message right away.
1253
+ */
1254
+ const interruptSend = () => {
1255
+ const trimmed = value.trim();
1256
+ if (!trimmed) {
1257
+ channel.notify(t('input-empty'), { color: 'warning' });
1258
+ return;
1259
+ }
1260
+ // Abort the running turn and deliver: previously queued pending
1261
+ // messages first (FIFO), then the current input — all processed
1262
+ // immediately once the abort settles.
1263
+ const images = imageRefsFor(trimmed);
1264
+ const queued = [
1265
+ ...channel.pending.map(item => ({ text: item.text, images: item.images ?? [] })),
1266
+ { text: value, images },
1267
+ ];
1268
+ const count = channel.interruptAndDeliver(queued);
1269
+ if (count === 0)
1270
+ return;
1271
+ rememberHistory(trimmed, images);
1272
+ clearDeliveredDraft();
1273
+ channel.notify(t('input-interrupt-immediate'), { timeoutMs: 2500 });
1274
+ };
1275
+ /**
1276
+ * Execute a slash command (built-in, plugin-registered, or hidden) when
1277
+ * the input resolves to one: the name parses as the first token so
1278
+ * `/plan off` dispatches `plan` with its argument text, and the merged
1279
+ * command list (locals + registry) decides whether the line is a command
1280
+ * at all. Hidden commands are recognized even though they are intentionally
1281
+ * absent from the suggestion/help catalogs.
1282
+ */
1283
+ const tryRunCommand = (text) => {
1284
+ if (!text.startsWith('/'))
1285
+ return false;
1286
+ const parsed = parseCommandName(text);
1287
+ if (parsed === undefined)
1288
+ return false;
1289
+ const command = channel.commandList.find(entry => entry.name === parsed.name);
1290
+ const known = command !== undefined || isHiddenCommandName(parsed.name);
1291
+ if (!known)
1292
+ return false;
1293
+ const generation = syncImageGeneration();
1294
+ const revision = draftRevisionRef.current;
1295
+ const editSequence = inputEditSequenceRef.current;
1296
+ if (pendingCommandRef.current?.generation === generation
1297
+ && pendingCommandRef.current.revision === revision
1298
+ && pendingCommandRef.current.editSequence === editSequence) {
1299
+ channel.notify(t('command-running'), { color: 'warning', timeoutMs: 2500 });
1300
+ return true;
1301
+ }
1302
+ if (pendingCommandRef.current !== null)
1303
+ pendingCommandRef.current = null;
1304
+ const images = imageRefsFor(text);
1305
+ // Commands are an explicit non-model route. Unless their registry
1306
+ // descriptor opted into composer images, refuse before dispatch and keep
1307
+ // the exact draft/capabilities so the user can edit or send them normally.
1308
+ // Completion-only filesystem skills still fall through to the model.
1309
+ const modelRoutedSkill = command?.skill === true && command.external !== true;
1310
+ if (images.length > 0 && !modelRoutedSkill && command?.acceptsImages !== true) {
1311
+ channel.notify(t('command-images-unsupported', { name: parsed.name }), {
1312
+ color: 'warning',
1313
+ timeoutMs: 4000,
1314
+ });
1315
+ return true;
1316
+ }
1317
+ const lease = captureDraftImageLease();
1318
+ const draftText = valueRef.current;
1319
+ const draftImages = imageRefsFor(draftText);
1320
+ const handled = onRunCommand(parsed.name, parsed.rawInput, images);
1321
+ if (handled === true) {
1322
+ // A local command consumed the line inside the screen.
1323
+ warnStaleImageTokens(text, images);
1324
+ rememberHistory(text.trim(), images);
1325
+ clearDeliveredDraft();
1326
+ }
1327
+ else if (handled !== false) {
1328
+ // Registry commands settle asynchronously. Keep the exact draft and
1329
+ // capabilities in place until admission succeeds; a handler/admission
1330
+ // error deliberately leaves them editable. A late success may clear
1331
+ // only the snapshot it actually submitted, never text/images typed
1332
+ // while the command was running or a replacement session's draft.
1333
+ const attempt = { token: Symbol('command-attempt'), generation, revision, editSequence };
1334
+ pendingCommandRef.current = attempt;
1335
+ void handled.then((consume) => {
1336
+ if (!consume
1337
+ || !draftImageLeaseIsCurrent(lease)
1338
+ || inputEditSequenceRef.current !== editSequence)
1339
+ return;
1340
+ rememberHistory(text.trim(), images);
1341
+ const currentText = valueRef.current;
1342
+ const currentImages = imageRefsFor(currentText);
1343
+ if (currentText === draftText && sameImageRefs(currentImages, draftImages)) {
1344
+ clearDeliveredDraft();
1345
+ }
1346
+ }).catch((error) => {
1347
+ if (!draftImageLeaseIsCurrent(lease))
1348
+ return;
1349
+ channel.notify(error instanceof Error ? error.message : String(error), {
1350
+ color: 'error',
1351
+ timeoutMs: 5000,
1352
+ });
1353
+ }).finally(() => {
1354
+ if (pendingCommandRef.current?.token === attempt.token)
1355
+ pendingCommandRef.current = null;
1356
+ });
1357
+ }
1358
+ return handled !== false;
1359
+ };
1360
+ /**
1361
+ * The Enter main path, shared by the inline prompt, the expanded
1362
+ * editor's Ctrl+Enter, and its Send button:
1363
+ * - command menu open → run the SELECTED command (never send `/mo`);
1364
+ * - model working → STEER into the running turn (next step boundary,
1365
+ * agent continues — the "immediate" send; Codex/pi semantics);
1366
+ * - otherwise → submit directly (or run a unique command).
1367
+ * Reads valueRef so a key batch (typing + Enter in one stdin read)
1368
+ * operates on the text the preceding keys produced.
1369
+ */
1370
+ const handleEnter = () => {
1371
+ // A single Enter can arrive as two events in cmd pipelines (`\r`
1372
+ // parsed as return + a raw `\n` line): collapse them so one keypress
1373
+ // never sends the message twice.
1374
+ const now = Date.now();
1375
+ if (now - lastEnterAtRef.current < 80)
1376
+ return;
1377
+ lastEnterAtRef.current = now;
1378
+ const value = valueRef.current;
1379
+ if (overlayOpen) {
1380
+ const command = suggestions[selectedCommand];
1381
+ if (command) {
1382
+ tryRunCommand(command.commandLine);
1383
+ return;
1384
+ }
1385
+ }
1386
+ // File-completion overlay open → Enter accepts the selection (same
1387
+ // contract as the command menu: the overlay owns Enter while open).
1388
+ if (fileOverlayOpen) {
1389
+ const file = fileMatches[fileSelected];
1390
+ if (file) {
1391
+ acceptFile(file);
1392
+ return;
1393
+ }
1394
+ }
1395
+ if (channel.working && value.trim() !== '') {
1396
+ // Immediate-command semantics: /btw and /skills are exempt from
1397
+ // steering — neither command interrupts the running turn. Hidden
1398
+ // UI-only easter eggs (e.g. /deepseek) are also safe to run while
1399
+ // streaming. Every other input keeps the steer behavior so /new
1400
+ // /model etc. stay idle-only.
1401
+ const parsed = value.startsWith('/') ? parseCommandName(value) : undefined;
1402
+ if (parsed !== undefined && (((parsed.name === 'btw' || parsed.name === 'skills')
1403
+ && channel.commandList.some(c => c.name === parsed.name))
1404
+ || isHiddenCommandName(parsed.name))) {
1405
+ if (tryRunCommand(value))
1406
+ return;
1407
+ }
1408
+ steerSend(value);
1409
+ return;
1410
+ }
1411
+ if (!tryRunCommand(value))
1412
+ submitText(value);
1413
+ };
1414
+ /** Expand/collapse the fullscreen editor (shortcut + ✎ affordance).
1415
+ * Expanding also DROPS any fold block: the fullscreen view shows and
1416
+ * edits the full text, and the block's atomic-clamp semantics (caret
1417
+ * pushed to its edges, selection clamped to one side) would contradict
1418
+ * that — the chip's own click-to-expand already means "unfold". */
1419
+ const toggleExpand = () => {
1420
+ const next = !expandedRef.current;
1421
+ expandedRef.current = next;
1422
+ setExpanded(next);
1423
+ if (next) {
1424
+ expandedScrollRef.current = 0;
1425
+ if (foldBlockRef.current)
1426
+ updateFoldBlock(null);
1427
+ }
1428
+ // Geometry changed wholesale (a fullscreen cover): the double-click
1429
+ // self-detection's screen-cell memory is void, same as on resize.
1430
+ lastClickAtRef.current = 0;
1431
+ lastClickColRef.current = -1;
1432
+ lastClickRowRef.current = -1;
1433
+ };
1434
+ /** Withdraw the fullscreen editor, keeping text/caret/selection intact. */
1435
+ const collapseEditor = () => {
1436
+ expandedRef.current = false;
1437
+ setExpanded(false);
1438
+ lastClickAtRef.current = 0;
1439
+ lastClickColRef.current = -1;
1440
+ lastClickRowRef.current = -1;
1441
+ };
1442
+ /** The editor's explicit send (Ctrl+Enter / Send button): the Enter main
1443
+ * path, then collapse — an empty draft just collapses. */
1444
+ const submitFromEditor = () => {
1445
+ handleEnter();
1446
+ collapseEditor();
1447
+ };
1448
+ /** Clipboard reads are asynchronous; insert against the latest render so
1449
+ * typing while PowerShell owns the clipboard never gets overwritten.
1450
+ * An active selection is replaced by the insert. Returns the resulting
1451
+ * value and the insertion offset so callers can apply the paste fold. */
1452
+ const insertClipboardAtCaret = (text) => {
1453
+ text = sanitizeEditableText(text);
1454
+ const current = valueRef.current;
1455
+ const sel = selectionRef.current;
1456
+ const position = sel ? sel.start : cursorRef.current;
1457
+ const next = sel
1458
+ ? current.slice(0, sel.start) + text + current.slice(sel.end)
1459
+ : current.slice(0, position) + text + current.slice(position);
1460
+ setInput(next, position + text.length);
1461
+ setSelectedCommand(0);
1462
+ setFileSelected(0);
1463
+ return { next, at: position };
1464
+ };
1465
+ /** Read one local image file and stage it through the channel, returning
1466
+ * an opaque capability. Shared by every image paste path:
1467
+ * clipboard bitmap export, Finder-copied files, and pasted drop paths.
1468
+ * A Finder/drop path is untrusted input: one bounded descriptor read
1469
+ * applies the profile limit before bytes enter the composer. */
1470
+ const stageImagePath = async (path, lease) => {
1471
+ if (!draftImageLeaseIsCurrent(lease)) {
1472
+ throw new Error('the draft changed while the image was being staged');
1473
+ }
1474
+ const limits = channel.stagedImageLimits?.();
1475
+ if (limits === undefined)
1476
+ throw new Error('image attachments are unavailable in this profile');
1477
+ // One-image paste operations are serialized, so this is the cumulative
1478
+ // draft count (not merely the current Finder batch). Refuse before the
1479
+ // descriptor read/save and never let the channel's 128-capability cache
1480
+ // become an accidental per-command batch size.
1481
+ if (draftImagesRef.current.size >= limits.maxImagesPerMessage) {
1482
+ throw new Error('image count exceeds this profile\'s per-message limit');
1483
+ }
1484
+ const data = await readBoundedRegularFile(path, limits.maxImageBytes);
1485
+ if (!draftImageLeaseIsCurrent(lease)) {
1486
+ throw new Error('the draft changed while the image was being staged');
1487
+ }
1488
+ return channel.stageComposerImage({
1489
+ data,
1490
+ // Callers gate on imagePathMediaType; the assertion is unreachable.
1491
+ mediaType: imagePathMediaType(path) ?? 'image/png',
1492
+ name: basename(path),
1493
+ // The preview card's path row: the file that was read, as an
1494
+ // absolute path (a clipboard bitmap shows its temp export).
1495
+ path: resolve(path),
1496
+ }, lease.generation);
1497
+ };
1498
+ /** Queue one complete image operation (save plus synchronous bind/insert).
1499
+ * Keeping the visible mutation inside the chain makes terminal drop order
1500
+ * independent of attachment-store latency. Rejections settle the chain so
1501
+ * one bad file cannot wedge later drops. */
1502
+ const enqueueImageWork = (work) => {
1503
+ const queued = imageStageChainRef.current.then(work, work);
1504
+ imageStageChainRef.current = queued.then(() => undefined, () => undefined);
1505
+ return queued;
1506
+ };
1507
+ /** Success notice for one staged image. An adapted paste says what the user
1508
+ * actually got (stored dimensions, stored format, filled alpha) — naming it
1509
+ * is the difference between a reported adaptation and a silently rewritten
1510
+ * image. */
1511
+ const stagedImageNotice = (token, handle) => {
1512
+ const adjustment = handle.adjustment;
1513
+ if (adjustment === undefined)
1514
+ return t('input-image-pasted', { token });
1515
+ const details = [];
1516
+ if (adjustment.resized) {
1517
+ details.push(t('input-image-detail-resized', {
1518
+ width: adjustment.width,
1519
+ height: adjustment.height,
1520
+ }));
1521
+ }
1522
+ if (adjustment.mediaType !== adjustment.sourceMediaType) {
1523
+ const from = mediaTypeLabel(adjustment.sourceMediaType);
1524
+ const to = mediaTypeLabel(adjustment.mediaType);
1525
+ details.push(adjustment.flattened
1526
+ ? t('input-image-detail-converted-flattened', { from, to })
1527
+ : t('input-image-detail-converted', { from, to }));
1528
+ }
1529
+ // An adjustment always describes a resize or a conversion; anything else
1530
+ // keeps the plain notice rather than an empty parenthetical. ' · ' joins
1531
+ // the clauses in both shipped languages.
1532
+ if (details.length === 0)
1533
+ return t('input-image-pasted', { token });
1534
+ return t('input-image-pasted-adjusted', { token, detail: details.join(' · ') });
1535
+ };
1536
+ const discardStagedHandles = (handles) => {
1537
+ for (const stageId of new Set(handles.map(handle => handle.stageId))) {
1538
+ channel.discardStagedImage(stageId);
1539
+ }
1540
+ };
1541
+ /** Assign presentation numbering only after staging succeeds. Existing raw
1542
+ * tokens (including stale history) reserve their number, so a fresh image
1543
+ * can never visually alias one. The counter never goes backwards within
1544
+ * one session generation, which also keeps delete/undo safe. */
1545
+ const bindStagedImage = (handle, lease) => {
1546
+ if (!draftImageLeaseIsCurrent(lease)) {
1547
+ // The save completed, but its initiating draft was already submitted,
1548
+ // replaced, or unmounted. Reclaim this otherwise-unreachable channel
1549
+ // capability instead of waiting for the session FIFO to evict it.
1550
+ channel.discardStagedImage(handle.stageId);
1551
+ throw new Error('the draft changed while the image was being staged');
1552
+ }
1553
+ if (channel.hasStagedImage?.(handle.stageId) !== true) {
1554
+ throw new Error('the draft changed while the image was being staged');
1555
+ }
1556
+ let token = `[Image #${nextImageNumberRef.current}]`;
1557
+ while (valueRef.current.includes(token) || draftImagesRef.current.has(token)) {
1558
+ nextImageNumberRef.current += 1;
1559
+ token = `[Image #${nextImageNumberRef.current}]`;
1560
+ }
1561
+ nextImageNumberRef.current += 1;
1562
+ draftImagesRef.current.set(token, handle.stageId);
1563
+ return token;
1564
+ };
1565
+ /** Line index of the cursor; -1 when the cursor is at the very end. */
1566
+ const cursorLine = (text, cursorOffset) => {
1567
+ const before = text.slice(0, cursorOffset);
1568
+ return before.split('\n').length - 1;
1569
+ };
1570
+ /** Column of the cursor within its line. */
1571
+ const cursorColumn = (text, cursorOffset) => {
1572
+ const before = text.slice(0, cursorOffset);
1573
+ const line = before.split('\n').pop() ?? '';
1574
+ return line.length;
1575
+ };
1576
+ useInput((input, key, event) => {
1577
+ if (selectionActive)
1578
+ return;
1579
+ // The editor round-trip ends by resuming stdin one microtask before the
1580
+ // outcome lands — drop any key squeezed into that gap so the prompt's
1581
+ // setValue can never overwrite fresh typing (and vice versa).
1582
+ if (editorBusyRef.current)
1583
+ return;
1584
+ // Ctrl+Shift+E (remappable via /settings): toggle the fullscreen draft
1585
+ // editor. Matched before anything else so it works both while editing
1586
+ // and from an idle prompt; selectionActive has already returned above.
1587
+ // Refused while the feature is turned off in /settings.
1588
+ if (expandEnabled && actionMatches('expandEditor', input, key)) {
1589
+ event?.stopImmediatePropagation();
1590
+ toggleExpand();
1591
+ return;
1592
+ }
1593
+ // App deliberately dispatches every parsed key from one stdin read in a
1594
+ // single React update. Read the synchronous mirrors so each event sees
1595
+ // the text/caret produced by the preceding event in that batch.
1596
+ const value = valueRef.current;
1597
+ const cursor = cursorRef.current;
1598
+ const selection = selectionRef.current;
1599
+ // ── caret-driven image preview ──────────────────────────────────────
1600
+ // Esc dismisses the preview the caret opened, before any other Esc
1601
+ // meaning (help stays above it: the help menu is modal over the prompt).
1602
+ if (key.escape && caretPreviewOpen && !helpOpen) {
1603
+ event?.stopImmediatePropagation();
1604
+ onDismissCaretPreview?.();
1605
+ return;
1606
+ }
1607
+ // ── mouse selection (drag / Shift+click / double-click) ─────────────
1608
+ // Layered ahead of the fold-block rules: with an active selection, Esc
1609
+ // ONLY drops the highlight (text untouched), and Backspace/Delete
1610
+ // delete the selected span. Arrows/typing handle the selection at their
1611
+ // own arms below.
1612
+ if (key.escape && selection && !helpOpen && !overlayOpen && !fileOverlayOpen) {
1613
+ event.stopImmediatePropagation();
1614
+ clearSelection();
1615
+ return;
1616
+ }
1617
+ if ((key.backspace || key.delete) && selection) {
1618
+ deleteInputRange(selection.start, selection.end);
1619
+ setSelectedCommand(0);
1620
+ setFileSelected(0);
1621
+ return;
1622
+ }
1623
+ // ── 全屏草稿编辑(expandEditor,默认 Ctrl+Shift+E / 输入行 ✎)─────
1624
+ // 展开态拥有屏幕;Esc 收起(有选区时上面的 selection 分支已先行只清
1625
+ // 选区)。滚轮不经此——编辑区的 onWheel 位置路由直接驱动滚动窗口。
1626
+ if (key.escape && expandedRef.current) {
1627
+ // Collapse runs AHEAD of the fold-block/vim Esc meanings: the
1628
+ // fullscreen cover is the outermost modal layer.
1629
+ event?.stopImmediatePropagation();
1630
+ collapseEditor();
1631
+ return;
1632
+ }
1633
+ // Fold block: Esc expands it — it must NEVER clear text
1634
+ // that LOOKS like one line; Backspace at the block's tail / Delete at
1635
+ // its head deletes the WHOLE block in one key; ←/→ jump over the
1636
+ // atomic block. Typing NEVER expands it — the caret lives outside the
1637
+ // block and edits land in the visible text around it.
1638
+ const block = foldBlockRef.current;
1639
+ // Line-level moves/edits (↑/↓/Home/End/Ctrl+A/E/U/K/W) treat the
1640
+ // block as an atomic row: boundaries that would land inside it are
1641
+ // clamped to its edges.
1642
+ const clampRowStart = (pos) => block && cursor >= block.end ? Math.max(pos, block.end) : pos;
1643
+ const clampRowEnd = (pos) => block && cursor <= block.start ? Math.min(pos, block.start) : pos;
1644
+ if (block) {
1645
+ if (key.escape) {
1646
+ updateFoldBlock(null);
1647
+ return;
1648
+ }
1649
+ if ((key.backspace && cursor === block.end) || (key.delete && cursor === block.start)) {
1650
+ const next = value.slice(0, block.start) + value.slice(block.end);
1651
+ updateFoldBlock(null);
1652
+ setInput(next, block.start);
1653
+ setSelectedCommand(0);
1654
+ setFileSelected(0);
1655
+ return;
1656
+ }
1657
+ if (key.leftArrow && cursor === block.end) {
1658
+ setInput(value, block.start);
1659
+ return;
1660
+ }
1661
+ if (key.rightArrow && cursor === block.start) {
1662
+ setInput(value, block.end);
1663
+ return;
1664
+ }
1665
+ }
1666
+ // Grapheme boundaries of the current text: every caret move / delete
1667
+ // below snaps onto one of these offsets (never mid-cluster).
1668
+ const bounds = graphemeBoundaries(value);
1669
+ /** Insert text at the caret (typing, paste) and dismiss overlays. An
1670
+ * active selection is REPLACED by the insert (standard editor
1671
+ * semantics). Returns the insertion offset so callers can derive the
1672
+ * inserted span (paste fold). */
1673
+ const insertAtCaret = (text) => {
1674
+ if (helpOpen)
1675
+ onToggleHelp();
1676
+ const sel = selectionRef.current;
1677
+ const at = sel ? sel.start : cursor;
1678
+ const next = sel
1679
+ ? value.slice(0, sel.start) + text + value.slice(sel.end)
1680
+ : value.slice(0, cursor) + text + value.slice(cursor);
1681
+ setInput(next, at + text.length);
1682
+ setSelectedCommand(0);
1683
+ setFileSelected(0);
1684
+ return at;
1685
+ };
1686
+ // Bracketed paste (terminal paste — Ctrl+Shift+V / right-click): insert
1687
+ // at the caret after removing terminal controls and expanding tabs.
1688
+ // Newlines remain data — they are NOT Enter — so this branch runs before
1689
+ // the whole-line submit rule.
1690
+ if (event?.isPasted && input.length > 0) {
1691
+ const text = sanitizeEditableText(input.replace(/\r\n/g, '\n').replace(/\r/g, '\n'));
1692
+ // Desktop drops reach the TUI as pasted text (Ghostty forwards
1693
+ // Shell.escape(path) through the PTY with no drop boundary). Only a
1694
+ // paste that IS one unambiguous existing local image path stages as
1695
+ // an image; any parse/stat/staging failure inserts the text verbatim.
1696
+ const droppedPath = parsePastedImagePath(text);
1697
+ if (droppedPath !== null) {
1698
+ const lease = captureDraftImageLease();
1699
+ if (helpOpen)
1700
+ onToggleHelp();
1701
+ setSelectedCommand(0);
1702
+ setFileSelected(0);
1703
+ void enqueueImageWork(async () => {
1704
+ const handle = await stageImagePath(droppedPath, lease);
1705
+ const token = bindStagedImage(handle, lease);
1706
+ // Bind and insert share this synchronous continuation: setInput's
1707
+ // sidecar pruning can never observe a bound-but-not-visible token.
1708
+ insertClipboardAtCaret(`${token} `);
1709
+ channel.notify(stagedImageNotice(token, handle), { timeoutMs: 2500 });
1710
+ })
1711
+ .catch(() => {
1712
+ if (!draftImageLeaseIsCurrent(lease))
1713
+ return;
1714
+ // A real path/read/stage failure keeps the terminal paste as text.
1715
+ // A revoked lease is handled above and must not edit a newer draft.
1716
+ insertClipboardAtCaret(text);
1717
+ });
1718
+ return;
1719
+ }
1720
+ const at = insertAtCaret(text);
1721
+ // A big paste becomes a fold block right away (hover peeks
1722
+ // at it); an existing block is replaced by the new paste's span.
1723
+ // The EXPANDED editor never folds — pasting there is plain text
1724
+ // (fold semantics would clamp the caret out of the pasted span).
1725
+ if (!expandedRef.current && isBigInput(text))
1726
+ updateFoldBlock({ start: at, end: at + text.length });
1727
+ return;
1728
+ }
1729
+ // Clipboard paste (default Ctrl+V / Cmd+V, plus the Alt+V alias for
1730
+ // terminals that intercept Ctrl+V — combos are user-remappable via
1731
+ // /settings): raw mode hands the key to the app, so the clipboard is
1732
+ // read here — text, file paths when the file manager copied files, or
1733
+ // an exported temp-file path when the clipboard holds a raw image.
1734
+ if (actionMatches('paste', input, key)) {
1735
+ if (clipboardBusyRef.current)
1736
+ return;
1737
+ const lease = captureDraftImageLease();
1738
+ // Match insertAtCaret's overlay/selection dismissal up front: the
1739
+ // async continuation below only sets value/cursor, so a paste landing
1740
+ // while the help overlay is open would otherwise insert behind it.
1741
+ if (helpOpen)
1742
+ onToggleHelp();
1743
+ setSelectedCommand(0);
1744
+ setFileSelected(0);
1745
+ clipboardBusyRef.current = true;
1746
+ void readClipboard()
1747
+ .then(async (content) => {
1748
+ // Every `kind: image` path is a private temp export owned by this
1749
+ // paste, including TIFF/BMP/SVG formats the attachment profile
1750
+ // cannot stage. Ownership must not depend on format support.
1751
+ const temporaryImagePath = content?.kind === 'image' ? content.path : undefined;
1752
+ try {
1753
+ if (!draftImageLeaseIsCurrent(lease))
1754
+ return;
1755
+ if (content === null) {
1756
+ channel.notify(t('input-clipboard-empty'), { color: 'warning' });
1757
+ return;
1758
+ }
1759
+ if (content.kind === 'unavailable') {
1760
+ channel.notify(t('input-clipboard-unavailable'), { color: 'warning' });
1761
+ return;
1762
+ }
1763
+ if (content.kind === 'image') {
1764
+ if (imagePathMediaType(content.path) === undefined) {
1765
+ channel.notify(t('input-image-format-unsupported'), { color: 'warning', timeoutMs: 5000 });
1766
+ return;
1767
+ }
1768
+ try {
1769
+ await enqueueImageWork(async () => {
1770
+ const handle = await stageImagePath(content.path, lease);
1771
+ const token = bindStagedImage(handle, lease);
1772
+ insertClipboardAtCaret(`${token} `);
1773
+ channel.notify(stagedImageNotice(token, handle), { timeoutMs: 2500 });
1774
+ });
1775
+ }
1776
+ catch (error) {
1777
+ if (!draftImageLeaseIsCurrent(lease))
1778
+ return;
1779
+ const message = error instanceof Error ? error.message : String(error);
1780
+ channel.notify(t('input-image-paste-failed', { err: message }), { color: 'warning', timeoutMs: 5000 });
1781
+ }
1782
+ return;
1783
+ }
1784
+ if (content.kind === 'files') {
1785
+ // Finder/Explorer-copied image FILES stage like clipboard
1786
+ // bitmaps (macOS furl offers exactly one). Other files keep the
1787
+ // quoted/@ path insert, and an image that fails to stage falls
1788
+ // back to its `@` reference — the mention pipeline still
1789
+ // attaches it at submit.
1790
+ let insertedStaged = false;
1791
+ try {
1792
+ insertedStaged = await enqueueImageWork(async () => {
1793
+ const maxImages = channel.stagedImageLimits?.()?.maxImagesPerMessage ?? 0;
1794
+ const { parts, staged, failure, failureCode } = await stageClipboardFilePaths(content.paths, path => stageImagePath(path, lease), filePath => formatClipboardInsert({ kind: 'files', paths: [filePath] }), Math.max(0, maxImages - draftImagesRef.current.size));
1795
+ if (!draftImageLeaseIsCurrent(lease)) {
1796
+ discardStagedHandles(staged);
1797
+ return true;
1798
+ }
1799
+ const boundTokens = [];
1800
+ try {
1801
+ const rendered = parts.map(part => {
1802
+ if (part.kind === 'text')
1803
+ return part.value;
1804
+ const token = bindStagedImage(part.value, lease);
1805
+ boundTokens.push(token);
1806
+ return token;
1807
+ });
1808
+ if (failure !== '') {
1809
+ const message = failureCode === 'image-limit' ? t('input-image-paste-limit') : failure;
1810
+ channel.notify(t('input-image-paste-failed', { err: message }), { color: 'warning', timeoutMs: 5000 });
1811
+ }
1812
+ if (boundTokens.length === 0)
1813
+ return false;
1814
+ // All bindings and their visible labels enter together;
1815
+ // typing while an earlier file saves cannot prune one.
1816
+ insertClipboardAtCaret(`${rendered.join(' ')} `);
1817
+ // A batch cannot itemise every image in one line, but it must
1818
+ // still say that some of them were not stored as pasted.
1819
+ const adapted = staged.filter(handle => handle.adjustment !== undefined).length;
1820
+ channel.notify(boundTokens.length === 1
1821
+ ? stagedImageNotice(boundTokens[0], staged[0])
1822
+ : adapted > 0
1823
+ ? t('input-images-staged-adapted', { count: boundTokens.length, adapted })
1824
+ : t('input-images-staged', { count: boundTokens.length }), { timeoutMs: 2500 });
1825
+ return true;
1826
+ }
1827
+ catch (error) {
1828
+ for (const token of boundTokens)
1829
+ draftImagesRef.current.delete(token);
1830
+ discardStagedHandles(staged);
1831
+ throw error;
1832
+ }
1833
+ });
1834
+ }
1835
+ catch (error) {
1836
+ if (!draftImageLeaseIsCurrent(lease))
1837
+ return;
1838
+ const message = error instanceof Error ? error.message : String(error);
1839
+ channel.notify(t('input-image-paste-failed', { err: message }), { color: 'warning', timeoutMs: 5000 });
1840
+ }
1841
+ if (insertedStaged)
1842
+ return;
1843
+ // Nothing staged: fall through to the verbatim files insert.
1844
+ }
1845
+ if (!draftImageLeaseIsCurrent(lease))
1846
+ return;
1847
+ // Insert against the LIVE input state: the read above resolved
1848
+ // asynchronously and the user may have typed while waiting.
1849
+ const text = sanitizeEditableText(formatClipboardInsert(content));
1850
+ const { at } = insertClipboardAtCaret(text);
1851
+ // Same fold as bracketed paste — but never inside the expanded
1852
+ // editor (plain text there, see the isPasted branch).
1853
+ if (!expandedRef.current && isBigInput(text))
1854
+ updateFoldBlock({ start: at, end: at + text.length });
1855
+ }
1856
+ finally {
1857
+ // Clipboard bitmaps are private temp exports owned by this paste,
1858
+ // never durable attachment storage. Clean them on success,
1859
+ // rejection, draft invalidation, and session replacement alike.
1860
+ if (temporaryImagePath !== undefined) {
1861
+ await unlink(temporaryImagePath).catch(() => undefined);
1862
+ }
1863
+ }
1864
+ })
1865
+ .catch(() => {
1866
+ if (!draftImageLeaseIsCurrent(lease))
1867
+ return;
1868
+ channel.notify(t('input-clipboard-read-failed'), { color: 'warning' });
1869
+ })
1870
+ .finally(() => {
1871
+ // A rejected read must never wedge Ctrl+V for the rest of the
1872
+ // session.
1873
+ clipboardBusyRef.current = false;
1874
+ });
1875
+ return;
1876
+ }
1877
+ // Help is modal for modified keys and every Enter variant. The paste
1878
+ // branch above is the intentional exception: paste closes Help and
1879
+ // inserts visibly.
1880
+ // Swallow here before editor/submit/interrupt branches can mutate hidden
1881
+ // composer or working-turn state; plain typing still dismisses Help below.
1882
+ if (helpOpen && !key.escape && (key.ctrl || key.meta || key.super || key.return || input.includes('\n') || input.includes('\r'))) {
1883
+ event.stopImmediatePropagation();
1884
+ return;
1885
+ }
1886
+ // Ctrl+G (remappable via /settings): edit the current draft in
1887
+ // $VISUAL/$EDITOR (issue #123, readline's edit-and-execute-command). The
1888
+ // draft is written to a temp file, the terminal is handed to the editor
1889
+ // (Ink's alt-screen handoff), and the saved text replaces the input when
1890
+ // it differs. The util maps every failure to an outcome, but the
1891
+ // catch/finally here is the hard guarantee: a rejected promise must
1892
+ // never kill the process, and the busy flag must always clear or the
1893
+ // editor key stays locked forever.
1894
+ if (actionMatches('editor', input, key)) {
1895
+ // Opening the editor starts a new async draft lifecycle immediately:
1896
+ // fence an older paste before the terminal handoff, but retain already
1897
+ // bound image capabilities. setInput below prunes only tokens the user
1898
+ // actually removed in the editor.
1899
+ syncImageGeneration();
1900
+ advanceDraftRevision();
1901
+ const editorLease = captureDraftImageLease();
1902
+ editorBusyRef.current = true;
1903
+ void (async () => {
1904
+ try {
1905
+ const outcome = await editInExternalEditor(value);
1906
+ // Session switches, clears, history restores, and unmount all
1907
+ // revoke this editor round-trip. Never write its old draft into a
1908
+ // newer composer after the terminal handoff returns.
1909
+ if (!draftImageLeaseIsCurrent(editorLease))
1910
+ return;
1911
+ if (outcome.kind === 'edited') {
1912
+ updateFoldBlock(null);
1913
+ setInput(outcome.text);
1914
+ setSelectedCommand(0);
1915
+ setFileSelected(0);
1916
+ }
1917
+ else if (outcome.kind === 'unavailable') {
1918
+ channel.notify(t('input-editor-unavailable'), { color: 'warning' });
1919
+ }
1920
+ else if (outcome.kind === 'failed') {
1921
+ channel.notify(t('input-editor-failed', { name: outcome.message }), {
1922
+ color: 'warning',
1923
+ });
1924
+ }
1925
+ }
1926
+ catch {
1927
+ if (!draftImageLeaseIsCurrent(editorLease))
1928
+ return;
1929
+ channel.notify(t('input-editor-failed', { name: 'unknown' }), {
1930
+ color: 'warning',
1931
+ });
1932
+ }
1933
+ finally {
1934
+ editorBusyRef.current = false;
1935
+ }
1936
+ })();
1937
+ return;
1938
+ }
1939
+ // Ctrl+J is the portable multiline fallback when a terminal cannot
1940
+ // report modifiers on Enter. Legacy terminals deliver bare LF (`enter`),
1941
+ // while kitty/modifyOtherKeys encode it as an exact Ctrl+J key.
1942
+ const isCtrlJ = input === 'j' && key.ctrl && !key.shift && !key.meta && !key.super;
1943
+ if ((input === '\n' && event?.keypress.name === 'enter') || isCtrlJ) {
1944
+ insertAtCaret('\n');
1945
+ return;
1946
+ }
1947
+ // Whole-line input from Windows ConPTY pipelines (cmd batch -> node):
1948
+ // the trailing CR/LF marks a complete line to submit. A bare CR/CRLF is
1949
+ // Enter, while real multi-char piped lines keep the legacy direct-submit
1950
+ // path. The expanded editor treats piped lines as DATA — CR/LF
1951
+ // normalizes to '\n' and inserts (sending needs Ctrl+Enter there), so a
1952
+ // fast batch never dumps raw '\r' into the draft.
1953
+ if (input.includes('\n') || input.includes('\r')) {
1954
+ if (expandedRef.current) {
1955
+ insertAtCaret(sanitizeEditableText(input.replace(/\r\n/g, '\n').replace(/\r/g, '\n')));
1956
+ return;
1957
+ }
1958
+ if (/^[\r\n]+$/.test(input)) {
1959
+ handleEnter();
1960
+ return;
1961
+ }
1962
+ const line = (value + input).trim();
1963
+ if (line.startsWith('/')) {
1964
+ const matches = channel.commandCompletions(line);
1965
+ if (matches.length === 1) {
1966
+ tryRunCommand(matches[0].commandLine);
1967
+ return;
1968
+ }
1969
+ }
1970
+ if (!tryRunCommand(line))
1971
+ submitText(line);
1972
+ return;
1973
+ }
1974
+ if (key.return && isMod(key)) {
1975
+ // Ctrl+Enter / Cmd+Enter: in the EXPANDED editor this is the explicit
1976
+ // send (Enter inserts newlines there, so sending needs its own key);
1977
+ // inline it interrupts the running turn and processes this message
1978
+ // immediately (Windows Terminal sends CSI 13;5u / 13;1;5u).
1979
+ if (expandedRef.current) {
1980
+ submitFromEditor();
1981
+ }
1982
+ else {
1983
+ interruptSend();
1984
+ }
1985
+ return;
1986
+ }
1987
+ if (key.return && (key.shift || key.meta)) {
1988
+ // Shift+Enter / Option+Enter: insert a newline at the caret
1989
+ // (multi-line input). Shift+Enter only arrives when the terminal
1990
+ // supports extended key reporting (kitty/modifyOtherKeys allowlist in
1991
+ // ink/terminal.ts); Option+Enter (ESC CR) is the fallback on terminals
1992
+ // that can't report shift — e.g. macOS Terminal.app (issue #110).
1993
+ insertAtCaret('\n');
1994
+ return;
1995
+ }
1996
+ if (key.return && expandedRef.current) {
1997
+ // Expanded editor: plain Enter inserts a newline (text-editor
1998
+ // semantics — long-draft editing must never misfire a send). The
1999
+ // shift/meta variants above already newline; Ctrl+Enter sends.
2000
+ insertAtCaret('\n');
2001
+ return;
2002
+ }
2003
+ if (key.return) {
2004
+ handleEnter();
2005
+ return;
2006
+ }
2007
+ // Help is modal over the composer. Backtab must not cycle the session
2008
+ // mode invisibly behind it, and plain Tab has no Help action.
2009
+ if (helpOpen && key.tab) {
2010
+ event.stopImmediatePropagation();
2011
+ return;
2012
+ }
2013
+ // Completion menus own Backtab just like plain Tab; do not mutate the
2014
+ // background session mode while the user is choosing a candidate.
2015
+ if (key.tab && key.shift && (fileOverlayOpen || overlayOpen)) {
2016
+ event.stopImmediatePropagation();
2017
+ return;
2018
+ }
2019
+ // Shift+Tab cycles the configured session modes (default: 默认 →
2020
+ // 计划模式 → 完全访问; each mode bundles plan/sandbox/approval atoms —
2021
+ // see the `modes` config). Must precede the fullscreen editor's Tab
2022
+ // indentation arm so the expanded editor participates in the cycle too —
2023
+ // the parser reports backtab as key.tab + key.shift.
2024
+ if (key.tab && key.shift) {
2025
+ void channel.cycleMode();
2026
+ return;
2027
+ }
2028
+ // Expanded editor: plain Tab inserts indentation; Shift+Tab was handled
2029
+ // above and therefore never disappears behind the fullscreen cover.
2030
+ if (expandedRef.current && key.tab) {
2031
+ if (!key.shift)
2032
+ insertAtCaret(' ');
2033
+ return;
2034
+ }
2035
+ if (key.tab && fileOverlayOpen) {
2036
+ const file = fileMatches[fileSelected];
2037
+ if (file)
2038
+ acceptFile(file);
2039
+ return;
2040
+ }
2041
+ if (key.tab && overlayOpen) {
2042
+ const command = suggestions[selectedCommand];
2043
+ if (command) {
2044
+ updateFoldBlock(null);
2045
+ setInput(command.replacement);
2046
+ }
2047
+ return;
2048
+ }
2049
+ // Tab while the model is working = queue for AFTER the turn (followup),
2050
+ // distinct from Enter's steer (Codex's "tab to queue message").
2051
+ if (key.tab && channel.working && value.trim() !== '') {
2052
+ queueSend(value);
2053
+ return;
2054
+ }
2055
+ // Help is a viewport, not prompt history. It deliberately owns every
2056
+ // vertical navigation event while visible; otherwise Up/Down silently
2057
+ // walk the input history and the clipped command rows remain unreachable.
2058
+ if (helpOpen) {
2059
+ const page = Math.max(1, helpViewportHeight - 2);
2060
+ if (key.upArrow || key.wheelUp) {
2061
+ helpScrollRef.current?.scrollBy(key.wheelUp ? -3 : -1);
2062
+ event.stopImmediatePropagation();
2063
+ return;
2064
+ }
2065
+ if (key.downArrow || key.wheelDown) {
2066
+ helpScrollRef.current?.scrollBy(key.wheelDown ? 3 : 1);
2067
+ event.stopImmediatePropagation();
2068
+ return;
2069
+ }
2070
+ if (key.pageUp || key.pageDown) {
2071
+ helpScrollRef.current?.scrollBy(key.pageUp ? -page : page);
2072
+ event.stopImmediatePropagation();
2073
+ return;
2074
+ }
2075
+ if (key.home) {
2076
+ helpScrollRef.current?.scrollTo(0);
2077
+ event.stopImmediatePropagation();
2078
+ return;
2079
+ }
2080
+ if (key.end) {
2081
+ // Use a deliberately oversized absolute target rather than the
2082
+ // sticky-bottom path: compact Help may still be measuring nested
2083
+ // sections in this commit, while ScrollBox's render clamp resolves
2084
+ // the target to the exact current maximum without a follow-up frame.
2085
+ helpScrollRef.current?.scrollTo(Number.MAX_SAFE_INTEGER);
2086
+ event.stopImmediatePropagation();
2087
+ return;
2088
+ }
2089
+ }
2090
+ if (key.meta && key.upArrow) {
2091
+ // Alt+Up: pull the last pending message back for editing (pi/Codex).
2092
+ pullBackLast();
2093
+ return;
2094
+ }
2095
+ if (key.upArrow) {
2096
+ // A history walk owns the arrows until it returns to the draft: a
2097
+ // recalled entry can itself open the @ menu or the slash menu (e.g.
2098
+ // `/model`), and letting the overlay navigate here strands the stashed
2099
+ // draft — Down would cycle menu rows instead of walking back.
2100
+ if (fileOverlayOpen && historyIndex.current < 0) {
2101
+ setFileSelected(index => index <= 0 ? fileMatches.length - 1 : index - 1);
2102
+ return;
2103
+ }
2104
+ // With a fold block the caret in the tail walks the TAIL's lines
2105
+ // (the block is one atomic row); the first tail line steps over the
2106
+ // block to its head.
2107
+ if (block && cursor >= block.end) {
2108
+ const tailCursor = cursor - block.end;
2109
+ const line = cursorLine(tail, tailCursor);
2110
+ if (line > 0) {
2111
+ const upToLineStart = tail.lastIndexOf('\n', tailCursor - 1);
2112
+ const prevLineStart = upToLineStart === -1 ? 0 : tail.lastIndexOf('\n', upToLineStart - 1) + 1;
2113
+ const prevLine = tail.slice(prevLineStart, upToLineStart);
2114
+ setInput(value, block.end + prevLineStart + Math.min(cursorColumn(tail, tailCursor), prevLine.length));
2115
+ return;
2116
+ }
2117
+ setInput(value, block.start);
2118
+ return;
2119
+ }
2120
+ const line = cursorLine(value, cursor);
2121
+ if (line > 0) {
2122
+ // Move to the previous line, clamping to its length.
2123
+ const upToLineStart = value.lastIndexOf('\n', cursor - 1);
2124
+ const prevLineStart = upToLineStart === -1 ? 0 : value.lastIndexOf('\n', upToLineStart - 1) + 1;
2125
+ const prevLine = value.slice(prevLineStart, upToLineStart);
2126
+ setInput(value, prevLineStart + Math.min(cursorColumn(value, cursor), prevLine.length));
2127
+ return;
2128
+ }
2129
+ if (overlayOpen && historyIndex.current < 0) {
2130
+ setSelectedCommand(index => index <= 0 ? suggestions.length - 1 : index - 1);
2131
+ return;
2132
+ }
2133
+ seedHistory();
2134
+ if (history.current.length === 0)
2135
+ return;
2136
+ if (historyIndex.current < 0) {
2137
+ historyDraft.current = {
2138
+ text: value,
2139
+ images: imageRefsFor(value),
2140
+ };
2141
+ historyIndex.current = history.current.length - 1;
2142
+ }
2143
+ else {
2144
+ historyIndex.current = Math.max(0, historyIndex.current - 1);
2145
+ }
2146
+ const entry = history.current[historyIndex.current];
2147
+ if (entry === undefined)
2148
+ return;
2149
+ retractRecalledCopy(entry.text);
2150
+ updateFoldBlock(null);
2151
+ restoreDraftImages(entry);
2152
+ setInput(entry.text);
2153
+ return;
2154
+ }
2155
+ if (key.downArrow) {
2156
+ // Same history-walk ownership as ↑ above.
2157
+ if (fileOverlayOpen && historyIndex.current < 0) {
2158
+ setFileSelected(index => index >= fileMatches.length - 1 ? 0 : index + 1);
2159
+ return;
2160
+ }
2161
+ // Mirror of the tail-side ↑ walk: with a fold block the caret walks
2162
+ // the TAIL's lines; past its last line it falls through to the
2163
+ // overlay/history handling below.
2164
+ if (block && cursor >= block.end) {
2165
+ const tailCursor = cursor - block.end;
2166
+ const line = cursorLine(tail, tailCursor);
2167
+ const lines = tail.split('\n');
2168
+ if (line < lines.length - 1) {
2169
+ const nextLineStart = tail.indexOf('\n', tailCursor) + 1;
2170
+ const nextLineEnd = tail.indexOf('\n', nextLineStart);
2171
+ const nextLine = tail.slice(nextLineStart, nextLineEnd === -1 ? tail.length : nextLineEnd);
2172
+ setInput(value, block.end + nextLineStart + Math.min(cursorColumn(tail, tailCursor), nextLine.length));
2173
+ return;
2174
+ }
2175
+ }
2176
+ else if (block && cursor <= block.start) {
2177
+ // Head side: walk the HEAD's lines; its last line steps over the
2178
+ // block to the tail (never into history for a multi-row input).
2179
+ const line = cursorLine(head, cursor);
2180
+ const lines = head.split('\n');
2181
+ if (line < lines.length - 1) {
2182
+ const nextLineStart = head.indexOf('\n', cursor) + 1;
2183
+ const nextLineEnd = head.indexOf('\n', nextLineStart);
2184
+ const nextLine = head.slice(nextLineStart, nextLineEnd === -1 ? head.length : nextLineEnd);
2185
+ setInput(value, nextLineStart + Math.min(cursorColumn(head, cursor), nextLine.length));
2186
+ return;
2187
+ }
2188
+ setInput(value, block.end);
2189
+ return;
2190
+ }
2191
+ const line = cursorLine(value, cursor);
2192
+ const lines = value.split('\n');
2193
+ if (line < lines.length - 1) {
2194
+ const nextLineStart = value.indexOf('\n', cursor) + 1;
2195
+ const nextLineEnd = value.indexOf('\n', nextLineStart);
2196
+ const nextLine = value.slice(nextLineStart, nextLineEnd === -1 ? value.length : nextLineEnd);
2197
+ setInput(value, nextLineStart + Math.min(cursorColumn(value, cursor), nextLine.length));
2198
+ return;
2199
+ }
2200
+ if (overlayOpen && historyIndex.current < 0) {
2201
+ setSelectedCommand(index => index >= suggestions.length - 1 ? 0 : index + 1);
2202
+ return;
2203
+ }
2204
+ if (historyIndex.current < 0)
2205
+ return;
2206
+ if (historyIndex.current >= history.current.length - 1) {
2207
+ historyIndex.current = -1;
2208
+ updateFoldBlock(null);
2209
+ restoreDraftImages(historyDraft.current);
2210
+ setInput(historyDraft.current.text);
2211
+ }
2212
+ else {
2213
+ historyIndex.current += 1;
2214
+ const entry = history.current[historyIndex.current];
2215
+ if (entry !== undefined) {
2216
+ restoreDraftImages(entry);
2217
+ setInput(entry.text);
2218
+ }
2219
+ }
2220
+ return;
2221
+ }
2222
+ if (isMod(key) && key.leftArrow) {
2223
+ // Jump to the previous word boundary (readline alt+b). Must precede the
2224
+ // bare-arrow arms: Ctrl+Left arrives as leftArrow + ctrl. An active
2225
+ // selection collapses to its START edge first (editor semantics).
2226
+ const sel = selectionRef.current;
2227
+ setInput(value, sel ? sel.start : wordBoundaryLeft(value, cursor));
2228
+ return;
2229
+ }
2230
+ if (isMod(key) && key.rightArrow) {
2231
+ // Jump to the next word boundary (readline alt+f).
2232
+ const sel = selectionRef.current;
2233
+ setInput(value, sel ? sel.end : wordBoundaryRight(value, cursor));
2234
+ return;
2235
+ }
2236
+ if (key.leftArrow) {
2237
+ // ← on an EMPTY prompt backgrounds this session
2238
+ // and opens the agent view; with text it moves the caret as usual.
2239
+ // (The command/file overlays both imply non-empty text, so no extra
2240
+ // gate beyond the help menu is needed.)
2241
+ if (value.length === 0 && !helpOpen) {
2242
+ onBackgroundRequest?.();
2243
+ return;
2244
+ }
2245
+ // Grapheme-step: skip the whole cluster (surrogate pair, ZWJ emoji,
2246
+ // combining mark) so the caret never sits inside one. With a
2247
+ // selection, collapse to its start edge instead.
2248
+ const sel = selectionRef.current;
2249
+ setInput(value, sel ? sel.start : previousGraphemeBoundary(bounds, cursor));
2250
+ return;
2251
+ }
2252
+ if (key.rightArrow) {
2253
+ const sel = selectionRef.current;
2254
+ setInput(value, sel ? sel.end : nextGraphemeBoundary(bounds, cursor));
2255
+ return;
2256
+ }
2257
+ if (key.backspace) {
2258
+ if (cursor === 0)
2259
+ return;
2260
+ const start = previousGraphemeBoundary(bounds, cursor);
2261
+ deleteInputRange(start, cursor);
2262
+ return;
2263
+ }
2264
+ if (key.delete) {
2265
+ const end = nextGraphemeBoundary(bounds, cursor);
2266
+ if (end === cursor)
2267
+ return;
2268
+ deleteInputRange(cursor, end);
2269
+ return;
2270
+ }
2271
+ if (key.home) {
2272
+ // Start of the current line (the block is one atomic row).
2273
+ const lineStart = clampRowStart(value.lastIndexOf('\n', cursor - 1) + 1);
2274
+ setInput(value, lineStart);
2275
+ return;
2276
+ }
2277
+ if (key.end) {
2278
+ // End of the current line.
2279
+ const nextLine = value.indexOf('\n', cursor);
2280
+ setInput(value, nextLine === -1 ? value.length : clampRowEnd(nextLine));
2281
+ return;
2282
+ }
2283
+ if (isMod(key) && input === 'a') {
2284
+ const lineStart = clampRowStart(value.lastIndexOf('\n', cursor - 1) + 1);
2285
+ setInput(value, lineStart);
2286
+ return;
2287
+ }
2288
+ if (isMod(key) && input === 'e') {
2289
+ const nextLine = value.indexOf('\n', cursor);
2290
+ setInput(value, nextLine === -1 ? value.length : clampRowEnd(nextLine));
2291
+ return;
2292
+ }
2293
+ if (isMod(key) && input === 'u') {
2294
+ // Delete to start of line (never into the block).
2295
+ const lineStart = clampRowStart(value.lastIndexOf('\n', cursor - 1) + 1);
2296
+ deleteInputRange(lineStart, cursor);
2297
+ return;
2298
+ }
2299
+ if (isMod(key) && input === 'k') {
2300
+ // Delete to end of line (never into the block).
2301
+ const nextLine = value.indexOf('\n', cursor);
2302
+ const end = nextLine === -1 ? value.length : clampRowEnd(nextLine);
2303
+ deleteInputRange(cursor, end);
2304
+ return;
2305
+ }
2306
+ if (isMod(key) && input === 'w') {
2307
+ // Delete the word before the cursor: skip
2308
+ // trailing whitespace, then the whitespace-delimited word. The
2309
+ // deletion start never crosses into the block.
2310
+ const before = value.slice(0, cursor);
2311
+ let end = before.length;
2312
+ while (end > 0 && /\s/.test(before[end - 1]))
2313
+ end--;
2314
+ let start = end;
2315
+ while (start > 0 && !/\s/.test(before[start - 1]))
2316
+ start--;
2317
+ deleteInputRange(clampRowStart(start), cursor);
2318
+ return;
2319
+ }
2320
+ // ── vim mode (`/vim`) ──────────────────────────────────────────────
2321
+ // INSERT submode: only Esc is intercepted (back to NORMAL — the usual
2322
+ // clear/rewind Esc semantics stay disabled while vim is on).
2323
+ // NORMAL submode: bare characters and Esc are vim keys; help/command/
2324
+ // file overlays, modified combos, Tab, Enter, arrows and other
2325
+ // structured keys keep their existing handlers.
2326
+ const vimNormalEdit = (next, cursorOffset) => {
2327
+ updateFoldBlock(null);
2328
+ setInput(next, cursorOffset);
2329
+ setSelectedCommand(0);
2330
+ setFileSelected(0);
2331
+ };
2332
+ const vimPushUndo = () => {
2333
+ const images = imageRefsFor(valueRef.current);
2334
+ const evicted = vimUndoRef.current.length >= 100 ? vimUndoRef.current.shift() : undefined;
2335
+ vimUndoRef.current.push({ text: valueRef.current, cursor: cursorRef.current, images });
2336
+ if (evicted !== undefined)
2337
+ discardUnretainedImages(evicted.images.map(image => image.stageId));
2338
+ };
2339
+ const vimDeleteRange = (start, end) => {
2340
+ if (start >= end)
2341
+ return;
2342
+ vimPushUndo();
2343
+ updateFoldBlock(null);
2344
+ deleteInputRange(start, end);
2345
+ setSelectedCommand(0);
2346
+ setFileSelected(0);
2347
+ };
2348
+ const handleVimNormal = (input) => {
2349
+ // One stdin batch can merge several bare keys into a single event
2350
+ // (fast typing), so re-read the synchronous mirrors and recompute
2351
+ // the grapheme boundaries: every key in the batch operates on the
2352
+ // text/caret its predecessor produced (the outer `value`/`cursor`/
2353
+ // `bounds` reflect only the batch's first key).
2354
+ const value = valueRef.current;
2355
+ const cursor = cursorRef.current;
2356
+ const bounds = graphemeBoundaries(value);
2357
+ const pending = vimPendingRef.current;
2358
+ vimPendingRef.current = '';
2359
+ // Operator pending (`d`): the second key picks the target.
2360
+ if (pending === 'd') {
2361
+ switch (input) {
2362
+ case 'd': { // delete the whole line, newline included (vim `dd`);
2363
+ // the last line has no newline — its content is cleared
2364
+ const lineStart = vimLineStart(value, cursor);
2365
+ const lineEnd = vimLineEnd(value, cursor);
2366
+ const end = lineEnd < value.length ? lineEnd + 1 : lineEnd;
2367
+ vimDeleteRange(lineStart, end);
2368
+ return;
2369
+ }
2370
+ case '$': { // delete to end of line
2371
+ const end = vimLineEnd(value, cursor);
2372
+ vimDeleteRange(cursor, end);
2373
+ return;
2374
+ }
2375
+ case '0':
2376
+ case '^': { // delete to start of line
2377
+ const start = input === '^' ? vimLineFirstNonBlank(value, cursor) : vimLineStart(value, cursor);
2378
+ vimDeleteRange(start, cursor);
2379
+ return;
2380
+ }
2381
+ case 'w': { // delete to end of word
2382
+ const end = vimWordEnd(value, cursor);
2383
+ vimDeleteRange(cursor, end);
2384
+ return;
2385
+ }
2386
+ default:
2387
+ return; // unrecognized second key: cancel the operator, drop it
2388
+ }
2389
+ }
2390
+ switch (input) {
2391
+ case 'h':
2392
+ setInput(value, previousGraphemeBoundary(bounds, cursor));
2393
+ return;
2394
+ case 'l':
2395
+ setInput(value, nextGraphemeBoundary(bounds, cursor));
2396
+ return;
2397
+ case 'j': { // down one line (single-line input: no-op)
2398
+ const line = cursorLine(value, cursor);
2399
+ const lines = value.split('\n');
2400
+ if (line >= lines.length - 1)
2401
+ return;
2402
+ const col = Math.min(cursorColumn(value, cursor), (lines[line + 1] ?? '').length);
2403
+ setInput(value, vimLineEnd(value, cursor) + 1 + col);
2404
+ return;
2405
+ }
2406
+ case 'k': { // up one line
2407
+ const line = cursorLine(value, cursor);
2408
+ if (line <= 0)
2409
+ return;
2410
+ const lines = value.split('\n');
2411
+ const col = Math.min(cursorColumn(value, cursor), (lines[line - 1] ?? '').length);
2412
+ const prevStart = vimLineStart(value, vimLineStart(value, cursor) - 1);
2413
+ setInput(value, prevStart + col);
2414
+ return;
2415
+ }
2416
+ case '0': {
2417
+ setInput(value, vimLineStart(value, cursor));
2418
+ return;
2419
+ }
2420
+ case '^': {
2421
+ setInput(value, vimLineFirstNonBlank(value, cursor));
2422
+ return;
2423
+ }
2424
+ case '$': {
2425
+ setInput(value, vimLineEnd(value, cursor));
2426
+ return;
2427
+ }
2428
+ case 'w':
2429
+ setInput(value, vimWordForward(value, cursor));
2430
+ return;
2431
+ case 'b':
2432
+ setInput(value, vimWordBackward(value, cursor));
2433
+ return;
2434
+ case 'x': { // delete the character at the caret; at the very end of
2435
+ // the text delete the last character (vim: the caret sits ON the
2436
+ // last char after `$`, so `x` must still delete it). Same rule
2437
+ // when the caret sits right before a '\n' mid-draft — after `$`
2438
+ // the caret is on the line's last char, `x` must delete THAT
2439
+ // char, not the newline (which would join the lines).
2440
+ if (cursor > 0 && (cursor === value.length || value[cursor] === '\n')) {
2441
+ const start = previousGraphemeBoundary(bounds, cursor);
2442
+ vimDeleteRange(start, cursor);
2443
+ return;
2444
+ }
2445
+ const end = nextGraphemeBoundary(bounds, cursor);
2446
+ if (end === cursor)
2447
+ return;
2448
+ vimDeleteRange(cursor, end);
2449
+ return;
2450
+ }
2451
+ case 'X': { // delete the character before the caret
2452
+ if (cursor === 0)
2453
+ return;
2454
+ const start = previousGraphemeBoundary(bounds, cursor);
2455
+ vimDeleteRange(start, cursor);
2456
+ return;
2457
+ }
2458
+ case 'd':
2459
+ vimPendingRef.current = 'd';
2460
+ return;
2461
+ case 'u': { // undo the last vim edit
2462
+ syncImageGeneration();
2463
+ const prev = vimUndoRef.current.pop();
2464
+ if (prev === undefined)
2465
+ return;
2466
+ advanceDraftRevision();
2467
+ replaceDraftImages(prev.images);
2468
+ updateFoldBlock(null);
2469
+ setInput(prev.text, prev.cursor);
2470
+ setSelectedCommand(0);
2471
+ setFileSelected(0);
2472
+ return;
2473
+ }
2474
+ case 'i': // insert at the caret
2475
+ vimInsertRef.current = true;
2476
+ setVimInsert(true);
2477
+ return;
2478
+ case 'I': { // insert at the line's first non-blank (vim `I`)
2479
+ setInput(value, vimLineFirstNonBlank(value, cursor));
2480
+ vimInsertRef.current = true;
2481
+ setVimInsert(true);
2482
+ return;
2483
+ }
2484
+ case 'a': { // insert after the caret
2485
+ setInput(value, nextGraphemeBoundary(bounds, cursor));
2486
+ vimInsertRef.current = true;
2487
+ setVimInsert(true);
2488
+ return;
2489
+ }
2490
+ case 'A': { // insert at the line end
2491
+ setInput(value, vimLineEnd(value, cursor));
2492
+ vimInsertRef.current = true;
2493
+ setVimInsert(true);
2494
+ return;
2495
+ }
2496
+ case 'o': { // new line below, then insert
2497
+ vimPushUndo();
2498
+ const end = vimLineEnd(value, cursor);
2499
+ vimNormalEdit(value.slice(0, end) + '\n' + value.slice(end), end + 1);
2500
+ vimInsertRef.current = true;
2501
+ setVimInsert(true);
2502
+ return;
2503
+ }
2504
+ case 'O': { // new line above, then insert
2505
+ vimPushUndo();
2506
+ const start = vimLineStart(value, cursor);
2507
+ vimNormalEdit(value.slice(0, start) + '\n' + value.slice(start), start);
2508
+ vimInsertRef.current = true;
2509
+ setVimInsert(true);
2510
+ return;
2511
+ }
2512
+ default:
2513
+ return; // unrecognized key: ignored (never inserts in NORMAL)
2514
+ }
2515
+ };
2516
+ if (vimEnabledRef.current) {
2517
+ if (vimInsertRef.current) {
2518
+ // INSERT: Esc returns to NORMAL instead of the clear/rewind path.
2519
+ if (key.escape && !helpOpen && !overlayOpen && !fileOverlayOpen) {
2520
+ event.stopImmediatePropagation();
2521
+ vimInsertRef.current = false;
2522
+ setVimInsert(false);
2523
+ return;
2524
+ }
2525
+ }
2526
+ else if (!helpOpen && !overlayOpen && !fileOverlayOpen) {
2527
+ if (key.escape) {
2528
+ // NORMAL: Esc cancels a pending operator and otherwise no-ops
2529
+ // (the clear/rewind double-Esc semantics belong to non-vim mode).
2530
+ vimPendingRef.current = '';
2531
+ event.stopImmediatePropagation();
2532
+ return;
2533
+ }
2534
+ const plainChar = input.length > 0 &&
2535
+ !key.ctrl && !key.meta && !key.super && !key.tab && !key.return;
2536
+ if (plainChar) {
2537
+ // `?` on an empty input falls through to the help shortcut below.
2538
+ if (input === '?' && value.length === 0)
2539
+ return;
2540
+ // `/` opens the slash-command menu even in NORMAL: insert it and
2541
+ // switch to INSERT so the rest of the command types normally
2542
+ // (the menu then owns the keys while it is open).
2543
+ if (input === '/') {
2544
+ const text = valueRef.current;
2545
+ const pos = cursorRef.current;
2546
+ const next = text.slice(0, pos) + '/' + text.slice(pos);
2547
+ setInput(next, pos + 1);
2548
+ setSelectedCommand(0);
2549
+ setFileSelected(0);
2550
+ vimInsertRef.current = true;
2551
+ setVimInsert(true);
2552
+ return;
2553
+ }
2554
+ event.stopImmediatePropagation();
2555
+ // A merged multi-char event (fast typing) is one vim key per
2556
+ // character — handleVimNormal re-reads the refs each call, so a
2557
+ // batch like `dd` works exactly like two separate keypresses.
2558
+ // Once a key switches back to INSERT (i/a/o/…), the remaining
2559
+ // characters of the batch are ordinary typing and insert as text.
2560
+ for (let i = 0; i < input.length; i++) {
2561
+ if (vimInsertRef.current) {
2562
+ const rest = input.slice(i);
2563
+ const text = valueRef.current;
2564
+ const pos = cursorRef.current;
2565
+ const next = text.slice(0, pos) + rest + text.slice(pos);
2566
+ setInput(next, pos + rest.length);
2567
+ setSelectedCommand(0);
2568
+ setFileSelected(0);
2569
+ break;
2570
+ }
2571
+ handleVimNormal(input[i]);
2572
+ }
2573
+ return;
2574
+ }
2575
+ }
2576
+ }
2577
+ if (key.escape) {
2578
+ if (helpOpen) {
2579
+ onToggleHelp();
2580
+ return;
2581
+ }
2582
+ // A single Esc closes the open command menu first;
2583
+ // the double-tap-clear semantics only apply to ordinary input.
2584
+ if (overlayOpen) {
2585
+ syncImageGeneration();
2586
+ discardDraftImages();
2587
+ setInput('', 0);
2588
+ setSelectedCommand(0);
2589
+ setFileSelected(0);
2590
+ return;
2591
+ }
2592
+ // File overlay: Esc dismisses the menu for THIS token only — clearing
2593
+ // the input would nuke a mid-message `@` mention's surrounding text.
2594
+ if (fileOverlayOpen) {
2595
+ fileEscRef.current = mention?.start ?? -1;
2596
+ return;
2597
+ }
2598
+ // With pending messages while working, Esc = interrupt and deliver
2599
+ // them right away (Codex's "interrupt and send immediately"): the
2600
+ // turn is aborted and each message is re-queued once it settles.
2601
+ if (channel.working && channel.pending.length > 0) {
2602
+ const count = channel.interruptAndDeliver(channel.pending.map(item => ({
2603
+ text: item.text,
2604
+ images: item.images ?? [],
2605
+ })));
2606
+ channel.notify(t('interrupt-delivered', { n: count }), {
2607
+ timeoutMs: 2500,
2608
+ });
2609
+ return;
2610
+ }
2611
+ // A single Esc clears the current input (if any); the double-tap
2612
+ // path below handles rewind/clear on an already-empty input. A BIG
2613
+ // input folds into a block instead (Esc = the fold toggle; the
2614
+ // expand → fold → expand cycle is lossless, and clearing a big draft
2615
+ // stays reachable via the block-delete Backspace or Ctrl+C).
2616
+ if (value.length > 0) {
2617
+ if (isBigInput(value)) {
2618
+ updateFoldBlock({ start: 0, end: value.length });
2619
+ setSelectedCommand(0);
2620
+ setFileSelected(0);
2621
+ return;
2622
+ }
2623
+ syncImageGeneration();
2624
+ discardDraftImages();
2625
+ setInput('', 0);
2626
+ setSelectedCommand(0);
2627
+ setFileSelected(0);
2628
+ return;
2629
+ }
2630
+ // Double-tap Esc: clear the input when it has content; when empty,
2631
+ // open the rewind picker (double-tap Esc rewinds the selected message
2632
+ // and/or conversation to a previous point in time).
2633
+ if (escPendingRef.current) {
2634
+ escPendingRef.current = false;
2635
+ if (escTimerRef.current)
2636
+ clearTimeout(escTimerRef.current);
2637
+ if (value.length === 0) {
2638
+ onRewindRequest?.();
2639
+ }
2640
+ else {
2641
+ syncImageGeneration();
2642
+ discardDraftImages();
2643
+ setInput('', 0);
2644
+ }
2645
+ return;
2646
+ }
2647
+ escPendingRef.current = true;
2648
+ channel.notify(value.length === 0 ? t('esc-again-rewind') : t('esc-again-clear'));
2649
+ escTimerRef.current = setTimeout(() => {
2650
+ escPendingRef.current = false;
2651
+ }, 3000);
2652
+ return;
2653
+ }
2654
+ if (input === '?' && value.length === 0 && !expandedRef.current) {
2655
+ onToggleHelp();
2656
+ return;
2657
+ }
2658
+ if (input && !key.ctrl && !key.meta && !key.super && !key.tab && !key.escape) {
2659
+ // Typing anything else dismisses the help menu.
2660
+ if (helpOpen)
2661
+ onToggleHelp();
2662
+ // An active selection is REPLACED by the typed text, caret after it.
2663
+ const sel = selectionRef.current;
2664
+ const at = sel ? sel.start : cursor;
2665
+ const next = sel
2666
+ ? value.slice(0, sel.start) + input + value.slice(sel.end)
2667
+ : value.slice(0, cursor) + input + value.slice(cursor);
2668
+ setInput(next, at + input.length);
2669
+ setSelectedCommand(0);
2670
+ setFileSelected(0);
2671
+ }
2672
+ }, { isActive: !suspended });
2673
+ // === Render: hard-wrap every logical line at the input width, then show
2674
+ // the window of visual lines with the caret row always visible.
2675
+ // Narrow terminals: the usable width follows the real terminal down to a
2676
+ // single column — a fixed floor of 10 would wrap far too early and park
2677
+ // the declared cursor past the value box's actual width.
2678
+ // The vim badge ('INSERT '/'NORMAL ', 7 cols) sits BEFORE the value box in
2679
+ // the same row, so the wrap budget must shrink by its width or long lines
2680
+ // would be clipped at the value box's right edge.
2681
+ const vimBadgeCols = vimEnabled ? 7 : 0;
2682
+ // 行首会话入口占列:未传 onOpenSessions 时按钮整体不渲染,预算同步归还
2683
+ // (既有调用方的可用列数逐列不变)。用实测常量而不是 stringWidth:该字符
2684
+ // 是 U+1F3E0+VS15,stringWidth 按码点算 2(含 VS15 仍是 2),终端只给 1,
2685
+ // 见 HOME_BUTTON_COLS 的说明。
2686
+ const homeButtonCols = onOpenSessions === undefined ? 0 : HOME_BUTTON_COLS;
2687
+ // 补全卡片边框与输入框 idle 边框同色(plan 模式下整套面板一起变 sage
2688
+ // 绿)。`/color` 会话强调色优先于主题 promptBorder(plan 模式仍整体走
2689
+ // sage 绿)。`?? ''` 防御最小 mock channel(只声明用到的字段的回归脚
2690
+ // 本)。声明在渲染派生区之前:展开编辑器的行号高亮与边框同用此色。
2691
+ const sessionAccent = sessionColorHex(channel.sessionColor ?? '');
2692
+ const promptAccent = channel.mode.plan === true ? 'planMode' : (sessionAccent ?? 'promptBorder');
2693
+ // 展开态布局参数:编辑器独占整屏 —— 行号槽(宽度随逻辑行数伸缩)+
2694
+ // 圆角边框 2 + 两侧 padding 各 1 占列,⌸ 入口 / ❯ 前缀 / vim 徽标 /
2695
+ // ⛶ 按钮全部让位;收起态额外扣掉行首 ⌸ 入口(未渲染时 0 列)与行尾
2696
+ // ⛶ 按钮的 2 列。
2697
+ const editorLogicalLines = expanded ? value.split('\n').length : 1;
2698
+ const editorNoWidth = Math.max(2, String(editorLogicalLines).length);
2699
+ const editorGutterCols = editorNoWidth + 3;
2700
+ const inputWidth = expanded
2701
+ ? Math.max(1, columns - 4 - editorGutterCols)
2702
+ : Math.max(1, columns - 3 - vimBadgeCols - homeButtonCols - (expandEnabled ? 2 : 0));
2703
+ // 展开态无视折叠块:全屏编辑就是为了看全文(foldBlock 状态保留,
2704
+ // 收起后折叠显示恢复)。
2705
+ const block = expanded ? null : foldBlock;
2706
+ // Fold-block model: the value renders as [head rows][chip row][tail rows]
2707
+ // — the block is ONE atomic visual row regardless of its text size; text
2708
+ // before/after it stays fully editable and never unfolds it.
2709
+ const foldText = block ? value.slice(block.start, block.end) : value;
2710
+ const head = block ? value.slice(0, block.start) : '';
2711
+ const tail = block ? value.slice(block.end) : '';
2712
+ const headRows = block ? wrapToWidth(head, inputWidth) : [];
2713
+ const tailRows = block ? wrapToWidth(tail, inputWidth) : [];
2714
+ const chipRow = block ? headRows.length : -1;
2715
+ const visualLines = block
2716
+ ? [...headRows, '', ...tailRows]
2717
+ : wrapToWidth(value, inputWidth);
2718
+ // Caret geometry uses the FULL wrap (not `value.slice(0, cursor)`):
2719
+ // word-wrap carry moves already-placed clusters, so a prefix wrap would
2720
+ // disagree with the displayed rows whenever the cursor sits inside a
2721
+ // carried word.
2722
+ const caretPlaced = block
2723
+ ? cursor <= block.start
2724
+ ? caretInText(head, inputWidth, cursor)
2725
+ : caretInText(tail, inputWidth, Math.max(0, cursor - block.end))
2726
+ : caretInText(value, inputWidth, cursor);
2727
+ const caretVisualLine = block && cursor > block.start
2728
+ ? headRows.length + 1 + caretPlaced.line
2729
+ : caretPlaced.line;
2730
+ const caretCharCol = caretPlaced.charCol;
2731
+ const caretVisualCol = caretPlaced.visualCol;
2732
+ // Fold stats describe the BLOCK (or the whole input when expanded and
2733
+ // the ▾ prefix offers a manual whole-input fold). The chip shows the
2734
+ // block's own line/char count + first-line preview — the preview text
2735
+ // around it is unaffected.
2736
+ const big = isBigInput(foldText);
2737
+ const stats = big
2738
+ ? t('input-fold-stats', { lines: foldText.split('\n').length, chars: foldText.length })
2739
+ : '';
2740
+ const peekOpen = block !== null && hovered && !selectionActive;
2741
+ // 展开态的编辑区行高预算:圆角边框 2 + 标题行 1 + 状态行 1 + 按钮行 1。
2742
+ const editorMaxRows = Math.max(1, terminalRows - EDITOR_CHROME_ROWS);
2743
+ if (expanded && caretVisualLine !== prevCaretLineRef.current) {
2744
+ // A real caret move re-engages following after wheel browsing.
2745
+ editorFreeScrollRef.current = false;
2746
+ prevCaretLineRef.current = caretVisualLine;
2747
+ }
2748
+ let windowStart;
2749
+ let visibleCount;
2750
+ if (expanded) {
2751
+ // 滚轮推动的窗口与 caret 跟随合并:自由滚动(滚轮浏览)期间不强制
2752
+ // caret 可见;caret 移动后恢复跟随。写回 ref,滚轮分支读到的就是
2753
+ // 合并后的基线。
2754
+ let win = expandedScrollRef.current;
2755
+ if (!editorFreeScrollRef.current) {
2756
+ if (caretVisualLine < win)
2757
+ win = caretVisualLine;
2758
+ if (caretVisualLine >= win + editorMaxRows)
2759
+ win = caretVisualLine - editorMaxRows + 1;
2760
+ }
2761
+ win = Math.max(0, Math.min(win, Math.max(0, visualLines.length - editorMaxRows)));
2762
+ expandedScrollRef.current = win;
2763
+ windowStart = win;
2764
+ visibleCount = editorMaxRows;
2765
+ }
2766
+ else {
2767
+ windowStart = Math.max(0, Math.min(caretVisualLine - MAX_VISIBLE_LINES + 1, visualLines.length - MAX_VISIBLE_LINES));
2768
+ visibleCount = MAX_VISIBLE_LINES;
2769
+ }
2770
+ const visibleLines = visualLines.slice(windowStart, windowStart + visibleCount);
2771
+ // Caret-window jump: when the caret leaves MAX_VISIBLE_LINES (typing past
2772
+ // it, arrow-key walks through a long prompt) the whole visible band is
2773
+ // replaced in place — same-height rows, completely different text. The
2774
+ // per-cell diff that repaints that band is exactly the path that goes
2775
+ // haywire when the inline viewport is even one row out of sync with the
2776
+ // terminal's scrollback ("重叠变花": old rows bleeding through the new
2777
+ // ones). Same one-shot reanchor family as the shrink/floaters/editor
2778
+ // patches above — the window jump is a viewport-level discontinuity, not
2779
+ // an ordinary content edit.
2780
+ const prevWindowStartRef = React.useRef(windowStart);
2781
+ React.useLayoutEffect(() => {
2782
+ if (windowStart !== prevWindowStartRef.current) {
2783
+ prevWindowStartRef.current = windowStart;
2784
+ const ink = instances.get(process.stdout) ?? instances.values().next().value;
2785
+ ink?.invalidatePrevFrame();
2786
+ ink?.reanchorViewport();
2787
+ }
2788
+ }, [windowStart]);
2789
+ // useInput 的滚轮分支需要这份几何(它在这些派生之前注册)。
2790
+ if (expanded) {
2791
+ editorViewportRef.current = { maxRows: editorMaxRows, total: visualLines.length };
2792
+ }
2793
+ // Folded chip content: block stats + first-line preview + hover hint,
2794
+ // all pre-truncated to the input width (the row is one line, always).
2795
+ // `·` separators are U+30FB KATAKANA MIDDLE DOT, NOT U+00B7: the latter
2796
+ // is East-Asian-ambiguous (model 1 cell, CJK terminal fonts paint 2) and
2797
+ // this row's stats→preview→hint truncation arithmetic all runs through
2798
+ // stringWidth — a painted-wide separator shifts every segment right by
2799
+ // one column per separator and the row reads as overlapping text.
2800
+ // U+30FB is officially Ambiguous too, but get-east-asian-width hardcodes
2801
+ // it Wide and mainstream terminals (Western included) paint it 2 cells —
2802
+ // the model and the painted width agree in practice. A wcwidth-strict
2803
+ // Western terminal painting it 1 cell would leave a spare column, which
2804
+ // the `- 6` slack below absorbs.
2805
+ const foldBadge = `▸ ${stats}`;
2806
+ const foldHint = t('input-fold-hover');
2807
+ const foldPreviewWidth = inputWidth - stringWidth(foldBadge) - stringWidth(`・${foldHint}`) - 6;
2808
+ const foldPreview = foldPreviewWidth >= 8
2809
+ ? truncateToWidth(foldText.split('\n')[0] ?? '', foldPreviewWidth)
2810
+ : '';
2811
+ // Expanded-state fold affordance: a `▾` prefix at the start of the FIRST
2812
+ // row (only while the window is at the top and no block exists); its
2813
+ // cells fold the whole input into a block again on click.
2814
+ const prefixLabel = `▾ ${stats}・`;
2815
+ const prefixCols = !block && !expanded && big && windowStart === 0 ? stringWidth(prefixLabel) : 0;
2816
+ // Offset range [start, end) of every visual row — the SAME break rule as
2817
+ // wrapToWidth — so the selection highlight can intersect each row. With a
2818
+ // fold block, the chip row maps to the block's own span (never selected:
2819
+ // updateSelection clamps the selection into the head or the tail side).
2820
+ const lineRanges = block
2821
+ ? [
2822
+ ...visualLineRanges(head, inputWidth),
2823
+ [block.start, block.end],
2824
+ ...visualLineRanges(tail, inputWidth).map(([s, e]) => [s + block.end, e + block.end]),
2825
+ ]
2826
+ : visualLineRanges(value, inputWidth);
2827
+ /**
2828
+ * Inverse runs for one rendered row, shared by the inline prompt and the
2829
+ * expanded editor: the selection's intersection (if any) and the caret
2830
+ * cluster on the caret's row. Both render <Text inverse>; overlapping
2831
+ * intervals merge so a caret inside the selection stays one continuous
2832
+ * highlight. The caret row inverts the WHOLE cluster at the caret column
2833
+ * (solid block) — [col, next boundary) covers a surrogate pair or ZWJ
2834
+ * emoji as one glyph; at the text end it shows a blank inverse cell like
2835
+ * the empty-input caret (appended after everything, so a selection
2836
+ * ending there cannot swallow it).
2837
+ */
2838
+ const rowHighlightPieces = (text, absoluteLine) => {
2839
+ const [rowStart] = lineRanges[absoluteLine] ?? [0, 0];
2840
+ // Per-character style: 0 plain, 1 chip (a staged token), 2 inverse
2841
+ // (selection or caret cluster). Inverse wins over chip.
2842
+ const PLAIN = 0;
2843
+ const CHIP = 1;
2844
+ const INVERSE = 2;
2845
+ const kinds = new Uint8Array(text.length);
2846
+ const fill = (lo, hi, kind) => {
2847
+ for (let i = Math.max(lo, 0); i < Math.min(hi, text.length); i++)
2848
+ kinds[i] = kind;
2849
+ };
2850
+ const spans = boundImageSpans(value);
2851
+ for (const span of spans)
2852
+ fill(span.start - rowStart, span.end - rowStart, CHIP);
2853
+ const sel = selection;
2854
+ if (sel)
2855
+ fill(sel.start - rowStart, sel.end - rowStart, INVERSE);
2856
+ let endBlankCaret = false;
2857
+ if (absoluteLine === caretVisualLine) {
2858
+ const col = Math.min(caretCharCol, text.length);
2859
+ // A staged token is one caret cluster: with the caret at its start the
2860
+ // whole token inverts (the selected-chip look), and Delete removes it.
2861
+ const tokenAtCaret = spans.find(span => span.start === rowStart + col);
2862
+ const clusterEnd = tokenAtCaret !== undefined
2863
+ ? Math.min(tokenAtCaret.end - rowStart, text.length)
2864
+ : nextGraphemeBoundary(graphemeBoundaries(text), col);
2865
+ if (clusterEnd > col)
2866
+ fill(col, clusterEnd, INVERSE);
2867
+ else
2868
+ endBlankCaret = col === text.length;
2869
+ }
2870
+ const pieces = [];
2871
+ let pos = 0;
2872
+ while (pos < text.length) {
2873
+ const kind = kinds[pos];
2874
+ let end = pos + 1;
2875
+ while (end < text.length && kinds[end] === kind)
2876
+ end++;
2877
+ pieces.push({ text: text.slice(pos, end), inverse: kind === INVERSE, chip: kind === CHIP });
2878
+ pos = end;
2879
+ }
2880
+ if (endBlankCaret)
2881
+ pieces.push({ text: ' ', inverse: true, chip: false });
2882
+ return pieces;
2883
+ };
2884
+ const rendered = visibleLines.map((line, index) => {
2885
+ const absoluteLine = windowStart + index;
2886
+ if (block && absoluteLine === chipRow) {
2887
+ // The fold block's atomic chip row: click expands it; hover pops the
2888
+ // peek card. The row is one line no matter how big the block is.
2889
+ return (_jsxs(Box, { flexDirection: "row", onClick: (event) => {
2890
+ event.stopImmediatePropagation();
2891
+ updateFoldBlock(null);
2892
+ }, onMouseEnter: hoverEnter, onMouseLeave: hoverLeave, children: [_jsx(Text, { dimColor: true, children: foldBadge }), foldPreview !== '' && _jsx(Text, { dimColor: true, children: "\u30FB" }), foldPreview !== '' && _jsx(Text, { wrap: "truncate-end", children: foldPreview }), _jsx(Text, { dimColor: true, children: `・${foldHint}` })] }, `fold-${absoluteLine}`));
2893
+ }
2894
+ const withPrefix = absoluteLine === 0 && prefixCols > 0;
2895
+ const text = withPrefix ? truncateToWidth(line, inputWidth - prefixCols) : line;
2896
+ const prefix = withPrefix ? _jsx(Text, { dimColor: true, children: prefixLabel }) : null;
2897
+ const pieces = rowHighlightPieces(text, absoluteLine);
2898
+ return (_jsxs(Text, { wrap: "truncate-end", children: [prefix, pieces.length === 0 ? ' ' : pieces.map((piece, pieceIndex) => piece.inverse ? (_jsx(Text, { inverse: true, children: piece.text }, pieceIndex)) : piece.chip ? (_jsx(Text, { color: "suggestion", children: piece.text }, pieceIndex)) : (piece.text))] }, absoluteLine));
2899
+ });
2900
+ // ── 展开态编辑行 ────────────────────────────────────────────────────
2901
+ // Logical line number per visual row (a wrapped continuation keeps its
2902
+ // line's number): the row's range end sitting on a '\n' starts a new
2903
+ // logical line from the NEXT row.
2904
+ const editorRowLogical = [];
2905
+ if (expanded) {
2906
+ let count = 0;
2907
+ for (let i = 0; i < lineRanges.length; i++) {
2908
+ editorRowLogical.push(count);
2909
+ const rangeEnd = lineRanges[i][1];
2910
+ if (value[rangeEnd] === '\n')
2911
+ count++;
2912
+ }
2913
+ }
2914
+ const editorRows = expanded
2915
+ ? visibleLines.map((line, index) => {
2916
+ const absoluteLine = windowStart + index;
2917
+ const isCaretRow = absoluteLine === caretVisualLine;
2918
+ const logicalNo = editorRowLogical[absoluteLine];
2919
+ const gutterLabel = logicalNo === undefined
2920
+ ? ' '.repeat(editorNoWidth)
2921
+ : String(logicalNo + 1).padStart(editorNoWidth, ' ');
2922
+ const pieces = rowHighlightPieces(line, absoluteLine);
2923
+ return (_jsxs(Text, { wrap: "truncate-end", backgroundColor: isCaretRow ? 'toolCardBackgroundDim' : undefined, children: [_jsx(Text, { dimColor: !isCaretRow, bold: isCaretRow, color: isCaretRow ? promptAccent : undefined, children: `${gutterLabel} │ ` }), pieces.map((piece, pieceIndex) => piece.inverse ? (_jsx(Text, { inverse: true, children: piece.text }, pieceIndex)) : piece.chip ? (_jsx(Text, { color: "suggestion", children: piece.text }, pieceIndex)) : (piece.text))] }, absoluteLine));
2924
+ })
2925
+ : null;
2926
+ // Peek card content: the BLOCK's text wrapped to the card's inner width,
2927
+ // capped at PEEK_MAX_ROWS visual rows (a preview — click to expand and
2928
+ // edit the real input). The footer reports the clipped remainder.
2929
+ const PEEK_MAX_ROWS = 10;
2930
+ const peekVisualLines = [];
2931
+ for (const line of foldText.split('\n')) {
2932
+ for (const row of wrapToWidth(line, cardContentWidth(columns))) {
2933
+ if (peekVisualLines.length >= PEEK_MAX_ROWS)
2934
+ break;
2935
+ peekVisualLines.push(row);
2936
+ }
2937
+ if (peekVisualLines.length >= PEEK_MAX_ROWS)
2938
+ break;
2939
+ }
2940
+ const peekClipped = peekVisualLines.length >= PEEK_MAX_ROWS;
2941
+ // Composer height shrink: clearing multi-line text (Enter/Esc/Ctrl+C/
2942
+ // Backspace) collapses the input area within one commit, shifting the
2943
+ // status line up and the whole chrome with it. The renderer's
2944
+ // full-damage pass (didLayoutShift) repaints the shifted siblings, but
2945
+ // inline mode's virtual↔scrollback correspondence needs the stronger
2946
+ // in-place viewport repaint — same treatment as Ctrl+O and the
2947
+ // loaded-context toggle (see Chat.tsx). One-shot, only on SHRINK:
2948
+ // growth scrolls the terminal naturally and needs no recovery.
2949
+ const contentRows = value.length === 0 ? 1 : visibleLines.length;
2950
+ noteAuxNumber('promptContentRows', contentRows);
2951
+ const prevContentRowsRef = React.useRef(contentRows);
2952
+ React.useLayoutEffect(() => {
2953
+ if (contentRows < prevContentRowsRef.current) {
2954
+ const ink = instances.get(process.stdout) ?? instances.values().next().value;
2955
+ ink?.invalidatePrevFrame();
2956
+ ink?.reanchorViewport();
2957
+ }
2958
+ prevContentRowsRef.current = contentRows;
2959
+ }, [contentRows]);
2960
+ const lastNotification = channel.notifications[channel.notifications.length - 1];
2961
+ // Park the native terminal cursor at the input caret (via the renderer's
2962
+ // cursor-declaration mechanism). Terminal emulators render IME preedit
2963
+ // text and screen-reader focus at the physical cursor, so parking it at
2964
+ // the caret makes CJK/IME composition appear inline at the input instead
2965
+ // of at the screen's bottom row; in line-mode terminals the console echo
2966
+ // of typed characters lands at the same spot. `line`/`column` are
2967
+ // relative to the value box the ref attaches to.
2968
+ const valueBoxRef = useDeclaredCursor({
2969
+ line: caretVisualLine - windowStart,
2970
+ // Clamp the declared column to the wrap width: a grapheme wider than
2971
+ // the last remaining column (emoji at width 1) can push the visual
2972
+ // column past inputWidth, and the park must stay inside the value box.
2973
+ // In the expanded editor the declared box starts at its outer edge
2974
+ // (padding + gutter included), so those columns ride along and the
2975
+ // clamp grows with them.
2976
+ //
2977
+ // The declared column is relative to the VALUE BOX, and `caretVisualCol`
2978
+ // is already measured in that box's cell space: the text box IS the text
2979
+ // run, so nothing that renders before it — the session entry, the `❯ `
2980
+ // glyph, the fold prefix — shifts a cell inside it. Adding any of those
2981
+ // back double-counts them and parks the hardware cursor to the RIGHT of
2982
+ // the inverted caret cell (a 2-column miss shows up as a displaced IME
2983
+ // preedit target). Only the expanded editor declares against a wider box
2984
+ // (gutter + padding), so only that branch adds columns.
2985
+ column: Math.min(caretVisualCol + (expanded ? editorGutterCols + 1 : 0), expanded ? editorGutterCols + 1 + inputWidth : inputWidth),
2986
+ active: !suspended && !selectionActive,
2987
+ });
2988
+ /**
2989
+ * Map a pointer position relative to the value box to a UTF-16 offset
2990
+ * via the same grapheme walk the renderer wraps with — exact under CJK
2991
+ * widths, wrapped rows and multi-codepoint clusters. Rows are clamped to
2992
+ * the VISIBLE window (drag moves never auto-scroll past it in v1); the
2993
+ * fold chip row maps to null (its cells belong to the expand affordance,
2994
+ * not to text).
2995
+ */
2996
+ const localToOffset = (localCol, localRow) => {
2997
+ const lastVisible = Math.min(visualLines.length - 1, windowStart + visibleCount - 1);
2998
+ const clamped = Math.max(windowStart, Math.min(windowStart + localRow, lastVisible));
2999
+ // Fold prefix (▾) row: the rendered first row is truncated by prefixCols,
3000
+ // so both the column and the wrap budget shift — without the correction
3001
+ // a drag starting on the first row lands prefixCols to the right of the
3002
+ // pointer (consistent with handleValueClick's click mapping). Presses ON the
3003
+ // prefix cells clamp to the row start (drag-from-0, like selecting the
3004
+ // whole first row backwards).
3005
+ const isPrefixRow = !block && clamped === 0 && prefixCols > 0;
3006
+ const col = isPrefixRow ? Math.max(0, localCol - prefixCols) : localCol;
3007
+ const width = isPrefixRow ? inputWidth - prefixCols : inputWidth;
3008
+ if (block) {
3009
+ if (clamped === chipRow)
3010
+ return null;
3011
+ return clamped < chipRow
3012
+ ? clickToCursorOffset(head, width, clamped, col)
3013
+ : block.end + clickToCursorOffset(tail, width, clamped - chipRow - 1, col);
3014
+ }
3015
+ return clickToCursorOffset(value, width, clamped, col);
3016
+ };
3017
+ /**
3018
+ * Click-to-position the caret: map a click inside the value box (local
3019
+ * row/column relative to the box) to a UTF-16 cursor offset via the same
3020
+ * grapheme walk the renderer wraps with — exact under CJK widths, wrapped
3021
+ * rows and multi-codepoint clusters. Clicks land on the boundary nearest
3022
+ * the clicked cell (mid-grapheme snaps to its start). With a fold block,
3023
+ * clicks map into the head/tail text (the chip row has its own expand
3024
+ * onClick); without one, the fold prefix's cells fold the whole input.
3025
+ *
3026
+ * The drag protocol resets ink's multi-click chain on every press inside
3027
+ * the value box (it carries onDragStart), so double-click word selection
3028
+ * is self-detected here: two clicks within DOUBLE_CLICK_MS and one cell.
3029
+ * Shift+click extends the selection from its start edge (or the caret)
3030
+ * to the clicked offset; a plain click clears the selection and moves
3031
+ * the caret.
3032
+ *
3033
+ * `colOffset` shifts the local column origin: the expanded editor's
3034
+ * value box starts at the line-number gutter, so its callers subtract
3035
+ * the gutter width (0 for the inline prompt).
3036
+ */
3037
+ /** A plain click on a `[Image #N]` token: a staged one is reported as the
3038
+ * caret image (the caret was just placed at its start, so the caller
3039
+ * shows the preview even if it was dismissed); a stale one warns.
3040
+ * Offsets come from the input's own click-to-cursor mapping, never from
3041
+ * screen coordinates. */
3042
+ const openStagedImageAt = (offset) => {
3043
+ syncImageGeneration();
3044
+ for (const match of valueRef.current.matchAll(COMPOSER_IMAGE_TOKEN)) {
3045
+ const start = match.index ?? 0;
3046
+ if (start > offset)
3047
+ break;
3048
+ if (offset < start + match[0].length) {
3049
+ const stageId = draftImagesRef.current.get(match[0]);
3050
+ const image = stageId === undefined ? undefined : channel.stagedImage(stageId);
3051
+ if (image === undefined) {
3052
+ // Evicted by the FIFO cap or cleared by a session switch: the
3053
+ // placeholder text will NOT attach an image on submit. A raw
3054
+ // token (never staged) is plain text and gets no notice.
3055
+ if (stageId !== undefined) {
3056
+ channel.notify(t('input-image-token-stale', { token: match[0] }), { color: 'warning', timeoutMs: 5000 });
3057
+ }
3058
+ }
3059
+ else {
3060
+ reportCaretImage('click');
3061
+ }
3062
+ return;
3063
+ }
3064
+ }
3065
+ };
3066
+ const handleValueClick = (e, colOffset = 0) => {
3067
+ const now = Date.now();
3068
+ const modified = e.shift || e.alt || e.ctrl;
3069
+ const isDouble = !modified &&
3070
+ now - lastClickAtRef.current < DOUBLE_CLICK_MS &&
3071
+ Math.abs(e.col - lastClickColRef.current) <= 1 &&
3072
+ Math.abs(e.row - lastClickRowRef.current) <= 1;
3073
+ if (modified) {
3074
+ // Shift+click is range extension, never a word-select click. It also
3075
+ // breaks the local chain so a following plain click cannot complete a
3076
+ // double-click that started under a modifier.
3077
+ lastClickAtRef.current = 0;
3078
+ lastClickColRef.current = -1;
3079
+ lastClickRowRef.current = -1;
3080
+ }
3081
+ else {
3082
+ lastClickAtRef.current = now;
3083
+ lastClickColRef.current = e.col;
3084
+ lastClickRowRef.current = e.row;
3085
+ }
3086
+ const localCol = e.localCol - colOffset;
3087
+ const clickedVisual = windowStart + e.localRow;
3088
+ const clamped = Math.max(0, Math.min(clickedVisual, visualLines.length - 1));
3089
+ if (block) {
3090
+ if (clamped === chipRow)
3091
+ return;
3092
+ const offset = clamped < chipRow
3093
+ ? clickToCursorOffset(head, inputWidth, clamped, localCol, isDouble ? 'grapheme-start' : 'nearest')
3094
+ : block.end + clickToCursorOffset(tail, inputWidth, clamped - chipRow - 1, localCol, isDouble ? 'grapheme-start' : 'nearest');
3095
+ if (isDouble) {
3096
+ // Word select stays inside the clicked side: the block is atomic.
3097
+ const side = offset <= block.start;
3098
+ const w = wordSelectionAt(value, offset, side ? 0 : block.end, side ? block.start : value.length);
3099
+ if (w) {
3100
+ updateSelection(w.start, w.end);
3101
+ placeCaret(selectionRef.current?.end ?? w.end, 'end');
3102
+ }
3103
+ return;
3104
+ }
3105
+ if (e.shift) {
3106
+ const base = selectionRef.current ? selectionRef.current.start : cursorRef.current;
3107
+ updateSelection(base, offset);
3108
+ placeCaret(offset, 'nearest');
3109
+ return;
3110
+ }
3111
+ clearSelection();
3112
+ // A click on a staged token puts the caret at its start: the token is
3113
+ // the caret cluster, so it highlights whole.
3114
+ placeCaret(offset, 'start');
3115
+ openStagedImageAt(offset);
3116
+ return;
3117
+ }
3118
+ if (clamped === 0 && prefixCols > 0 && localCol < prefixCols) {
3119
+ // Folding hides the entire editable projection, so no selection may
3120
+ // survive invisibly inside the chip and keep owning Ctrl+C/Delete.
3121
+ clearSelection();
3122
+ dragAnchorRef.current = null;
3123
+ setCursor(value.length);
3124
+ updateFoldBlock({ start: 0, end: value.length });
3125
+ return;
3126
+ }
3127
+ const col = clamped === 0 && prefixCols > 0 ? Math.max(0, localCol - prefixCols) : localCol;
3128
+ const offset = clickToCursorOffset(value, clamped === 0 && prefixCols > 0 ? inputWidth - prefixCols : inputWidth, clamped, col, isDouble ? 'grapheme-start' : 'nearest');
3129
+ if (isDouble) {
3130
+ const w = wordSelectionAt(value, offset, 0, value.length);
3131
+ if (w) {
3132
+ updateSelection(w.start, w.end);
3133
+ placeCaret(selectionRef.current?.end ?? w.end, 'end');
3134
+ }
3135
+ return;
3136
+ }
3137
+ if (e.shift) {
3138
+ const base = selectionRef.current ? selectionRef.current.start : cursorRef.current;
3139
+ updateSelection(base, offset);
3140
+ placeCaret(offset, 'nearest');
3141
+ return;
3142
+ }
3143
+ clearSelection();
3144
+ placeCaret(offset, 'start');
3145
+ openStagedImageAt(offset);
3146
+ };
3147
+ /**
3148
+ * Drag selection (component-level drag protocol): the press origin is
3149
+ * derived from the event's start/current delta (dragstart fires on the
3150
+ * FIRST motion), the focus follows every dragmove. The caret rides the
3151
+ * focus edge; updateSelection clamps both ends into one fold side, so a
3152
+ * drag can never cross the chip row. `colOffset` as in handleValueClick.
3153
+ */
3154
+ const handleDragStart = (e, colOffset = 0) => {
3155
+ const anchorLocalCol = e.localCol - (e.col - e.startCol) - colOffset;
3156
+ const anchorLocalRow = e.localRow - (e.row - e.startRow);
3157
+ const anchor = localToOffset(anchorLocalCol, anchorLocalRow);
3158
+ if (anchor === null) {
3159
+ dragAnchorRef.current = null;
3160
+ return;
3161
+ }
3162
+ dragAnchorRef.current = anchor;
3163
+ placeCaret(anchor, 'nearest');
3164
+ };
3165
+ const handleDragMove = (e, colOffset = 0) => {
3166
+ const anchor = dragAnchorRef.current;
3167
+ if (anchor === null)
3168
+ return;
3169
+ const focus = localToOffset(e.localCol - colOffset, e.localRow);
3170
+ if (focus === null)
3171
+ return;
3172
+ // The caret rides the focus edge, clamped into the anchor's fold side
3173
+ // exactly like updateSelection clamps the range — the caret must never
3174
+ // jump across the chip row while the selection stays behind.
3175
+ let caret = focus;
3176
+ const block = foldBlockRef.current;
3177
+ if (block) {
3178
+ caret = anchor <= block.start ? Math.min(focus, block.start) : Math.max(focus, block.end);
3179
+ }
3180
+ updateSelection(anchor, focus);
3181
+ placeCaret(normalizeCursorOffset(valueRef.current, caret), 'nearest');
3182
+ };
3183
+ const handleDragEnd = () => {
3184
+ dragAnchorRef.current = null;
3185
+ };
3186
+ // 浮层整体挂载条件:与内部面板可见条件精确同值。关闭时必须把整个
3187
+ // absolute 浮层移除——渲染器的 absolute-removed 检测只看被移除节点自身
3188
+ // 的 style.position,常驻浮层 + 移除普通子节点不会触发 blit 解毒,被
3189
+ // 覆盖的转录行会留空(见 Chat.tsx dialogOverlayOpen 注释)。展开态由
3190
+ // 全屏编辑器接管,内联浮层全部撤下。
3191
+ const floatersOpen = !suspended &&
3192
+ !expanded &&
3193
+ (helpOpen || channel.pending.length > 0 || fileOverlayOpen || overlayOpen || peekOpen);
3194
+ // 顶边框右侧的会话名标签 chip:色随强调色;超宽截断,宽度
3195
+ // 随终端列数伸缩但不超过 28 显示单元。默认关闭——`/settings` 的
3196
+ // 「会话名标签」开关(dsh-tui.promptSessionLabel)开启后显示。
3197
+ const sessionTitle = channel.sessionTitle ?? '';
3198
+ const topRightLabel = channel.promptSessionLabel === true && sessionTitle !== ''
3199
+ ? {
3200
+ text: truncateToWidth(sessionTitle, Math.max(8, Math.min(28, columns - 8))),
3201
+ color: channel.mode.plan === true ? 'planMode' : (sessionAccent ?? 'accent'),
3202
+ ink: 'inverseText',
3203
+ }
3204
+ : undefined;
3205
+ // 浮层最佳路径(/ 命令卡、@ 文件卡、帮助/队列)经渲染器 absolute-overlay
3206
+ // 机制覆盖转录尾部与状态行。若覆盖期间上方兄弟重绘(spinner 滴答、流式
3207
+ // 文本),覆盖单元格会混入 prevScreen 的旧转录内容——"重叠变花"的根因
3208
+ // (渲染器注释描述的同族问题)。Chat.tsx 对其浮层/高度切换都做视口重锚
3209
+ // (Ctrl+O、loaded-context);此处为斜杠/文件浮层的开关补上同样的恢复:
3210
+ // 打开时保证卡片整块重绘、关闭时保证被覆盖行回到干净的转录内容,而非与
3211
+ // scrollback 失同步后残留花屏。
3212
+ const prevFloatersOpenRef = React.useRef(floatersOpen);
3213
+ React.useLayoutEffect(() => {
3214
+ if (floatersOpen === prevFloatersOpenRef.current)
3215
+ return;
3216
+ prevFloatersOpenRef.current = floatersOpen;
3217
+ const ink = instances.get(process.stdout) ?? instances.values().next().value;
3218
+ ink?.invalidatePrevFrame();
3219
+ ink?.reanchorViewport();
3220
+ }, [floatersOpen]);
3221
+ // 全屏编辑器的真实可见性同时受 expanded 与 prompt-slot suspension
3222
+ // 控制。对话框临时接管时撤下、关闭后恢复,和手动展开/收起一样都必须
3223
+ // 重锚 inline 视口;只在一次真正的 false→true 展开时归零滚动位置,
3224
+ // suspension 往返保留用户浏览到的行。
3225
+ const editorVisible = expanded && !suspended;
3226
+ const prevEditorVisibleRef = React.useRef(editorVisible);
3227
+ React.useLayoutEffect(() => {
3228
+ if (expanded && !prevExpandedRef.current)
3229
+ expandedScrollRef.current = 0;
3230
+ prevExpandedRef.current = expanded;
3231
+ if (editorVisible === prevEditorVisibleRef.current)
3232
+ return;
3233
+ prevEditorVisibleRef.current = editorVisible;
3234
+ const ink = instances.get(process.stdout) ?? instances.values().next().value;
3235
+ ink?.invalidatePrevFrame();
3236
+ ink?.reanchorViewport();
3237
+ }, [editorVisible, expanded]);
3238
+ // Feature turned off mid-session while the editor is up: withdraw the
3239
+ // cover (the draft and every other editing state survive).
3240
+ React.useEffect(() => {
3241
+ if (expanded && !expandEnabled)
3242
+ collapseEditor();
3243
+ }, [expanded, expandEnabled]);
3244
+ // ── 全屏草稿编辑节点 ────────────────────────────────────────────────
3245
+ // 每次渲染构造新鲜闭包(value/caret/handlers),经 module store 发布给
3246
+ // Chat 根部末尾的 PromptEditorLayer(树序最后 → 盖住全部后绘兄弟)。
3247
+ // useInsertionEffect 发布:sink 的同步重渲染发生在 layout 阶段之前,
3248
+ // useDeclaredCursor(layout effect)读到的新 ref 已指向编辑区 Box。
3249
+ // 点击/拖拽坐标以内容区为原点(localCol 去掉行号槽宽度)。
3250
+ const editorNode = editorVisible ? (_jsxs(Box, { flexDirection: "column", width: "100%", height: "100%", borderStyle: "round", borderColor: promptAccent, backgroundColor: "toolCardBackground", children: [_jsxs(Box, { flexDirection: "row", flexShrink: 0, paddingLeft: 1, paddingRight: 1, children: [_jsx(Text, { bold: true, color: promptAccent, children: `✎ ${t('input-expand-editor-title')}` }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { dimColor: true, children: t('input-fold-stats', {
3251
+ lines: value.split('\n').length,
3252
+ chars: value.length,
3253
+ }) })] }), _jsx(Box, { ref: valueBoxRef, flexDirection: "column", flexGrow: 1, flexShrink: 1, paddingLeft: 1, paddingRight: 1, onClick: (event) => {
3254
+ handleValueClick(event, editorGutterCols + 1);
3255
+ }, onDragStart: (event) => {
3256
+ handleDragStart(event, editorGutterCols + 1);
3257
+ }, onDragMove: (event) => {
3258
+ handleDragMove(event, editorGutterCols + 1);
3259
+ }, onDragEnd: handleDragEnd, onWheel: (event) => {
3260
+ const viewport = editorViewportRef.current;
3261
+ if (!viewport)
3262
+ return;
3263
+ editorFreeScrollRef.current = true;
3264
+ const max = Math.max(0, viewport.total - viewport.maxRows);
3265
+ expandedScrollRef.current = Math.max(0, Math.min(expandedScrollRef.current + Math.round(event.deltaY), max));
3266
+ setExpandedTick(tick => tick + 1);
3267
+ }, children: editorRows }), _jsxs(Box, { flexDirection: "row", flexShrink: 0, paddingLeft: 1, paddingRight: 1, children: [vimEnabled && (_jsxs(Text, { bold: true, color: vimInsert ? 'success' : 'warning', children: [vimInsert ? 'INSERT' : 'NORMAL', ' '] })), _jsx(Text, { dimColor: true, children: t('input-expand-editor-position', {
3268
+ line: cursorLine(value, cursor) + 1,
3269
+ col: cursorColumn(value, cursor) + 1,
3270
+ }) }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { dimColor: true, children: `${t('input-expand-editor-hint-send')} · ${t('input-expand-editor-hint-collapse')}` })] }), _jsxs(Box, { flexDirection: "row", flexShrink: 0, paddingLeft: 1, paddingRight: 1, columnGap: 1, children: [_jsx(EditorButton, { label: `⏎ ${t('input-expand-editor-send')}`, hint: "Ctrl+Enter", primary: true, accent: promptAccent, onClick: submitFromEditor }), _jsx(EditorButton, { label: t('input-expand-editor-collapse'), hint: "Esc", onClick: collapseEditor }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { dimColor: true, children: t('input-expand-editor-scroll') })] })] })) : null;
3271
+ React.useInsertionEffect(() => {
3272
+ setPromptEditorNode(editorNode);
3273
+ });
3274
+ React.useEffect(() => {
3275
+ // 卸载保险:PromptInput 被替换(问卷/面板接管)时撤下全屏浮层。
3276
+ return () => {
3277
+ setPromptEditorNode(null);
3278
+ };
3279
+ }, []);
3280
+ // Approval, question and managed-dialog panels temporarily own Chat's
3281
+ // prompt slot. Stay mounted so an async command can settle without losing
3282
+ // its exact text/image draft, while contributing no layout, input, cursor,
3283
+ // editor layer, or external injection controller.
3284
+ if (suspended)
3285
+ return null;
3286
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [floatersOpen && (_jsxs(OverlayAbove, { maxHeight: Math.max(terminalRows - 6, 1), children: [helpOpen && (_jsx(Box, { marginBottom: 1, children: _jsx(HelpMenu, { commands: channel.commandList, viewportHeight: helpViewportHeight, viewportWidth: columns, scrollRef: helpScrollRef, onCommandPick: (name) => {
3287
+ // 点击命令行 = 填入 /name 并关闭帮助(Tab 补全的鼠标等价)
3288
+ updateFoldBlock(null);
3289
+ setInput(`/${name} `);
3290
+ onToggleHelp();
3291
+ } }) })), !helpOpen && channel.pending.length > 0 && (_jsxs(Box, { flexDirection: "column", paddingLeft: 2, paddingBottom: 1, children: [channel.pending.some(item => item.placement === 'steer') && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: ["\u26A1 ", t('input-pending-steer-label')] }), channel.pending
3292
+ .filter(item => item.placement === 'steer')
3293
+ .map(item => (_jsxs(Text, { dimColor: true, wrap: "truncate", children: [' ', "\u21B3 ", item.text] }, item.id)))] })), channel.pending.some(item => item.placement === 'followup') && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: ["\u23F3 ", t('input-pending-queue-label')] }), channel.pending
3294
+ .filter(item => item.placement === 'followup')
3295
+ .map(item => (_jsxs(Text, { dimColor: true, wrap: "truncate", children: [' ', "\u21B3 ", item.text] }, item.id)))] })), _jsxs(Text, { dimColor: true, children: ["Alt+\u2191 ", t('input-pending-actions-hint')] })] })), fileOverlayOpen && (_jsx(FileSuggestions, { files: fileMatches, selectedIndex: fileSelected, columns: columns, query: mention?.query ?? '', accent: promptAccent,
3296
+ // 点击行 = 接受该项(与 Enter 同路径)
3297
+ onPick: (index) => {
3298
+ const file = fileMatches[index];
3299
+ if (file)
3300
+ acceptFile(file);
3301
+ },
3302
+ // 滚轮 = 移动选中行(与 ↑/↓ 同路径,窗口跟随)
3303
+ onWheelStep: (step) => {
3304
+ setFileSelected(i => Math.max(0, Math.min(fileMatches.length - 1, i + step)));
3305
+ } })), overlayOpen && (_jsx(CommandSuggestions, { commands: suggestions, selectedIndex: selectedCommand, columns: columns, query: value, accent: promptAccent,
3306
+ // 点击行 = 运行该命令(与 Enter 同路径)
3307
+ onPick: (index) => {
3308
+ const command = suggestions[index];
3309
+ if (command)
3310
+ tryRunCommand(command.commandLine);
3311
+ },
3312
+ // 滚轮 = 移动选中行(与 ↑/↓ 同路径,窗口跟随)
3313
+ onWheelStep: (step) => {
3314
+ setSelectedCommand(i => Math.max(0, Math.min(suggestions.length - 1, i + step)));
3315
+ } })), peekOpen && (_jsx(Box, { onMouseEnter: hoverEnter, onMouseLeave: hoverLeave, children: _jsx(SuggestionCard, { title: stats, columns: columns, accent: promptAccent, footer: peekClipped
3316
+ ? t('input-fold-peek-footer', { lines: foldText.split('\n').length })
3317
+ : undefined, rows: peekVisualLines.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, index))), onRowPick: () => {
3318
+ updateFoldBlock(null);
3319
+ setHovered(false);
3320
+ } }) }))] })), lastNotification && (_jsx(Box, { position: "absolute", marginTop: -1, height: 1, width: "100%", paddingLeft: 2, paddingRight: 1, flexDirection: "column", justifyContent: "flex-end", overflow: "hidden", children: _jsx(Box, { justifyContent: "flex-end", children: _jsx(Text, { color: lastNotification.color, dimColor: !lastNotification.color, wrap: "truncate", children: lastNotification.text }) }) })), _jsx(EffortInputBorder, { effort: channel.reasoningEffort, levels: channel.effortLevels, columns: columns, onLight: isLightThemeActive(themeName), idleColor: promptAccent, topRightLabel: topRightLabel, children: _jsxs(Box, { flexDirection: "row", alignItems: "flex-start", width: "100%", children: [onOpenSessions !== undefined && (_jsx(Box, { flexShrink: 0, onClick: (event) => {
3321
+ event.stopImmediatePropagation();
3322
+ onOpenSessions?.();
3323
+ }, onMouseEnter: () => {
3324
+ setHomeHovered(true);
3325
+ }, onMouseLeave: () => {
3326
+ setHomeHovered(false);
3327
+ }, children: _jsx(Text, { dimColor: !homeHovered, bold: homeHovered, color: homeHovered ? promptAccent : undefined, children: HOME_BUTTON_TEXT }) })), _jsx(EffortChargeGlyph, { effort: channel.reasoningEffort, levels: channel.effortLevels, working: channel.working }), vimEnabled && (_jsxs(Text, { bold: true, color: vimInsert ? 'success' : 'warning', children: [vimInsert ? 'INSERT' : 'NORMAL', " "] })), _jsx(Box, { ref: expanded ? undefined : valueBoxRef, flexGrow: 1, flexShrink: 1, onClick: handleValueClick, onDragStart: handleDragStart, onDragMove: handleDragMove, onDragEnd: handleDragEnd, children: value.length === 0 ? (_jsxs(_Fragment, { children: [_jsx(Text, { inverse: true, children: " " }), _jsx(EffortTierBadge, { effort: channel.reasoningEffort, levels: channel.effortLevels, onLight: isLightThemeActive(themeName), columns: columns, leadingColumns: 3 + homeButtonCols })] })) : (_jsx(Box, { flexDirection: "column", children: rendered })) }), expandEnabled && (_jsx(Box, { flexShrink: 0, onClick: (event) => {
3328
+ event.stopImmediatePropagation();
3329
+ toggleExpand();
3330
+ }, onMouseEnter: () => {
3331
+ setExpandHovered(true);
3332
+ }, onMouseLeave: () => {
3333
+ setExpandHovered(false);
3334
+ }, children: _jsx(Text, { dimColor: !expandHovered, bold: expandHovered, color: expandHovered ? promptAccent : undefined, children: "\u26F6" }) }))] }) }), backgroundAgentsNeedingInput !== undefined && (_jsx(Box, { flexDirection: "row", justifyContent: "flex-end", paddingRight: 2, children: _jsx(Text, { dimColor: true, children: backgroundAgentsNeedingInput > 0
3335
+ ? t('input-background-hint-count', { n: backgroundAgentsNeedingInput })
3336
+ : t('input-background-hint-idle') }) }))] }));
3337
+ }
3338
+ /**
3339
+ * Grapheme word-wrap for one logical line: break at the last space when
3340
+ * the row overflows; hard-wrap a word that cannot fit; never split a
3341
+ * cluster (ZWJ emoji, combining sequences, CJK wide cells stay whole).
3342
+ */
3343
+ function wrapLineRows(line, width) {
3344
+ if (line === '')
3345
+ return [{ start: 0, end: 0 }];
3346
+ const rows = [];
3347
+ const segmenter = getGraphemeSegmenter();
3348
+ // The space inside `[Image #N]` is not a break opportunity: the token is
3349
+ // one unit on screen (its caret cluster and chip styling span it), so it
3350
+ // wraps whole, like a word.
3351
+ const unbreakable = imageTokenSpans(line);
3352
+ let rowStart = 0;
3353
+ let currentWidth = 0;
3354
+ let offset = 0;
3355
+ let lastBreak = -1;
3356
+ for (const { segment } of segmenter.segment(line)) {
3357
+ const w = stringWidth(segment);
3358
+ while (currentWidth + w > width && offset > rowStart) {
3359
+ if (lastBreak > rowStart) {
3360
+ rows.push({ start: rowStart, end: lastBreak });
3361
+ rowStart = lastBreak;
3362
+ currentWidth = stringWidth(line.slice(rowStart, offset));
3363
+ lastBreak = -1;
3364
+ }
3365
+ else {
3366
+ rows.push({ start: rowStart, end: offset });
3367
+ rowStart = offset;
3368
+ currentWidth = 0;
3369
+ lastBreak = -1;
3370
+ }
3371
+ }
3372
+ currentWidth += w;
3373
+ offset += segment.length;
3374
+ if (segment === ' ' && imageTokenAround(unbreakable, offset) === undefined)
3375
+ lastBreak = offset;
3376
+ }
3377
+ rows.push({ start: rowStart, end: offset });
3378
+ return rows;
3379
+ }
3380
+ /** Wrap text to `width` columns via {@link wrapLineRows} (newlines honoured). */
3381
+ function wrapToWidth(text, width) {
3382
+ return text.split('\n').flatMap(line => wrapLineRows(line, width).map(r => line.slice(r.start, r.end)));
3383
+ }
3384
+ /**
3385
+ * Locate `offset` in the wrapped layout of `text`. Uses the full wrap —
3386
+ * not a prefix — so a cursor inside a carried word maps to the displayed
3387
+ * row. At a wrap join the caret stays on the earlier row (after the space).
3388
+ */
3389
+ function caretInText(text, width, offset) {
3390
+ let line = 0;
3391
+ let lineBase = 0;
3392
+ let last = { line: 0, charCol: 0, visualCol: 0 };
3393
+ for (const logical of text.split('\n')) {
3394
+ for (const r of wrapLineRows(logical, width)) {
3395
+ const start = lineBase + r.start;
3396
+ const charCol = Math.max(0, offset - start);
3397
+ last = {
3398
+ line,
3399
+ charCol,
3400
+ visualCol: stringWidth(logical.slice(r.start, r.start + charCol)),
3401
+ };
3402
+ if (offset <= lineBase + r.end)
3403
+ return last;
3404
+ line++;
3405
+ }
3406
+ lineBase += logical.length + 1;
3407
+ }
3408
+ return last;
3409
+ }
3410
+ /**
3411
+ * Inverse of {@link wrapToWidth}: map a click position (visual row index +
3412
+ * visual column) back to a UTF-16 offset in the original text. Uses the
3413
+ * same {@link wrapLineRows} row boundaries, so every visual row's start
3414
+ * offset is known exactly. Within the clicked row, the caret snaps to the
3415
+ * boundary nearest the click: a grapheme whose midpoint lies past the
3416
+ * click column takes the caret before it, otherwise after.
3417
+ */
3418
+ function clickToCursorOffset(text, width, visualLine, visualCol, snapWithin = 'nearest') {
3419
+ const segmenter = getGraphemeSegmenter();
3420
+ let row = 0;
3421
+ let lineBase = 0;
3422
+ for (const line of text.split('\n')) {
3423
+ for (const r of wrapLineRows(line, width)) {
3424
+ if (row === visualLine) {
3425
+ let currentWidth = 0;
3426
+ let local = 0;
3427
+ for (const { segment } of segmenter.segment(line.slice(r.start, r.end))) {
3428
+ const w = stringWidth(segment);
3429
+ // Caret positioning uses the nearest edge. Double-click selection
3430
+ // instead needs the grapheme UNDER the cell: on the second cell of a
3431
+ // CJK/emoji glyph, nearest-edge would point after the glyph (and the
3432
+ // final glyph would select nothing).
3433
+ if (snapWithin === 'grapheme-start' && currentWidth + w > visualCol) {
3434
+ return lineBase + r.start + local;
3435
+ }
3436
+ if (currentWidth + w / 2 > visualCol)
3437
+ return lineBase + r.start + local;
3438
+ if (currentWidth + w > visualCol)
3439
+ return lineBase + r.start + local + segment.length;
3440
+ currentWidth += w;
3441
+ local += segment.length;
3442
+ }
3443
+ return lineBase + r.end;
3444
+ }
3445
+ row++;
3446
+ }
3447
+ lineBase += line.length + 1;
3448
+ }
3449
+ return lineBase;
3450
+ }
3451
+ /**
3452
+ * Offset range [start, end) of every visual row, using the same {@link
3453
+ * wrapLineRows} boundaries as `wrapToWidth`. The selection highlight
3454
+ * intersects each row with these ranges so offsets map 1:1 onto the
3455
+ * rendered row strings.
3456
+ */
3457
+ function visualLineRanges(text, width) {
3458
+ const ranges = [];
3459
+ let lineBase = 0;
3460
+ for (const line of text.split('\n')) {
3461
+ for (const r of wrapLineRows(line, width))
3462
+ ranges.push([lineBase + r.start, lineBase + r.end]);
3463
+ lineBase += line.length + 1;
3464
+ }
3465
+ return ranges;
3466
+ }
3467
+ /** Word characters for double-click selection: letters (any script),
3468
+ * digits and the punctuation set terminal emulators treat as word-part by
3469
+ * default (`/usr/bin/bash` selects whole — iTerm2 defaults). */
3470
+ const WORD_CHAR = /[\p{L}\p{N}_/.\-+~\\]/u;
3471
+ /** Character class for double-click word expansion: whitespace, word
3472
+ * char, everything else (punctuation/symbols). A same-class grapheme
3473
+ * run is one word. */
3474
+ function selectionCharClass(c) {
3475
+ if (c === '' || /\s/.test(c))
3476
+ return 0;
3477
+ if (WORD_CHAR.test(c))
3478
+ return 1;
3479
+ return 2;
3480
+ }
3481
+ /**
3482
+ * Word selection around `offset` within [lo, hi): expand left/right over
3483
+ * grapheme clusters of the same class as the clicked one (terminal
3484
+ * double-click semantics — punctuation runs select as one). Returns null
3485
+ * when the offset sits at the range's end (nothing to select).
3486
+ */
3487
+ function wordSelectionAt(text, offset, lo, hi) {
3488
+ if (offset < lo || offset >= hi)
3489
+ return null;
3490
+ const bounds = graphemeBoundaries(text.slice(lo, hi)).map(b => b + lo);
3491
+ let i = 0;
3492
+ while (i < bounds.length - 1 && bounds[i + 1] <= offset)
3493
+ i++;
3494
+ const clusterAt = (index) => text.slice(bounds[index], bounds[index + 1]);
3495
+ const cls = selectionCharClass(clusterAt(i));
3496
+ let a = i;
3497
+ while (a > 0 && selectionCharClass(clusterAt(a - 1)) === cls)
3498
+ a--;
3499
+ let b = i;
3500
+ while (b < bounds.length - 2 && selectionCharClass(clusterAt(b + 1)) === cls)
3501
+ b++;
3502
+ return { start: bounds[a], end: bounds[b + 1] };
3503
+ }