@ai-zen/cli 1.0.0-alpha.9 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/CHANGELOG.md +1334 -275
  2. package/LICENSE +21 -0
  3. package/README.md +136 -31
  4. package/README.zh.md +136 -31
  5. package/dist/agent-creator.d.ts +11 -0
  6. package/dist/agent-creator.d.ts.map +1 -1
  7. package/dist/agent-creator.js +50 -20
  8. package/dist/agent-creator.js.map +1 -1
  9. package/dist/agent-switch.d.ts +61 -0
  10. package/dist/agent-switch.d.ts.map +1 -0
  11. package/dist/agent-switch.js +83 -0
  12. package/dist/agent-switch.js.map +1 -0
  13. package/dist/agents-store.d.ts +6 -1
  14. package/dist/agents-store.d.ts.map +1 -1
  15. package/dist/agents-store.js +46 -4
  16. package/dist/agents-store.js.map +1 -1
  17. package/dist/auto-migrate-confirm.d.ts +43 -0
  18. package/dist/auto-migrate-confirm.d.ts.map +1 -0
  19. package/dist/auto-migrate-confirm.js +47 -0
  20. package/dist/auto-migrate-confirm.js.map +1 -0
  21. package/dist/clipboard.d.ts +68 -0
  22. package/dist/clipboard.d.ts.map +1 -0
  23. package/dist/clipboard.js +177 -0
  24. package/dist/clipboard.js.map +1 -0
  25. package/dist/config-editor.d.ts +42 -5
  26. package/dist/config-editor.d.ts.map +1 -1
  27. package/dist/config-editor.js +80 -27
  28. package/dist/config-editor.js.map +1 -1
  29. package/dist/config.d.ts +76 -17
  30. package/dist/config.d.ts.map +1 -1
  31. package/dist/config.js +143 -39
  32. package/dist/config.js.map +1 -1
  33. package/dist/conversation-commands/registry.d.ts +127 -4
  34. package/dist/conversation-commands/registry.d.ts.map +1 -1
  35. package/dist/conversation-commands/registry.js +93 -14
  36. package/dist/conversation-commands/registry.js.map +1 -1
  37. package/dist/conversation-persist-plugin.d.ts +0 -1
  38. package/dist/conversation-persist-plugin.d.ts.map +1 -1
  39. package/dist/conversation-persist-plugin.js +7 -16
  40. package/dist/conversation-persist-plugin.js.map +1 -1
  41. package/dist/conversation-repository.d.ts +79 -18
  42. package/dist/conversation-repository.d.ts.map +1 -1
  43. package/dist/conversation-repository.js +96 -30
  44. package/dist/conversation-repository.js.map +1 -1
  45. package/dist/cwd-tracker-plugin.d.ts.map +1 -1
  46. package/dist/cwd-tracker-plugin.js +22 -7
  47. package/dist/cwd-tracker-plugin.js.map +1 -1
  48. package/dist/format-time.d.ts +17 -6
  49. package/dist/format-time.d.ts.map +1 -1
  50. package/dist/format-time.js +32 -14
  51. package/dist/format-time.js.map +1 -1
  52. package/dist/handoff-service.d.ts +19 -0
  53. package/dist/handoff-service.d.ts.map +1 -0
  54. package/dist/handoff-service.js +85 -0
  55. package/dist/handoff-service.js.map +1 -0
  56. package/dist/hook.d.ts.map +1 -1
  57. package/dist/hook.js +69 -15
  58. package/dist/hook.js.map +1 -1
  59. package/dist/i18n/en-wizard.d.ts +8 -0
  60. package/dist/i18n/en-wizard.d.ts.map +1 -0
  61. package/dist/i18n/en-wizard.js +303 -0
  62. package/dist/i18n/en-wizard.js.map +1 -0
  63. package/dist/i18n/en.d.ts +7 -0
  64. package/dist/i18n/en.d.ts.map +1 -0
  65. package/dist/i18n/en.js +245 -0
  66. package/dist/i18n/en.js.map +1 -0
  67. package/dist/i18n/index.d.ts +57 -0
  68. package/dist/i18n/index.d.ts.map +1 -0
  69. package/dist/i18n/index.js +109 -0
  70. package/dist/i18n/index.js.map +1 -0
  71. package/dist/i18n/preferences.d.ts +37 -0
  72. package/dist/i18n/preferences.d.ts.map +1 -0
  73. package/dist/i18n/preferences.js +73 -0
  74. package/dist/i18n/preferences.js.map +1 -0
  75. package/dist/i18n/zh-wizard.d.ts +11 -0
  76. package/dist/i18n/zh-wizard.d.ts.map +1 -0
  77. package/dist/i18n/zh-wizard.js +306 -0
  78. package/dist/i18n/zh-wizard.js.map +1 -0
  79. package/dist/i18n/zh.d.ts +10 -0
  80. package/dist/i18n/zh.d.ts.map +1 -0
  81. package/dist/i18n/zh.js +249 -0
  82. package/dist/i18n/zh.js.map +1 -0
  83. package/dist/index.js +52 -23
  84. package/dist/index.js.map +1 -1
  85. package/dist/mcp-command.d.ts +32 -0
  86. package/dist/mcp-command.d.ts.map +1 -0
  87. package/dist/mcp-command.js +37 -0
  88. package/dist/mcp-command.js.map +1 -0
  89. package/dist/mode.d.ts +31 -4
  90. package/dist/mode.d.ts.map +1 -1
  91. package/dist/mode.js +42 -7
  92. package/dist/mode.js.map +1 -1
  93. package/dist/model-switch.d.ts +58 -0
  94. package/dist/model-switch.d.ts.map +1 -0
  95. package/dist/model-switch.js +62 -0
  96. package/dist/model-switch.js.map +1 -0
  97. package/dist/reasoning-effort.d.ts +96 -0
  98. package/dist/reasoning-effort.d.ts.map +1 -0
  99. package/dist/reasoning-effort.js +164 -0
  100. package/dist/reasoning-effort.js.map +1 -0
  101. package/dist/reasoning-presets.d.ts +34 -0
  102. package/dist/reasoning-presets.d.ts.map +1 -0
  103. package/dist/reasoning-presets.js +85 -0
  104. package/dist/reasoning-presets.js.map +1 -0
  105. package/dist/sdk-log.d.ts +84 -0
  106. package/dist/sdk-log.d.ts.map +1 -0
  107. package/dist/sdk-log.js +167 -0
  108. package/dist/sdk-log.js.map +1 -0
  109. package/dist/session-pointer.d.ts.map +1 -1
  110. package/dist/session-pointer.js +10 -4
  111. package/dist/session-pointer.js.map +1 -1
  112. package/dist/stdio-runner.d.ts.map +1 -1
  113. package/dist/stdio-runner.js +32 -30
  114. package/dist/stdio-runner.js.map +1 -1
  115. package/dist/sub-agent-guard-plugin.d.ts +10 -7
  116. package/dist/sub-agent-guard-plugin.d.ts.map +1 -1
  117. package/dist/sub-agent-guard-plugin.js +12 -9
  118. package/dist/sub-agent-guard-plugin.js.map +1 -1
  119. package/dist/tui/chat-history.d.ts +29 -0
  120. package/dist/tui/chat-history.d.ts.map +1 -0
  121. package/dist/tui/chat-history.js +55 -0
  122. package/dist/tui/chat-history.js.map +1 -0
  123. package/dist/tui/chat-session.d.ts +144 -13
  124. package/dist/tui/chat-session.d.ts.map +1 -1
  125. package/dist/tui/chat-session.js +312 -73
  126. package/dist/tui/chat-session.js.map +1 -1
  127. package/dist/tui/components.d.ts +109 -6
  128. package/dist/tui/components.d.ts.map +1 -1
  129. package/dist/tui/components.js +177 -12
  130. package/dist/tui/components.js.map +1 -1
  131. package/dist/tui/config-wizard/detail.d.ts +18 -10
  132. package/dist/tui/config-wizard/detail.d.ts.map +1 -1
  133. package/dist/tui/config-wizard/detail.js +53 -46
  134. package/dist/tui/config-wizard/detail.js.map +1 -1
  135. package/dist/tui/config-wizard/engine.d.ts +2 -2
  136. package/dist/tui/config-wizard/engine.d.ts.map +1 -1
  137. package/dist/tui/config-wizard/engine.js +48 -26
  138. package/dist/tui/config-wizard/engine.js.map +1 -1
  139. package/dist/tui/config-wizard/fields.d.ts +3 -1
  140. package/dist/tui/config-wizard/fields.d.ts.map +1 -1
  141. package/dist/tui/config-wizard/fields.js +202 -167
  142. package/dist/tui/config-wizard/fields.js.map +1 -1
  143. package/dist/tui/config-wizard/frame.js +1 -1
  144. package/dist/tui/config-wizard/kv-editor.d.ts.map +1 -1
  145. package/dist/tui/config-wizard/kv-editor.js +13 -5
  146. package/dist/tui/config-wizard/kv-editor.js.map +1 -1
  147. package/dist/tui/config-wizard/list.d.ts +3 -1
  148. package/dist/tui/config-wizard/list.d.ts.map +1 -1
  149. package/dist/tui/config-wizard/list.js +4 -4
  150. package/dist/tui/config-wizard/list.js.map +1 -1
  151. package/dist/tui/config-wizard/mcp-helpers.d.ts.map +1 -1
  152. package/dist/tui/config-wizard/mcp-helpers.js +4 -3
  153. package/dist/tui/config-wizard/mcp-helpers.js.map +1 -1
  154. package/dist/tui/config-wizard/menu.d.ts.map +1 -1
  155. package/dist/tui/config-wizard/menu.js +33 -21
  156. package/dist/tui/config-wizard/menu.js.map +1 -1
  157. package/dist/tui/config-wizard/prompt-editor.d.ts +8 -1
  158. package/dist/tui/config-wizard/prompt-editor.d.ts.map +1 -1
  159. package/dist/tui/config-wizard/prompt-editor.js +11 -7
  160. package/dist/tui/config-wizard/prompt-editor.js.map +1 -1
  161. package/dist/tui/config-wizard/prompt.d.ts.map +1 -1
  162. package/dist/tui/config-wizard/prompt.js +8 -7
  163. package/dist/tui/config-wizard/prompt.js.map +1 -1
  164. package/dist/tui/config-wizard/step-agents.d.ts.map +1 -1
  165. package/dist/tui/config-wizard/step-agents.js +50 -29
  166. package/dist/tui/config-wizard/step-agents.js.map +1 -1
  167. package/dist/tui/config-wizard/step-defaults.d.ts.map +1 -1
  168. package/dist/tui/config-wizard/step-defaults.js +77 -27
  169. package/dist/tui/config-wizard/step-defaults.js.map +1 -1
  170. package/dist/tui/config-wizard/step-endpoints.d.ts.map +1 -1
  171. package/dist/tui/config-wizard/step-endpoints.js +27 -14
  172. package/dist/tui/config-wizard/step-endpoints.js.map +1 -1
  173. package/dist/tui/config-wizard/step-mcp.d.ts.map +1 -1
  174. package/dist/tui/config-wizard/step-mcp.js +29 -25
  175. package/dist/tui/config-wizard/step-mcp.js.map +1 -1
  176. package/dist/tui/config-wizard/step-models.d.ts.map +1 -1
  177. package/dist/tui/config-wizard/step-models.js +98 -43
  178. package/dist/tui/config-wizard/step-models.js.map +1 -1
  179. package/dist/tui/config-wizard/step-new-endpoint.d.ts.map +1 -1
  180. package/dist/tui/config-wizard/step-new-endpoint.js +16 -12
  181. package/dist/tui/config-wizard/step-new-endpoint.js.map +1 -1
  182. package/dist/tui/config-wizard/step-simple.d.ts.map +1 -1
  183. package/dist/tui/config-wizard/step-simple.js +18 -17
  184. package/dist/tui/config-wizard/step-simple.js.map +1 -1
  185. package/dist/tui/config-wizard/types.d.ts +31 -3
  186. package/dist/tui/config-wizard/types.d.ts.map +1 -1
  187. package/dist/tui/config-wizard/types.js.map +1 -1
  188. package/dist/tui/file-index.d.ts +38 -0
  189. package/dist/tui/file-index.d.ts.map +1 -0
  190. package/dist/tui/file-index.js +117 -0
  191. package/dist/tui/file-index.js.map +1 -0
  192. package/dist/tui/index.d.ts +17 -1
  193. package/dist/tui/index.d.ts.map +1 -1
  194. package/dist/tui/index.js +105 -49
  195. package/dist/tui/index.js.map +1 -1
  196. package/dist/tui/input-editing.d.ts +52 -0
  197. package/dist/tui/input-editing.d.ts.map +1 -0
  198. package/dist/tui/input-editing.js +91 -0
  199. package/dist/tui/input-editing.js.map +1 -0
  200. package/dist/tui/key-debug.d.ts +62 -0
  201. package/dist/tui/key-debug.d.ts.map +1 -0
  202. package/dist/tui/key-debug.js +92 -0
  203. package/dist/tui/key-debug.js.map +1 -0
  204. package/dist/tui/mention.d.ts +47 -0
  205. package/dist/tui/mention.d.ts.map +1 -0
  206. package/dist/tui/mention.js +152 -0
  207. package/dist/tui/mention.js.map +1 -0
  208. package/dist/tui/mouse.d.ts +55 -0
  209. package/dist/tui/mouse.d.ts.map +1 -0
  210. package/dist/tui/mouse.js +74 -0
  211. package/dist/tui/mouse.js.map +1 -0
  212. package/dist/tui/phase.d.ts +64 -0
  213. package/dist/tui/phase.d.ts.map +1 -0
  214. package/dist/tui/phase.js +112 -0
  215. package/dist/tui/phase.js.map +1 -0
  216. package/dist/tui/screens/agent-tabs.d.ts +53 -0
  217. package/dist/tui/screens/agent-tabs.d.ts.map +1 -0
  218. package/dist/tui/screens/agent-tabs.js +81 -0
  219. package/dist/tui/screens/agent-tabs.js.map +1 -0
  220. package/dist/tui/screens/chat-commands.d.ts +78 -1
  221. package/dist/tui/screens/chat-commands.d.ts.map +1 -1
  222. package/dist/tui/screens/chat-commands.js +688 -157
  223. package/dist/tui/screens/chat-commands.js.map +1 -1
  224. package/dist/tui/screens/chat.d.ts +57 -1
  225. package/dist/tui/screens/chat.d.ts.map +1 -1
  226. package/dist/tui/screens/chat.js +708 -261
  227. package/dist/tui/screens/chat.js.map +1 -1
  228. package/dist/tui/screens/common-keys.d.ts +36 -0
  229. package/dist/tui/screens/common-keys.d.ts.map +1 -0
  230. package/dist/tui/screens/common-keys.js +67 -0
  231. package/dist/tui/screens/common-keys.js.map +1 -0
  232. package/dist/tui/screens/frame-buffer.d.ts.map +1 -1
  233. package/dist/tui/screens/frame-buffer.js.map +1 -1
  234. package/dist/tui/screens/handoff-choice.d.ts +37 -0
  235. package/dist/tui/screens/handoff-choice.d.ts.map +1 -0
  236. package/dist/tui/screens/handoff-choice.js +42 -0
  237. package/dist/tui/screens/handoff-choice.js.map +1 -0
  238. package/dist/tui/screens/index.d.ts +7 -5
  239. package/dist/tui/screens/index.d.ts.map +1 -1
  240. package/dist/tui/screens/index.js +6 -5
  241. package/dist/tui/screens/index.js.map +1 -1
  242. package/dist/tui/screens/input-row.d.ts +64 -0
  243. package/dist/tui/screens/input-row.d.ts.map +1 -0
  244. package/dist/tui/screens/input-row.js +67 -0
  245. package/dist/tui/screens/input-row.js.map +1 -0
  246. package/dist/tui/screens/input.d.ts +77 -1
  247. package/dist/tui/screens/input.d.ts.map +1 -1
  248. package/dist/tui/screens/input.js +125 -8
  249. package/dist/tui/screens/input.js.map +1 -1
  250. package/dist/tui/screens/layout.d.ts +49 -0
  251. package/dist/tui/screens/layout.d.ts.map +1 -1
  252. package/dist/tui/screens/layout.js +45 -7
  253. package/dist/tui/screens/layout.js.map +1 -1
  254. package/dist/tui/screens/lines.d.ts +7 -0
  255. package/dist/tui/screens/lines.d.ts.map +1 -1
  256. package/dist/tui/screens/lines.js +6 -6
  257. package/dist/tui/screens/lines.js.map +1 -1
  258. package/dist/tui/screens/messages-view.d.ts +20 -1
  259. package/dist/tui/screens/messages-view.d.ts.map +1 -1
  260. package/dist/tui/screens/messages-view.js +55 -8
  261. package/dist/tui/screens/messages-view.js.map +1 -1
  262. package/dist/tui/screens/notice-bar.d.ts +5 -0
  263. package/dist/tui/screens/notice-bar.d.ts.map +1 -0
  264. package/dist/tui/screens/notice-bar.js +21 -0
  265. package/dist/tui/screens/notice-bar.js.map +1 -0
  266. package/dist/tui/screens/notice.d.ts +44 -10
  267. package/dist/tui/screens/notice.d.ts.map +1 -1
  268. package/dist/tui/screens/notice.js +75 -15
  269. package/dist/tui/screens/notice.js.map +1 -1
  270. package/dist/tui/screens/overlays.d.ts.map +1 -1
  271. package/dist/tui/screens/overlays.js +4 -3
  272. package/dist/tui/screens/overlays.js.map +1 -1
  273. package/dist/tui/screens/render.d.ts +1 -1
  274. package/dist/tui/screens/render.d.ts.map +1 -1
  275. package/dist/tui/screens/render.js +18 -11
  276. package/dist/tui/screens/render.js.map +1 -1
  277. package/dist/tui/screens/use-chat-viewport.d.ts +22 -0
  278. package/dist/tui/screens/use-chat-viewport.d.ts.map +1 -0
  279. package/dist/tui/screens/use-chat-viewport.js +50 -0
  280. package/dist/tui/screens/use-chat-viewport.js.map +1 -0
  281. package/dist/tui/screens/use-input-editing.d.ts +69 -0
  282. package/dist/tui/screens/use-input-editing.d.ts.map +1 -0
  283. package/dist/tui/screens/use-input-editing.js +220 -0
  284. package/dist/tui/screens/use-input-editing.js.map +1 -0
  285. package/dist/tui/screens/use-overlays.d.ts +25 -0
  286. package/dist/tui/screens/use-overlays.d.ts.map +1 -0
  287. package/dist/tui/screens/use-overlays.js +32 -0
  288. package/dist/tui/screens/use-overlays.js.map +1 -0
  289. package/dist/tui/screens/use-wizard-host.d.ts +46 -0
  290. package/dist/tui/screens/use-wizard-host.d.ts.map +1 -0
  291. package/dist/tui/screens/use-wizard-host.js +123 -0
  292. package/dist/tui/screens/use-wizard-host.js.map +1 -0
  293. package/dist/tui/screens/welcome.d.ts +12 -0
  294. package/dist/tui/screens/welcome.d.ts.map +1 -0
  295. package/dist/tui/screens/welcome.js +36 -0
  296. package/dist/tui/screens/welcome.js.map +1 -0
  297. package/dist/tui/status-segments.d.ts +37 -0
  298. package/dist/tui/status-segments.d.ts.map +1 -0
  299. package/dist/tui/status-segments.js +166 -0
  300. package/dist/tui/status-segments.js.map +1 -0
  301. package/dist/tui/text.d.ts +22 -7
  302. package/dist/tui/text.d.ts.map +1 -1
  303. package/dist/tui/text.js +110 -39
  304. package/dist/tui/text.js.map +1 -1
  305. package/dist/tui/theme.d.ts +2 -0
  306. package/dist/tui/theme.d.ts.map +1 -1
  307. package/dist/tui/theme.js +2 -0
  308. package/dist/tui/theme.js.map +1 -1
  309. package/dist/tui/token-rate.d.ts +83 -0
  310. package/dist/tui/token-rate.d.ts.map +1 -0
  311. package/dist/tui/token-rate.js +195 -0
  312. package/dist/tui/token-rate.js.map +1 -0
  313. package/dist/types.d.ts +7 -8
  314. package/dist/types.d.ts.map +1 -1
  315. package/dist/user-content.d.ts +41 -0
  316. package/dist/user-content.d.ts.map +1 -0
  317. package/dist/user-content.js +37 -0
  318. package/dist/user-content.js.map +1 -0
  319. package/dist/version-compare.d.ts +37 -0
  320. package/dist/version-compare.d.ts.map +1 -0
  321. package/dist/version-compare.js +105 -0
  322. package/dist/version-compare.js.map +1 -0
  323. package/dist/version.js.map +1 -1
  324. package/package.json +7 -5
  325. package/dist/auto-migrate-confirm-plugin.d.ts +0 -58
  326. package/dist/auto-migrate-confirm-plugin.d.ts.map +0 -1
  327. package/dist/auto-migrate-confirm-plugin.js +0 -61
  328. package/dist/auto-migrate-confirm-plugin.js.map +0 -1
  329. package/dist/migration-service.d.ts +0 -15
  330. package/dist/migration-service.d.ts.map +0 -1
  331. package/dist/migration-service.js +0 -66
  332. package/dist/migration-service.js.map +0 -1
  333. package/dist/tui/screens/splash.d.ts +0 -5
  334. package/dist/tui/screens/splash.d.ts.map +0 -1
  335. package/dist/tui/screens/splash.js +0 -51
  336. package/dist/tui/screens/splash.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-chat-viewport.js","sourceRoot":"","sources":["../../../src/tui/screens/use-chat-viewport.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,EAAE;AACF,yDAAyD;AACzD,kDAAkD;AAClD,yBAAyB;AACzB,EAAE;AACF,gDAAgD;AAChD,8BAA8B;AAC9B,2DAA2D;AAC3D,2BAA2B;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAmB,MAAM,aAAa,CAAC;AAqB5D,MAAM,UAAU,eAAe;IAC7B,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC5D,MAAM,SAAS,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IAElD,wDAAwD;IACxD,sCAAsC;IACtC,0DAA0D;IAC1D,wCAAwC;IACxC,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,OAAe,EAAE,EAAE;QAC/C,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5D,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,GAAW,EAAE,EAAE;QACd,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,gDAAgD;QAChD,0CAA0C;QAC1C,QAAQ,CAAC,CAAC,CAAC,OAAO,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,GAAW,EAAE,EAAE;QACd,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,QAAQ,CAAC,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC;IAC5B,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,MAAM,aAAa,GAAG,WAAW,CAC/B,CAAC,GAAW,EAAE,EAAE;QACd,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,QAAQ,CAAC,CAAC,CAAC,OAAO,GAAG,GAAG,GAAG,UAAU,CAAC,CAAC;IACzC,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAE/D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC;AAC3F,CAAC"}
@@ -0,0 +1,69 @@
1
+ import type { ClipboardImage } from "../../clipboard.js";
2
+ import type { HistoryEntry } from "../chat-history.js";
3
+ import type { Notice } from "./notice.js";
4
+ export interface InputEditingDeps {
5
+ /** 初始草稿(`/back` 撤回后重挂载用的预填内容),缺省空 */
6
+ initialText?: string;
7
+ /** 通知出口(暂存 / 取回草稿的提示,走通知通道而不是转录) */
8
+ notify: (text: string, tone?: Notice["tone"]) => void;
9
+ /**
10
+ * 历史数据源(`↑` / `↓` 翻的就是它):按发送顺序返回草稿,**最后一条最新**。
11
+ *
12
+ * 由外部注入(`userDrafts(session.messages)`)而不是 hook 自己攒:消息才是真相源,
13
+ * 自带图片;内部再存一份 `string[]` 就只能存文本,`↑` 回到带图消息时图会静默丢失。
14
+ */
15
+ historySource: () => readonly HistoryEntry[];
16
+ /** 把历史里的附件放回输入区(`↑` 回到带图片的消息时) */
17
+ restoreImages: (images: readonly ClipboardImage[]) => void;
18
+ }
19
+ export interface InputEditing {
20
+ /** 当前草稿 */
21
+ input: string;
22
+ /** 光标位置:以字素簇计的索引(0..字数),可落在末尾之后一格 */
23
+ cursor: number;
24
+ /** 整体替换草稿(光标移到末尾) */
25
+ setInputText: (text: string) => void;
26
+ insertAtCursor: (text: string) => void;
27
+ /**
28
+ * 用一段文本替换 `[start, end)` 区间(光标落到插入文本末尾),并记一条撤销。
29
+ *
30
+ * `@` 文件补全专用:它替换的是**整个 token**(可能是 `@src/tu` 这种半截路径,
31
+ * 也可能是光标停在中间、右半边还没删的部分),而不是在光标处插入。
32
+ * 走 `applyEdit` 才有撤销快照 —— 补错一次 `Ctrl+_` 就能退回原样。
33
+ */
34
+ replaceRange: (start: number, end: number, text: string) => void;
35
+ deleteBeforeCursor: () => void;
36
+ deleteAfterCursor: () => void;
37
+ deleteWordBeforeCursor: () => void;
38
+ deleteWordAfterCursor: () => void;
39
+ deleteToStartOfLine: () => void;
40
+ deleteToEndOfLine: () => void;
41
+ /** Ctrl+W:删到前一空白(标点不切分) */
42
+ deletePrevWhitespace: () => void;
43
+ /** Ctrl+Y / Alt+Y:取回 kill ring 里的一段;`advance` 为真时循环到更早的一段 */
44
+ yank: (advance: boolean) => void;
45
+ /** Ctrl+_:撤销上一次编辑 */
46
+ undoEdit: () => void;
47
+ /** Ctrl+S:暂存草稿 / 取回草稿 */
48
+ toggleStash: () => void;
49
+ moveCursor: (delta: number) => void;
50
+ moveCursorToLineStart: () => void;
51
+ moveCursorToLineEnd: () => void;
52
+ /**
53
+ * ↑ / ↓:光标上 / 下移一行(按折行后的视觉行,需要当前折行宽度)。
54
+ *
55
+ * 返回 `false` 表示已经在首行(↑)/ 末行(↓)——呼叫方据此改成翻历史:
56
+ * 「能在行间走就在行间走,走不动了才动历史」是这两个键的唯一语义。
57
+ */
58
+ moveCursorUpRow: (width: number) => boolean;
59
+ moveCursorDownRow: (width: number) => boolean;
60
+ /** 按词左右移动:`dir` 为 -1 往前、1 往后 */
61
+ moveCursorByWord: (dir: -1 | 1) => void;
62
+ /** 历史:上一条 / 下一条(没有可翻的时候自动空转;带图片的消息会把附件一并放回) */
63
+ historyPrev: () => void;
64
+ historyNext: () => void;
65
+ /** 提交时调用:清空草稿并退出历史浏览(历史游标复位到底部) */
66
+ clearDraft: () => void;
67
+ }
68
+ export declare function useInputEditing({ initialText, notify, historySource, restoreImages }: InputEditingDeps): InputEditing;
69
+ //# sourceMappingURL=use-input-editing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-input-editing.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/use-input-editing.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IACtD;;;;;OAKG;IACH,aAAa,EAAE,MAAM,SAAS,YAAY,EAAE,CAAC;IAC7C,kCAAkC;IAClC,aAAa,EAAE,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,KAAK,IAAI,CAAC;CAC5D;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW;IACX,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC;;;;;;OAMG;IACH,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjE,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,sBAAsB,EAAE,MAAM,IAAI,CAAC;IACnC,qBAAqB,EAAE,MAAM,IAAI,CAAC;IAClC,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,2BAA2B;IAC3B,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,6DAA6D;IAC7D,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjC,qBAAqB;IACrB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,yBAAyB;IACzB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,qBAAqB,EAAE,MAAM,IAAI,CAAC;IAClC,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC;;;;;OAKG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,gCAAgC;IAChC,gBAAgB,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IACxC,+CAA+C;IAC/C,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,mCAAmC;IACnC,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,wBAAgB,eAAe,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,EAAE,gBAAgB,GAAG,YAAY,CAkNrH"}
@@ -0,0 +1,220 @@
1
+ // 输入编辑 —— 草稿文本与光标、历史、kill ring、撤销栈、暂存区的唯一实现
2
+ //
3
+ // 从 `chat.tsx` 抽出来的理由:这一整块(`input` / `cursor` / `history` / kill ring /
4
+ // undo / stash + 20 个编辑动作)是**纯编辑器语义**,与「对话屏」毫无关系,却和会话、
5
+ // 向导、渲染挤在同一个组件里 —— 于是既不能单测,也每次都被误认为「对话的一部分」。
6
+ //
7
+ // 两条贯穿全篇的约定:
8
+ //
9
+ // 1. **按字素簇编辑**:所有位置计算都走 `graphemes()`。`❤️` 是 2 个 code point、
10
+ // `👨‍👩‍👧` 是 5 个,但它们都是**一个**字符 —— 按 code point 删会切出半个字素簇。
11
+ // 2. **纯函数算、hook 只套用**:具体「删哪个词、删到哪」在 `input.ts` /
12
+ // `input-editing.ts` 里(有独立测试),这里只负责「拿到结果 → 更新状态 + 记撤销」。
13
+ import { useRef, useState } from "react";
14
+ import { deleteToLineEnd, deleteToLineStart, deleteWordLeft, deleteWordRight, moveCursorRow, wordLeft, wordRight, } from "./input.js";
15
+ import { deleteToPrevWhitespace, killedText, killAt, popUndo, pushKill, pushUndo, } from "../input-editing.js";
16
+ import { graphemes } from "../text.js";
17
+ import { t } from "../../i18n/index.js";
18
+ export function useInputEditing({ initialText, notify, historySource, restoreImages }) {
19
+ const [input, setInput] = useState(initialText ?? "");
20
+ const [cursor, setCursor] = useState(graphemes(initialText ?? "").length);
21
+ /** 历史游标:-1 = 不在浏览历史(当前是草稿);具体内容每次现取 `historySource()` */
22
+ const historyIndex = useRef(-1);
23
+ /** kill ring:Ctrl+W/U/K 删掉的文本,Ctrl+Y 取回、Alt+Y 循环 */
24
+ const killRingRef = useRef([]);
25
+ const yankIndexRef = useRef(-1);
26
+ /** 编辑撤销栈(Ctrl+_) */
27
+ const undoStackRef = useRef([]);
28
+ /** 暂存区(Ctrl+S) */
29
+ const stashRef = useRef(null);
30
+ const setInputText = (text) => {
31
+ setInput(text);
32
+ setCursor(graphemes(text).length);
33
+ };
34
+ /**
35
+ * 取「当前文本 + 钳制后的光标」,所有编辑动作的统一起点。
36
+ *
37
+ * 钳制防的**不是**「cursor 越界」——`cursor` 的每个写入点都已保证落在 `[0, len]`;
38
+ * 防的是**文本与光标不同步**:`input` 与 `cursor` 是两个 state,任何一处只改其一
39
+ * (或将来新增编辑动作忘了同步)都会让 `cp > chars.length` 成立,那时 `slice`
40
+ * 会静默切少、`cp - 1` 会变负。钳一下把后果限制在「本次编辑落点不对」。
41
+ */
42
+ const clampCursor = () => {
43
+ const chars = graphemes(input);
44
+ return { chars, cp: Math.max(0, Math.min(cursor, chars.length)) };
45
+ };
46
+ const insertAtCursor = (text) => {
47
+ const { chars, cp } = clampCursor();
48
+ setInput(chars.slice(0, cp).join("") + text + chars.slice(cp).join(""));
49
+ setCursor(cp + graphemes(text).length);
50
+ };
51
+ const deleteBeforeCursor = () => {
52
+ const { chars, cp } = clampCursor();
53
+ if (cp === 0)
54
+ return;
55
+ setInput(chars.slice(0, cp - 1).join("") + chars.slice(cp).join(""));
56
+ setCursor(cp - 1);
57
+ };
58
+ const deleteAfterCursor = () => {
59
+ const { chars, cp } = clampCursor();
60
+ if (cp >= chars.length)
61
+ return;
62
+ setInput(chars.slice(0, cp).join("") + chars.slice(cp + 1).join(""));
63
+ };
64
+ /** 套用纯函数算好的「文本 + 光标」结果(无变化则不触发重渲染,也不进撤销栈) */
65
+ const applyEdit = (r) => {
66
+ if (r.text === input && r.cursor === cursor)
67
+ return;
68
+ undoStackRef.current = pushUndo(undoStackRef.current, { text: input, cursor });
69
+ setInput(r.text);
70
+ setCursor(r.cursor);
71
+ };
72
+ /**
73
+ * 用一段文本替换 `[start, end)`,光标落到插入文本末尾。
74
+ *
75
+ * 走 `applyEdit`(而不是 `setInput`)是必须的:`@` 补全会把半截路径整段替换掉,
76
+ * 补错了要能 `Ctrl+_` 退回原样。
77
+ */
78
+ const replaceRange = (start, end, text) => {
79
+ const { chars } = clampCursor();
80
+ const from = Math.max(0, Math.min(start, chars.length));
81
+ const to = Math.max(from, Math.min(end, chars.length));
82
+ applyEdit({
83
+ text: chars.slice(0, from).join("") + text + chars.slice(to).join(""),
84
+ cursor: from + graphemes(text).length,
85
+ });
86
+ };
87
+ /** 删除类编辑:额外把删掉的文本放进 kill ring(Ctrl+Y 可取回) */
88
+ const applyKill = (r) => {
89
+ if (r.text === input && r.cursor === cursor)
90
+ return;
91
+ killRingRef.current = pushKill(killRingRef.current, killedText(input, r.text));
92
+ yankIndexRef.current = -1;
93
+ applyEdit(r);
94
+ };
95
+ const yank = (advance) => {
96
+ const ring = killRingRef.current;
97
+ if (ring.length === 0)
98
+ return;
99
+ const next = advance ? yankIndexRef.current + 1 : 0;
100
+ // 只用 `killAt` 的 undefined 做越界守卫(环已到头),不再先判一遍 `next >= ring.length`
101
+ const text = killAt(ring, next);
102
+ if (text === undefined)
103
+ return;
104
+ yankIndexRef.current = next;
105
+ insertAtCursor(text);
106
+ };
107
+ const undoEdit = () => {
108
+ const popped = popUndo(undoStackRef.current);
109
+ if (!popped)
110
+ return;
111
+ undoStackRef.current = popped.rest;
112
+ setInput(popped.state.text);
113
+ setCursor(popped.state.cursor);
114
+ };
115
+ const toggleStash = () => {
116
+ if (input.length > 0) {
117
+ stashRef.current = { text: input, cursor };
118
+ setInputText("");
119
+ notify(t("notice.draftSaved"));
120
+ return;
121
+ }
122
+ const stashed = stashRef.current;
123
+ if (!stashed)
124
+ return;
125
+ stashRef.current = null;
126
+ setInput(stashed.text);
127
+ setCursor(stashed.cursor);
128
+ notify(t("notice.draftRestored"));
129
+ };
130
+ const moveCursor = (delta) => {
131
+ const len = graphemes(input).length;
132
+ setCursor((c) => Math.max(0, Math.min(len, c + delta)));
133
+ };
134
+ const moveCursorByWord = (dir) => {
135
+ setCursor(dir === -1 ? wordLeft(input, cursor) : wordRight(input, cursor));
136
+ };
137
+ const moveCursorToLineStart = () => {
138
+ const { chars, cp } = clampCursor();
139
+ let i = cp;
140
+ while (i > 0 && chars[i - 1] !== "\n")
141
+ i -= 1;
142
+ setCursor(i);
143
+ };
144
+ const moveCursorToLineEnd = () => {
145
+ const { chars, cp } = clampCursor();
146
+ let i = cp;
147
+ while (i < chars.length && chars[i] !== "\n")
148
+ i += 1;
149
+ setCursor(i);
150
+ };
151
+ /** 上下移一行:移得动就移并返回 true,已在边界则返回 false(交给历史) */
152
+ const moveCursorRowBy = (dir, width) => {
153
+ const next = moveCursorRow(input, cursor, width, dir);
154
+ if (next == null)
155
+ return false;
156
+ setCursor(next);
157
+ return true;
158
+ };
159
+ // 历史浏览:「上一条」从最新开始往回走,「下一条」走到底就回到空草稿。
160
+ // 上下两处按键(Ctrl+P/N 与 ↑/↓)共用这一对,不再各写一遍。
161
+ /** 把一条历史草稿放回输入区:文本 + 附件(`↑` 回到带图消息时图也跟着回来) */
162
+ const recall = (entry) => {
163
+ setInputText(entry.text);
164
+ restoreImages(entry.images);
165
+ };
166
+ const historyPrev = () => {
167
+ const entries = historySource();
168
+ if (entries.length === 0)
169
+ return;
170
+ const idx = historyIndex.current < 0 ? entries.length - 1 : Math.max(0, historyIndex.current - 1);
171
+ historyIndex.current = idx;
172
+ recall(entries[idx]);
173
+ };
174
+ const historyNext = () => {
175
+ if (historyIndex.current < 0)
176
+ return;
177
+ const entries = historySource();
178
+ const idx = historyIndex.current + 1;
179
+ if (idx >= entries.length) {
180
+ historyIndex.current = -1;
181
+ setInputText("");
182
+ restoreImages([]);
183
+ return;
184
+ }
185
+ historyIndex.current = idx;
186
+ recall(entries[idx]);
187
+ };
188
+ const clearDraft = () => {
189
+ setInput("");
190
+ setCursor(0);
191
+ historyIndex.current = -1;
192
+ };
193
+ return {
194
+ input,
195
+ cursor,
196
+ setInputText,
197
+ insertAtCursor,
198
+ replaceRange,
199
+ deleteBeforeCursor,
200
+ deleteAfterCursor,
201
+ deleteWordBeforeCursor: () => applyKill(deleteWordLeft(input, cursor)),
202
+ deleteWordAfterCursor: () => applyKill(deleteWordRight(input, cursor)),
203
+ deleteToStartOfLine: () => applyKill(deleteToLineStart(input, cursor)),
204
+ deleteToEndOfLine: () => applyKill(deleteToLineEnd(input, cursor)),
205
+ deletePrevWhitespace: () => applyKill(deleteToPrevWhitespace(input, cursor)),
206
+ yank,
207
+ undoEdit,
208
+ toggleStash,
209
+ moveCursor,
210
+ moveCursorToLineStart,
211
+ moveCursorToLineEnd,
212
+ moveCursorUpRow: (width) => moveCursorRowBy(-1, width),
213
+ moveCursorDownRow: (width) => moveCursorRowBy(1, width),
214
+ moveCursorByWord,
215
+ historyPrev,
216
+ historyNext,
217
+ clearDraft,
218
+ };
219
+ }
220
+ //# sourceMappingURL=use-input-editing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-input-editing.js","sourceRoot":"","sources":["../../../src/tui/screens/use-input-editing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type Dispatch, type SetStateAction } from "react";
2
+ import type { SelectItem } from "../components.js";
3
+ /** 确认框请求:`question` 上屏,用户作答后由 `resolve` 结算 */
4
+ export interface ConfirmState {
5
+ question: string;
6
+ resolve: (value: boolean) => void;
7
+ }
8
+ /** 选择器请求:`items` 上屏,用户选中 / 取消后由 `resolve` 结算(取消为 `null`) */
9
+ export interface PickerState {
10
+ title: string;
11
+ items: SelectItem<string>[];
12
+ resolve: (value: string | null) => void;
13
+ }
14
+ export interface ChatOverlays {
15
+ confirmState: ConfirmState | null;
16
+ pickerState: PickerState | null;
17
+ /** 命令层推送覆盖层用(`runCommand` / `chooseHandoffMode` 的入参类型) */
18
+ setConfirmState: Dispatch<SetStateAction<ConfirmState | null>>;
19
+ setPickerState: Dispatch<SetStateAction<PickerState | null>>;
20
+ /** 作答:结算 Promise 并关掉覆盖层(无覆盖层时为空操作) */
21
+ resolveConfirm: (value: boolean) => void;
22
+ resolvePicker: (value: string | null) => void;
23
+ }
24
+ export declare function useChatOverlays(): ChatOverlays;
25
+ //# sourceMappingURL=use-overlays.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-overlays.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/use-overlays.ts"],"names":[],"mappings":"AAWA,OAAO,EAAyB,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAClF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,8CAA8C;AAC9C,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACnC;AAED,4DAA4D;AAC5D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;IAC5B,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,0DAA0D;IAC1D,eAAe,EAAE,QAAQ,CAAC,cAAc,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC;IAC/D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC;IAC7D,sCAAsC;IACtC,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC/C;AAED,wBAAgB,eAAe,IAAI,YAAY,CAqB9C"}
@@ -0,0 +1,32 @@
1
+ // 覆盖层(确认框 / 选择器)—— 「弹一个、答一个、再关掉」的唯一实现
2
+ //
3
+ // 两种覆盖层共用同一套契约:调用方给一个 `resolve` 回调,拿到一个 Promise,
4
+ // **用户在覆盖层上作答后 Promise 才结算**。这正是命令处理器能写成
5
+ // `const ok = await confirm(...)` 的原因。
6
+ //
7
+ // 从 `chat.tsx` 抽出来的理由:这套 `resolve` 生命周期被埋在 God Component 里,
8
+ // 既没法单测(要从键盘打到命令层才能碰到),也容易被下一个人的 `setState` 写出
9
+ // 「先清状态、后调 resolve」的竞态。抽出来后:
10
+ // · 关状态与调 resolve 在**同一次**函数式更新里完成,不会读到过期状态;
11
+ // · 已经是 `null` 时重复 resolve 是安全空操作(Esc 连按不会炸)。
12
+ import { useCallback, useState } from "react";
13
+ export function useChatOverlays() {
14
+ const [confirmState, setConfirmState] = useState(null);
15
+ const [pickerState, setPickerState] = useState(null);
16
+ // 用函数式更新而不是闭包里的 `confirmState`:连按两下 Esc / 两个键同一帧到达时,
17
+ // 第二次更新仍能看到「已被第一次清掉」的真实状态,不会重复 resolve。
18
+ const resolveConfirm = useCallback((value) => {
19
+ setConfirmState((cs) => {
20
+ cs?.resolve(value);
21
+ return null;
22
+ });
23
+ }, []);
24
+ const resolvePicker = useCallback((value) => {
25
+ setPickerState((ps) => {
26
+ ps?.resolve(value);
27
+ return null;
28
+ });
29
+ }, []);
30
+ return { confirmState, pickerState, setConfirmState, setPickerState, resolveConfirm, resolvePicker };
31
+ }
32
+ //# sourceMappingURL=use-overlays.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-overlays.js","sourceRoot":"","sources":["../../../src/tui/screens/use-overlays.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,iDAAiD;AACjD,yCAAyC;AACzC,uCAAuC;AACvC,EAAE;AACF,4DAA4D;AAC5D,+CAA+C;AAC/C,6BAA6B;AAC7B,+CAA+C;AAC/C,gDAAgD;AAChD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAsC,MAAM,OAAO,CAAC;AA2BlF,MAAM,UAAU,eAAe;IAC7B,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAsB,IAAI,CAAC,CAAC;IAC5E,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC,CAAC;IAEzE,qDAAqD;IACrD,wCAAwC;IACxC,MAAM,cAAc,GAAG,WAAW,CAAC,CAAC,KAAc,EAAE,EAAE;QACpD,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE;YACrB,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,KAAoB,EAAE,EAAE;QACzD,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE;YACpB,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC;AACvG,CAAC"}
@@ -0,0 +1,46 @@
1
+ import type { AppConfig, ReasoningPresets } from "@ai-zen/agents-sdk";
2
+ import { type McpReadResult, type McpScope } from "../../config.js";
3
+ import { type AgentStore } from "../../agents-store.js";
4
+ import type { McpSnapshot, WizardCloseResult, WizardStep } from "../config-wizard/index.js";
5
+ import type { Notice } from "./notice.js";
6
+ export interface WizardHostDeps {
7
+ /** 当前模型 id:`/key` 直达它所用端点的密钥;也是「当前端点是否被改动」的比较基准 */
8
+ modelId: string;
9
+ /** 通知出口(读写失败、变更摘要都从这里出去,不进食转录) */
10
+ notify: (text: string, tone?: Notice["tone"]) => void;
11
+ /** 会话是否已建好(未建好时改配置只能重启) */
12
+ hasSession: () => boolean;
13
+ /** 会话还没建好就改了配置 → 只能重启进程让新配置生效 */
14
+ restart: () => void;
15
+ /** 改了当前端点 / MCP / Agent 定义 / 中断策略 → 重载会话(消息保留) */
16
+ reloadSession: () => void;
17
+ /**
18
+ * 快照读取器。缺省用真实实现;测试注入假实现即可,**不必** `vi.mock` 整个 config 模块
19
+ * ——模块级替换在进程内共享模块时会泄漏到其他测试文件。
20
+ */
21
+ readers?: {
22
+ readConfig: () => Promise<AppConfig>;
23
+ readMcpConfig: (scope: McpScope) => Promise<McpReadResult>;
24
+ readReasoningPresets: () => Promise<ReasoningPresets>;
25
+ readAgentStore: () => Promise<AgentStore>;
26
+ };
27
+ }
28
+ export interface WizardHost {
29
+ wizardStep: WizardStep | null;
30
+ wizardConfig: AppConfig | null;
31
+ wizardPresets: ReasoningPresets;
32
+ wizardAgents: {
33
+ id: string;
34
+ name: string;
35
+ }[];
36
+ wizardMcp: McpSnapshot | null;
37
+ wizardAgentStore: AgentStore | null;
38
+ /** 打开向导:先读齐快照再接管整屏(读失败则只报错、不进向导) */
39
+ openWizard: (step: WizardStep) => Promise<void>;
40
+ /** `/key`:直达当前模型所用端点的 API Key 编辑步骤 */
41
+ openKeyEditor: () => Promise<void>;
42
+ /** 向导关闭:渲染变更摘要,并让改动生效 */
43
+ closeWizard: (result: WizardCloseResult) => void;
44
+ }
45
+ export declare function useWizardHost({ modelId, notify, hasSession, restart, reloadSession, readers: injected, }: WizardHostDeps): WizardHost;
46
+ //# sourceMappingURL=use-wizard-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-wizard-host.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/use-wizard-host.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAqE,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACvI,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExE,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IACtD,2BAA2B;IAC3B,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,iCAAiC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,kDAAkD;IAClD,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B;;;OAGG;IACH,OAAO,CAAC,EAAE;QACR,UAAU,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;QACrC,aAAa,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;QAC3D,oBAAoB,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACtD,cAAc,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;KAC3C,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,gBAAgB,CAAC;IAChC,YAAY,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7C,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,UAAU,GAAG,IAAI,CAAC;IACpC,oCAAoC;IACpC,UAAU,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,sCAAsC;IACtC,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,yBAAyB;IACzB,WAAW,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAClD;AAED,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,MAAM,EACN,UAAU,EACV,OAAO,EACP,aAAa,EACb,OAAO,EAAE,QAAQ,GAClB,EAAE,cAAc,GAAG,UAAU,CA6G7B"}
@@ -0,0 +1,123 @@
1
+ // 配置向导宿主 —— 「打开向导 / 读齐快照 / 关闭后让改动生效」的唯一实现
2
+ //
3
+ // 从 `chat.tsx` 抽出来的理由:向导本身(`config-wizard/`)是独立状态机,但**宿主**
4
+ // 的活儿散落在对话屏里 —— 6 个 `useState`、3 个入口函数,还要顺手记「当前模型用的是
5
+ // 哪个端点」以便关闭时判断要不要重建会话。这些既不属于「对话」,也没法单测(要一路
6
+ // 从键盘打到向导关闭才能碰到)。
7
+ //
8
+ // 依赖方向是**注入**而非 import 会话:宿主要做的事(通知、重启、重载会话)都通过
9
+ // `WizardHostDeps` 传进来,于是 hook 可以在测试里用假依赖跑完整生命周期。
10
+ import { useRef, useState } from "react";
11
+ import { mcpConfigOrEmpty, readConfig, readMcpConfig, readReasoningPresets } from "../../config.js";
12
+ import { readAgentStore } from "../../agents-store.js";
13
+ import { resolveCredential } from "../../config-editor.js";
14
+ import { t } from "../../i18n/index.js";
15
+ export function useWizardHost({ modelId, notify, hasSession, restart, reloadSession, readers: injected, }) {
16
+ const readers = {
17
+ readConfig,
18
+ readMcpConfig,
19
+ readReasoningPresets,
20
+ readAgentStore,
21
+ ...injected,
22
+ };
23
+ const [wizardStep, setWizardStep] = useState(null);
24
+ const [wizardConfig, setWizardConfig] = useState(null);
25
+ const [wizardPresets, setWizardPresets] = useState({});
26
+ const [wizardAgents, setWizardAgents] = useState([]);
27
+ const [wizardMcp, setWizardMcp] = useState(null);
28
+ const [wizardAgentStore, setWizardAgentStore] = useState(null);
29
+ /**
30
+ * 打开向导时当前模型所用的端点 id —— 关闭时据此判断「当前端点有没有被改」。
31
+ *
32
+ * 用 ref 而不是 state:它只在 `openWizard` / `closeWizard` 之间传递,不上屏,
33
+ * 放 state 会多一次无意义渲染。
34
+ */
35
+ const currentEndpointRef = useRef(null);
36
+ const openWizard = async (step) => {
37
+ try {
38
+ const config = await readers.readConfig();
39
+ currentEndpointRef.current = resolveCredential(config, modelId)?.endpointId ?? null;
40
+ const agentStore = await readers.readAgentStore();
41
+ setWizardConfig(config);
42
+ setWizardPresets(await readers.readReasoningPresets());
43
+ setWizardAgents(agentStore.agents.map((agent) => ({ id: agent.id, name: agent.name || agent.id })));
44
+ setWizardAgentStore(agentStore);
45
+ // 坏文件照样进屏(屏上写明),只把失败原因随之带过去
46
+ const globalMcp = await readers.readMcpConfig("global");
47
+ const projectMcp = await readers.readMcpConfig("project");
48
+ const errors = {};
49
+ if (!globalMcp.ok)
50
+ errors.global = globalMcp.error;
51
+ if (!projectMcp.ok)
52
+ errors.project = projectMcp.error;
53
+ setWizardMcp({
54
+ global: mcpConfigOrEmpty(globalMcp),
55
+ project: mcpConfigOrEmpty(projectMcp),
56
+ ...(Object.keys(errors).length ? { errors } : {}),
57
+ });
58
+ setWizardStep(step);
59
+ }
60
+ catch (error) {
61
+ notify(t("chat.configReadFailed", { error: error?.message ?? error }), "error");
62
+ }
63
+ };
64
+ const openKeyEditor = async () => {
65
+ try {
66
+ const config = await readers.readConfig();
67
+ const credential = resolveCredential(config, modelId);
68
+ if (!credential) {
69
+ notify(t("chat.modelNoEndpoint", { id: modelId }), "error");
70
+ return;
71
+ }
72
+ currentEndpointRef.current = credential.endpointId;
73
+ setWizardConfig(config);
74
+ setWizardStep({ kind: "edit", field: "apiKey", endpointId: credential.endpointId });
75
+ }
76
+ catch (error) {
77
+ notify(t("chat.configReadFailed", { error: error?.message ?? error }), "error");
78
+ }
79
+ };
80
+ /** 向导关闭:渲染变更摘要;若改到当前端点 / MCP / Agent 定义则重建会话(消息保留) */
81
+ const closeWizard = (result) => {
82
+ setWizardStep(null);
83
+ setWizardConfig(null);
84
+ setWizardMcp(null);
85
+ setWizardAgentStore(null);
86
+ // 同一批摘要合成**一条**(多行):既能全部显示,又只占通知队列的一个槽位。
87
+ // 逐条 push 在单槽时代只剩最后一条,在队列时代则会挤掉更早的进度提示。
88
+ const { summary } = result;
89
+ if (summary.length === 1) {
90
+ notify(t("chat.configUpdated", { line: summary[0] }));
91
+ }
92
+ else if (summary.length > 1) {
93
+ // 子项缩进 = 一个汉字宽度(两个半角空格),不加 `·` 之类的项目符号:
94
+ // 通知正文本身就左对齐于行首,子项只需要一点层级差,符号是多余装饰。
95
+ notify(t("chat.configUpdatedMulti", { lines: summary.map((line) => ` ${line}`).join("\n") }));
96
+ }
97
+ if (!result.dirty)
98
+ return;
99
+ // 会话都没建好 → 只能重启让新配置生效。
100
+ if (!hasSession()) {
101
+ restart();
102
+ return;
103
+ }
104
+ // 只有「当前端点 / MCP / Agent 定义 / 建 Agent 时才读的配置(中断策略)」变了
105
+ // 才需要重建会话;改的是别的模型、别的端点的参数,当前会话不受影响,不该白重连一次。
106
+ const endpointChanged = !!currentEndpointRef.current && result.changedEndpointIds.includes(currentEndpointRef.current);
107
+ if (endpointChanged || result.mcpChanged || result.agentsChanged || result.sessionOptionsChanged) {
108
+ reloadSession();
109
+ }
110
+ };
111
+ return {
112
+ wizardStep,
113
+ wizardConfig,
114
+ wizardPresets,
115
+ wizardAgents,
116
+ wizardMcp,
117
+ wizardAgentStore,
118
+ openWizard,
119
+ openKeyEditor,
120
+ closeWizard,
121
+ };
122
+ }
123
+ //# sourceMappingURL=use-wizard-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-wizard-host.js","sourceRoot":"","sources":["../../../src/tui/screens/use-wizard-host.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type RLine } from "./lines.js";
2
+ /**
3
+ * 品牌区各行 —— 纯函数,不依赖 Ink(渲染交给 `LineView`)。
4
+ *
5
+ * 宽度取 `pickLogo()` 的判据:能放下宽版 6 行 logo 就用宽版,否则退化成单行
6
+ * `◢ AI · ZEN ◣`。整块按终端宽度居中。所有行都带 `spans`(颜色逐段给),
7
+ * 因此 `kind` 只取中性的 `content`。
8
+ */
9
+ export declare function welcomeLines({ columns }: {
10
+ columns: number;
11
+ }): RLine[];
12
+ //# sourceMappingURL=welcome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"welcome.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/welcome.ts"],"names":[],"mappings":"AASA,OAAO,EAAY,KAAK,KAAK,EAAa,MAAM,YAAY,CAAC;AAE7D;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,KAAK,EAAE,CAmBtE"}
@@ -0,0 +1,36 @@
1
+ // 欢迎块 —— 空对话时对话区顶部的品牌区(logo + 标语 + 版本)
2
+ //
3
+ // 这一块曾经是启动时的全屏开屏动画(splash):显现 + 扫光 + 停 1.1s 才进对话,
4
+ // 每次启动强阻塞约 1.8s。现在改为**对话区的普通内容**:不阻塞、随消息自然上滚、
5
+ // 滚回来还能看到。渐变相位固定为 0(静态),不持有任何定时器。
6
+ import { CLI_VERSION, CORE_VERSION, SDK_VERSION } from "../../version.js";
7
+ import { t } from "../../i18n/index.js";
8
+ import { displayWidth } from "../text.js";
9
+ import { logoGradientColors, pickLogo, theme } from "../theme.js";
10
+ import { spanLine } from "./lines.js";
11
+ /**
12
+ * 品牌区各行 —— 纯函数,不依赖 Ink(渲染交给 `LineView`)。
13
+ *
14
+ * 宽度取 `pickLogo()` 的判据:能放下宽版 6 行 logo 就用宽版,否则退化成单行
15
+ * `◢ AI · ZEN ◣`。整块按终端宽度居中。所有行都带 `spans`(颜色逐段给),
16
+ * 因此 `kind` 只取中性的 `content`。
17
+ */
18
+ export function welcomeLines({ columns }) {
19
+ const logo = pickLogo(columns);
20
+ const colors = logoGradientColors(logo, 0);
21
+ const tagline = t("welcome.tagline");
22
+ const versions = `v${CLI_VERSION} · sdk ${SDK_VERSION} · core ${CORE_VERSION}`;
23
+ /** 逐行居中(不按最宽行对齐 —— 否则 logo 会因版本行更长而看起来偏左) */
24
+ const center = (text) => " ".repeat(Math.max(0, Math.floor((columns - displayWidth(text)) / 2)));
25
+ const lines = logo.map((line, i) => {
26
+ const spans = [{ text: center(line) }];
27
+ for (const [x, ch] of [...line].entries())
28
+ spans.push({ text: ch, color: colors[i]?.[x] });
29
+ return spanLine(`welcome-logo-${i}`, "content", spans);
30
+ });
31
+ lines.push({ key: "welcome-gap", kind: "gap", text: "" });
32
+ lines.push(spanLine("welcome-tagline", "content", [{ text: center(tagline) }, { text: tagline, color: theme.accent }]));
33
+ lines.push(spanLine("welcome-versions", "content", [{ text: center(versions) }, { text: versions, color: theme.dim }]));
34
+ return lines;
35
+ }
36
+ //# sourceMappingURL=welcome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"welcome.js","sourceRoot":"","sources":["../../../src/tui/screens/welcome.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,EAAE;AACF,kDAAkD;AAClD,8CAA8C;AAC9C,kCAAkC;AAClC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAyB,MAAM,YAAY,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAAuB;IAC3D,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,IAAI,WAAW,UAAU,WAAW,WAAW,YAAY,EAAE,CAAC;IAE/E,6CAA6C;IAC7C,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzG,MAAM,KAAK,GAAY,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAW,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/C,KAAK,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3F,OAAO,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1D,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACxH,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,kBAAkB,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IACxH,OAAO,KAAK,CAAC;AACf,CAAC"}