@ai-zen/cli 0.9.0 → 1.0.0-alpha.10

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 (314) hide show
  1. package/CHANGELOG.md +199 -1
  2. package/README.md +115 -62
  3. package/README.zh.md +115 -62
  4. package/dist/agent-creator.d.ts +18 -1
  5. package/dist/agent-creator.d.ts.map +1 -1
  6. package/dist/agent-creator.js +36 -12
  7. package/dist/agent-creator.js.map +1 -1
  8. package/dist/agents-store.d.ts +33 -0
  9. package/dist/agents-store.d.ts.map +1 -0
  10. package/dist/agents-store.js +50 -0
  11. package/dist/agents-store.js.map +1 -0
  12. package/dist/auto-migrate-confirm.d.ts +43 -0
  13. package/dist/auto-migrate-confirm.d.ts.map +1 -0
  14. package/dist/auto-migrate-confirm.js +46 -0
  15. package/dist/auto-migrate-confirm.js.map +1 -0
  16. package/dist/config-editor.d.ts +201 -0
  17. package/dist/config-editor.d.ts.map +1 -0
  18. package/dist/config-editor.js +511 -0
  19. package/dist/config-editor.js.map +1 -0
  20. package/dist/config.d.ts +55 -16
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/config.js +46 -29
  23. package/dist/config.js.map +1 -1
  24. package/dist/conversation-commands/registry.d.ts +4 -5
  25. package/dist/conversation-commands/registry.d.ts.map +1 -1
  26. package/dist/conversation-commands/registry.js +11 -7
  27. package/dist/conversation-commands/registry.js.map +1 -1
  28. package/dist/conversation-persist-plugin.d.ts +25 -0
  29. package/dist/conversation-persist-plugin.d.ts.map +1 -0
  30. package/dist/conversation-persist-plugin.js +44 -0
  31. package/dist/conversation-persist-plugin.js.map +1 -0
  32. package/dist/conversation-repository.d.ts +19 -2
  33. package/dist/conversation-repository.d.ts.map +1 -1
  34. package/dist/conversation-repository.js +48 -5
  35. package/dist/conversation-repository.js.map +1 -1
  36. package/dist/format-time.d.ts +2 -2
  37. package/dist/format-time.js +2 -2
  38. package/dist/handoff-service.d.ts +19 -0
  39. package/dist/handoff-service.d.ts.map +1 -0
  40. package/dist/handoff-service.js +87 -0
  41. package/dist/handoff-service.js.map +1 -0
  42. package/dist/hook.d.ts.map +1 -1
  43. package/dist/hook.js +58 -46
  44. package/dist/hook.js.map +1 -1
  45. package/dist/index.js +82 -35
  46. package/dist/index.js.map +1 -1
  47. package/dist/mode.d.ts +56 -0
  48. package/dist/mode.d.ts.map +1 -0
  49. package/dist/mode.js +83 -0
  50. package/dist/mode.js.map +1 -0
  51. package/dist/session-pointer.d.ts +35 -0
  52. package/dist/session-pointer.d.ts.map +1 -0
  53. package/dist/session-pointer.js +81 -0
  54. package/dist/session-pointer.js.map +1 -0
  55. package/dist/stdio-runner.d.ts +34 -0
  56. package/dist/stdio-runner.d.ts.map +1 -0
  57. package/dist/stdio-runner.js +161 -0
  58. package/dist/stdio-runner.js.map +1 -0
  59. package/dist/tui/chat-session.d.ts +106 -0
  60. package/dist/tui/chat-session.d.ts.map +1 -0
  61. package/dist/tui/chat-session.js +299 -0
  62. package/dist/tui/chat-session.js.map +1 -0
  63. package/dist/tui/components.d.ts +47 -0
  64. package/dist/tui/components.d.ts.map +1 -0
  65. package/dist/tui/components.js +62 -0
  66. package/dist/tui/components.js.map +1 -0
  67. package/dist/tui/config-wizard/detail.d.ts +51 -0
  68. package/dist/tui/config-wizard/detail.d.ts.map +1 -0
  69. package/dist/tui/config-wizard/detail.js +273 -0
  70. package/dist/tui/config-wizard/detail.js.map +1 -0
  71. package/dist/tui/config-wizard/engine.d.ts +36 -0
  72. package/dist/tui/config-wizard/engine.d.ts.map +1 -0
  73. package/dist/tui/config-wizard/engine.js +187 -0
  74. package/dist/tui/config-wizard/engine.js.map +1 -0
  75. package/dist/tui/config-wizard/fields.d.ts +24 -0
  76. package/dist/tui/config-wizard/fields.d.ts.map +1 -0
  77. package/dist/tui/config-wizard/fields.js +411 -0
  78. package/dist/tui/config-wizard/fields.js.map +1 -0
  79. package/dist/tui/config-wizard/frame.d.ts +27 -0
  80. package/dist/tui/config-wizard/frame.d.ts.map +1 -0
  81. package/dist/tui/config-wizard/frame.js +28 -0
  82. package/dist/tui/config-wizard/frame.js.map +1 -0
  83. package/dist/tui/config-wizard/index.d.ts +6 -0
  84. package/dist/tui/config-wizard/index.d.ts.map +1 -0
  85. package/dist/tui/config-wizard/index.js +7 -0
  86. package/dist/tui/config-wizard/index.js.map +1 -0
  87. package/dist/tui/config-wizard/kv-editor.d.ts +18 -0
  88. package/dist/tui/config-wizard/kv-editor.d.ts.map +1 -0
  89. package/dist/tui/config-wizard/kv-editor.js +116 -0
  90. package/dist/tui/config-wizard/kv-editor.js.map +1 -0
  91. package/dist/tui/config-wizard/list.d.ts +13 -0
  92. package/dist/tui/config-wizard/list.d.ts.map +1 -0
  93. package/dist/tui/config-wizard/list.js +29 -0
  94. package/dist/tui/config-wizard/list.js.map +1 -0
  95. package/dist/tui/config-wizard/mcp-helpers.d.ts +9 -0
  96. package/dist/tui/config-wizard/mcp-helpers.d.ts.map +1 -0
  97. package/dist/tui/config-wizard/mcp-helpers.js +19 -0
  98. package/dist/tui/config-wizard/mcp-helpers.js.map +1 -0
  99. package/dist/tui/config-wizard/menu.d.ts +18 -0
  100. package/dist/tui/config-wizard/menu.d.ts.map +1 -0
  101. package/dist/tui/config-wizard/menu.js +70 -0
  102. package/dist/tui/config-wizard/menu.js.map +1 -0
  103. package/dist/tui/config-wizard/prompt-editor.d.ts +24 -0
  104. package/dist/tui/config-wizard/prompt-editor.d.ts.map +1 -0
  105. package/dist/tui/config-wizard/prompt-editor.js +83 -0
  106. package/dist/tui/config-wizard/prompt-editor.js.map +1 -0
  107. package/dist/tui/config-wizard/prompt.d.ts +57 -0
  108. package/dist/tui/config-wizard/prompt.d.ts.map +1 -0
  109. package/dist/tui/config-wizard/prompt.js +130 -0
  110. package/dist/tui/config-wizard/prompt.js.map +1 -0
  111. package/dist/tui/config-wizard/step-agents.d.ts +4 -0
  112. package/dist/tui/config-wizard/step-agents.d.ts.map +1 -0
  113. package/dist/tui/config-wizard/step-agents.js +110 -0
  114. package/dist/tui/config-wizard/step-agents.js.map +1 -0
  115. package/dist/tui/config-wizard/step-defaults.d.ts +4 -0
  116. package/dist/tui/config-wizard/step-defaults.d.ts.map +1 -0
  117. package/dist/tui/config-wizard/step-defaults.js +76 -0
  118. package/dist/tui/config-wizard/step-defaults.js.map +1 -0
  119. package/dist/tui/config-wizard/step-endpoints.d.ts +4 -0
  120. package/dist/tui/config-wizard/step-endpoints.d.ts.map +1 -0
  121. package/dist/tui/config-wizard/step-endpoints.js +43 -0
  122. package/dist/tui/config-wizard/step-endpoints.js.map +1 -0
  123. package/dist/tui/config-wizard/step-mcp.d.ts +4 -0
  124. package/dist/tui/config-wizard/step-mcp.d.ts.map +1 -0
  125. package/dist/tui/config-wizard/step-mcp.js +97 -0
  126. package/dist/tui/config-wizard/step-mcp.js.map +1 -0
  127. package/dist/tui/config-wizard/step-menu.d.ts +4 -0
  128. package/dist/tui/config-wizard/step-menu.d.ts.map +1 -0
  129. package/dist/tui/config-wizard/step-menu.js +28 -0
  130. package/dist/tui/config-wizard/step-menu.js.map +1 -0
  131. package/dist/tui/config-wizard/step-models.d.ts +4 -0
  132. package/dist/tui/config-wizard/step-models.d.ts.map +1 -0
  133. package/dist/tui/config-wizard/step-models.js +114 -0
  134. package/dist/tui/config-wizard/step-models.js.map +1 -0
  135. package/dist/tui/config-wizard/step-new-endpoint.d.ts +4 -0
  136. package/dist/tui/config-wizard/step-new-endpoint.d.ts.map +1 -0
  137. package/dist/tui/config-wizard/step-new-endpoint.js +54 -0
  138. package/dist/tui/config-wizard/step-new-endpoint.js.map +1 -0
  139. package/dist/tui/config-wizard/step-simple.d.ts +4 -0
  140. package/dist/tui/config-wizard/step-simple.d.ts.map +1 -0
  141. package/dist/tui/config-wizard/step-simple.js +55 -0
  142. package/dist/tui/config-wizard/step-simple.js.map +1 -0
  143. package/dist/tui/config-wizard/types.d.ts +147 -0
  144. package/dist/tui/config-wizard/types.d.ts.map +1 -0
  145. package/dist/tui/config-wizard/types.js +12 -0
  146. package/dist/tui/config-wizard/types.js.map +1 -0
  147. package/dist/tui/config-wizard/wizard.d.ts +9 -0
  148. package/dist/tui/config-wizard/wizard.d.ts.map +1 -0
  149. package/dist/tui/config-wizard/wizard.js +34 -0
  150. package/dist/tui/config-wizard/wizard.js.map +1 -0
  151. package/dist/tui/highlight.d.ts +35 -0
  152. package/dist/tui/highlight.d.ts.map +1 -0
  153. package/dist/tui/highlight.js +117 -0
  154. package/dist/tui/highlight.js.map +1 -0
  155. package/dist/tui/index.d.ts +34 -0
  156. package/dist/tui/index.d.ts.map +1 -0
  157. package/dist/tui/index.js +265 -0
  158. package/dist/tui/index.js.map +1 -0
  159. package/dist/tui/screens/chat-commands.d.ts +35 -0
  160. package/dist/tui/screens/chat-commands.d.ts.map +1 -0
  161. package/dist/tui/screens/chat-commands.js +214 -0
  162. package/dist/tui/screens/chat-commands.js.map +1 -0
  163. package/dist/tui/screens/chat.d.ts +21 -0
  164. package/dist/tui/screens/chat.d.ts.map +1 -0
  165. package/dist/tui/screens/chat.js +563 -0
  166. package/dist/tui/screens/chat.js.map +1 -0
  167. package/dist/tui/screens/frame-buffer.d.ts +47 -0
  168. package/dist/tui/screens/frame-buffer.d.ts.map +1 -0
  169. package/dist/tui/screens/frame-buffer.js +78 -0
  170. package/dist/tui/screens/frame-buffer.js.map +1 -0
  171. package/dist/tui/screens/index.d.ts +13 -0
  172. package/dist/tui/screens/index.d.ts.map +1 -0
  173. package/dist/tui/screens/index.js +14 -0
  174. package/dist/tui/screens/index.js.map +1 -0
  175. package/dist/tui/screens/input.d.ts +29 -0
  176. package/dist/tui/screens/input.d.ts.map +1 -0
  177. package/dist/tui/screens/input.js +54 -0
  178. package/dist/tui/screens/input.js.map +1 -0
  179. package/dist/tui/screens/layout.d.ts +44 -0
  180. package/dist/tui/screens/layout.d.ts.map +1 -0
  181. package/dist/tui/screens/layout.js +40 -0
  182. package/dist/tui/screens/layout.js.map +1 -0
  183. package/dist/tui/screens/lines.d.ts +42 -0
  184. package/dist/tui/screens/lines.d.ts.map +1 -0
  185. package/dist/tui/screens/lines.js +190 -0
  186. package/dist/tui/screens/lines.js.map +1 -0
  187. package/dist/tui/screens/messages-view.d.ts +10 -0
  188. package/dist/tui/screens/messages-view.d.ts.map +1 -0
  189. package/dist/tui/screens/messages-view.js +115 -0
  190. package/dist/tui/screens/messages-view.js.map +1 -0
  191. package/dist/tui/screens/notice.d.ts +32 -0
  192. package/dist/tui/screens/notice.d.ts.map +1 -0
  193. package/dist/tui/screens/notice.js +46 -0
  194. package/dist/tui/screens/notice.js.map +1 -0
  195. package/dist/tui/screens/overlays.d.ts +12 -0
  196. package/dist/tui/screens/overlays.d.ts.map +1 -0
  197. package/dist/tui/screens/overlays.js +34 -0
  198. package/dist/tui/screens/overlays.js.map +1 -0
  199. package/dist/tui/screens/render.d.ts +7 -0
  200. package/dist/tui/screens/render.d.ts.map +1 -0
  201. package/dist/tui/screens/render.js +61 -0
  202. package/dist/tui/screens/render.js.map +1 -0
  203. package/dist/tui/screens/splash.d.ts +5 -0
  204. package/dist/tui/screens/splash.d.ts.map +1 -0
  205. package/dist/tui/screens/splash.js +51 -0
  206. package/dist/tui/screens/splash.js.map +1 -0
  207. package/dist/tui/text.d.ts +76 -0
  208. package/dist/tui/text.d.ts.map +1 -0
  209. package/dist/tui/text.js +198 -0
  210. package/dist/tui/text.js.map +1 -0
  211. package/dist/tui/theme.d.ts +68 -0
  212. package/dist/tui/theme.d.ts.map +1 -0
  213. package/dist/tui/theme.js +132 -0
  214. package/dist/tui/theme.js.map +1 -0
  215. package/dist/types.d.ts +7 -5
  216. package/dist/types.d.ts.map +1 -1
  217. package/dist/types.js +1 -1
  218. package/package.json +12 -7
  219. package/dist/auto-migrate-confirm-plugin.d.ts +0 -58
  220. package/dist/auto-migrate-confirm-plugin.d.ts.map +0 -1
  221. package/dist/auto-migrate-confirm-plugin.js +0 -79
  222. package/dist/auto-migrate-confirm-plugin.js.map +0 -1
  223. package/dist/config-wizard.d.ts +0 -6
  224. package/dist/config-wizard.d.ts.map +0 -1
  225. package/dist/config-wizard.js +0 -46
  226. package/dist/config-wizard.js.map +0 -1
  227. package/dist/conversation-commands/back.d.ts +0 -3
  228. package/dist/conversation-commands/back.d.ts.map +0 -1
  229. package/dist/conversation-commands/back.js +0 -144
  230. package/dist/conversation-commands/back.js.map +0 -1
  231. package/dist/conversation-commands/clear.d.ts +0 -3
  232. package/dist/conversation-commands/clear.d.ts.map +0 -1
  233. package/dist/conversation-commands/clear.js +0 -8
  234. package/dist/conversation-commands/clear.js.map +0 -1
  235. package/dist/conversation-commands/editor.d.ts +0 -3
  236. package/dist/conversation-commands/editor.d.ts.map +0 -1
  237. package/dist/conversation-commands/editor.js +0 -15
  238. package/dist/conversation-commands/editor.js.map +0 -1
  239. package/dist/conversation-commands/exit.d.ts +0 -3
  240. package/dist/conversation-commands/exit.d.ts.map +0 -1
  241. package/dist/conversation-commands/exit.js +0 -37
  242. package/dist/conversation-commands/exit.js.map +0 -1
  243. package/dist/conversation-commands/help.d.ts +0 -3
  244. package/dist/conversation-commands/help.d.ts.map +0 -1
  245. package/dist/conversation-commands/help.js +0 -10
  246. package/dist/conversation-commands/help.js.map +0 -1
  247. package/dist/conversation-commands/index.d.ts +0 -13
  248. package/dist/conversation-commands/index.d.ts.map +0 -1
  249. package/dist/conversation-commands/index.js +0 -66
  250. package/dist/conversation-commands/index.js.map +0 -1
  251. package/dist/conversation-commands/migrate.d.ts +0 -12
  252. package/dist/conversation-commands/migrate.d.ts.map +0 -1
  253. package/dist/conversation-commands/migrate.js +0 -56
  254. package/dist/conversation-commands/migrate.js.map +0 -1
  255. package/dist/conversation-commands/new.d.ts +0 -3
  256. package/dist/conversation-commands/new.d.ts.map +0 -1
  257. package/dist/conversation-commands/new.js +0 -45
  258. package/dist/conversation-commands/new.js.map +0 -1
  259. package/dist/conversation-commands/save.d.ts +0 -3
  260. package/dist/conversation-commands/save.d.ts.map +0 -1
  261. package/dist/conversation-commands/save.js +0 -32
  262. package/dist/conversation-commands/save.js.map +0 -1
  263. package/dist/conversation-runner.d.ts +0 -17
  264. package/dist/conversation-runner.d.ts.map +0 -1
  265. package/dist/conversation-runner.js +0 -176
  266. package/dist/conversation-runner.js.map +0 -1
  267. package/dist/delta-renderer.d.ts +0 -33
  268. package/dist/delta-renderer.d.ts.map +0 -1
  269. package/dist/delta-renderer.js +0 -120
  270. package/dist/delta-renderer.js.map +0 -1
  271. package/dist/draft-plugin.d.ts +0 -19
  272. package/dist/draft-plugin.d.ts.map +0 -1
  273. package/dist/draft-plugin.js +0 -30
  274. package/dist/draft-plugin.js.map +0 -1
  275. package/dist/draft-repository.d.ts +0 -34
  276. package/dist/draft-repository.d.ts.map +0 -1
  277. package/dist/draft-repository.js +0 -64
  278. package/dist/draft-repository.js.map +0 -1
  279. package/dist/menus/agents.d.ts +0 -5
  280. package/dist/menus/agents.d.ts.map +0 -1
  281. package/dist/menus/agents.js +0 -219
  282. package/dist/menus/agents.js.map +0 -1
  283. package/dist/menus/common.d.ts +0 -41
  284. package/dist/menus/common.d.ts.map +0 -1
  285. package/dist/menus/common.js +0 -104
  286. package/dist/menus/common.js.map +0 -1
  287. package/dist/menus/config-display.d.ts +0 -2
  288. package/dist/menus/config-display.d.ts.map +0 -1
  289. package/dist/menus/config-display.js +0 -82
  290. package/dist/menus/config-display.js.map +0 -1
  291. package/dist/menus/config.d.ts +0 -8
  292. package/dist/menus/config.d.ts.map +0 -1
  293. package/dist/menus/config.js +0 -407
  294. package/dist/menus/config.js.map +0 -1
  295. package/dist/menus/conversations.d.ts +0 -20
  296. package/dist/menus/conversations.d.ts.map +0 -1
  297. package/dist/menus/conversations.js +0 -83
  298. package/dist/menus/conversations.js.map +0 -1
  299. package/dist/menus/index.d.ts +0 -5
  300. package/dist/menus/index.d.ts.map +0 -1
  301. package/dist/menus/index.js +0 -59
  302. package/dist/menus/index.js.map +0 -1
  303. package/dist/menus/start-conversation.d.ts +0 -16
  304. package/dist/menus/start-conversation.d.ts.map +0 -1
  305. package/dist/menus/start-conversation.js +0 -176
  306. package/dist/menus/start-conversation.js.map +0 -1
  307. package/dist/migration-service.d.ts +0 -13
  308. package/dist/migration-service.d.ts.map +0 -1
  309. package/dist/migration-service.js +0 -56
  310. package/dist/migration-service.js.map +0 -1
  311. package/dist/slash-hint-prompt.d.ts +0 -41
  312. package/dist/slash-hint-prompt.d.ts.map +0 -1
  313. package/dist/slash-hint-prompt.js +0 -92
  314. package/dist/slash-hint-prompt.js.map +0 -1
package/README.zh.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @ai-zen/cli
2
2
 
3
- AI Agent 命令行界面,基于 `@ai-zen/agents-sdk` 和 `@ai-zen/agents-core` 构建。提供交互式对话终端,内置文件系统操作工具,支持 MCP 协议集成外部工具、子 Agent 编排和 Skill 管理。
3
+ AI Agent 命令行界面,基于 `@ai-zen/agents-sdk` 和 `@ai-zen/agents-core` 构建。提供**双模式**运行:交互式终端(TUI)用于人与 AI 对话,纯 stdio 模式用于脚本、管道与 shell 兜底钩子。内置文件系统操作工具,支持 MCP 协议集成外部工具、子 Agent 编排和 Skill 管理。
4
4
 
5
5
  ## 安装
6
6
 
@@ -20,42 +20,78 @@ pnpm build
20
20
  npm install -g .
21
21
  ```
22
22
 
23
+ ## 运行模式
24
+
25
+ CLI 有两种**互不混合**的运行模式,由启动参数与终端环境自动判定:
26
+
27
+ | 模式 | 触发条件 | 面向对象 | 核心行为 |
28
+ |------|----------|----------|----------|
29
+ | **纯 stdio** | 带参数,**或** stdin/stdout 非 TTY(管道、重定向、CI) | 脚本、管道、shell 兜底钩子 | 无任何额外交互;读入文本,把**最终回答以纯文本写入 stdout** |
30
+ | **TUI** | 无参数且 stdin/stdout 均为 TTY | 人类用户 | 交互式对话界面 |
31
+
32
+ 纯 stdio 模式下,日志 / 进度 / 工具过程 / 错误摘要一律走 **stderr**,stdout 只有结果本身(零 ANSI、零 emoji 前缀、零 spinner);成功退出码 `0`,失败非 `0`。默认**不落盘**(不写对话存档)。
33
+
23
34
  ## 快速使用
24
35
 
25
36
  ```bash
26
- # 交互式主菜单
27
- zen
37
+ # TUI:无参数且处于交互终端
38
+ ai
39
+
40
+ # 纯 stdio:参数即提示词,结果写入 stdout
41
+ ai 你好,请介绍一下你自己。
42
+
43
+ # 管道:stdin 作为内容,参数作为指令
44
+ cat README.md | ai "用三句话总结"
28
45
 
29
- # 快速对话(参数作为初始消息)
30
- zen 你好,请介绍一下你自己。
46
+ # 落盘:默认不保存,需要时显式 --save
47
+ ai --save "帮我给这个函数起个名字"
48
+
49
+ # 帮助 / 版本
50
+ ai --help
51
+ ai --version
31
52
  ```
32
53
 
33
- ## 主菜单
54
+ > 旧命令名 `aiz` / `zen` 作为过渡别名在当前版本仍可用,未来版本会移除。
55
+
56
+ ## 界面(TUI)
34
57
 
35
- 运行 `zen` 进入主菜单:
58
+ 无参数且处于交互终端时,进入由 **Ink(React)** 打造的全屏界面。启动先呈现动画渐变的 ASCII 启动界面:
36
59
 
37
60
  ```
38
- 🤖 欢迎使用 AI-Zen CLI
39
-
40
- ? 请选择操作:
41
- ▶️ 继续上次未完成的对话 (如有草稿)
42
- 💬 开始新对话
43
- 📂 继续已保存的对话
44
- 📋 管理已保存的对话
45
- 🤖 管理 Agents
46
- ⚙️ 配置管理
47
- ❌ 退出
61
+ █████╗ ██╗ ███████╗███████╗███╗ ██╗
62
+ ██╔══██╗██║ ╚══███╔╝██╔════╝████╗ ██║
63
+ ███████║██║ ███╔╝ █████╗ ██╔██╗ ██║
64
+ ██╔══██║██║ ███╔╝ ██╔══╝ ██║╚██╗██║
65
+ ██║ ██║██║ ███████╗███████╗██║ ╚████║
66
+ ╚═╝ ╚═╝╚═╝ ╚══════╝╚══════╝╚═╝ ╚═══╝
67
+
68
+ 终端里的 AI 协作台
69
+ v1.0.0-alpha.10 · sdk x · core y
48
70
  ```
49
71
 
50
- ### 草稿恢复
72
+ 启动界面结束后**直接进入对话界面**(若存在「上一轮会话」则自动续接,否则新建对话)。对话界面采用**底部固定**布局:分隔线、输入行与状态栏(模型 · Agent · 本轮/累计 token 用量 · 生成状态)始终贴在终端底部,对话内容在其上方滚动;生成中时输入行位置显示进度指示。
73
+
74
+ 对话界面包含:流式输出区(思考过程 / 回答正文 / 工具调用分行展示)、多行输入(`Enter` 发送、`Ctrl+N` 换行、`← →` 移动光标、`Ctrl+← →` 跨词)与内联 `/` 命令菜单(↑↓ 选择、`Tab` 补全)。工具调用以 `⚙ 名称(参数)` 展示并带 **JSON 语法高亮**,正文与思考按 **Markdown 源码着色**(标题 / 粗体 / 斜体 / 行内代码 / 列表 / 引用 / 链接),**围栏代码块按语言高亮并保留围栏标记**(高亮数据来自 `highlight.js` / `lowlight`)。`Ctrl+C` 在生成中取消本轮请求、空闲时退出。
51
75
 
52
- 如果退出对话时没有保存(或进程被强制杀死),对话内容会**自动保存为草稿**。下次启动 `zen` 时会看到:
76
+ ### 首次配置(API Key)
77
+
78
+ 首次启动时若所选模型绑定的端点还没有 API Key,会**先弹出凭据设置屏**,而不是报错退出:
53
79
 
54
80
  ```
55
- ▶️ 继续上次未完成的对话 (12 条消息, 2025/1/1 12:00:00)
56
- 💬 开始新对话(放弃草稿)
81
+ ? 首次配置 · 设置 DeepSeek 的 API Key
82
+ 端点:DeepSeek · https://api.deepseek.com/v1
83
+ 当前:未设置
84
+ DeepSeek 申请地址:https://platform.deepseek.com/api_keys
85
+ 保存后立即进入对话(Esc 放弃并退出)。
86
+ ❯ ▏
57
87
  ```
58
88
 
89
+ `Enter` 保存并直接进入对话(写入 `~/.ai-zen/config.json`),`Tab` 切明文核对,`Esc` 放弃。进入对话后仍可用 `/key` 修改**当前端点**的 Key(保存后自动重建会话,立即生效)、用 `/config` 打开配置中心(默认模型 / 端点管理:列表含「+ 新建端点」与各端点,选中端点后可就地编辑 API Key / Base URL)。
90
+
91
+ ### 会话恢复
92
+
93
+ 每个会话都会在对话过程中**直接落盘为独立文件**(`cli/conversations/<id>.json`),不再有单独的草稿存储。一个指针文件(`cli/last-session.json`)记录**上一轮会话 id**;下次启动 `ai` 会**自动续接该会话**,接着上次继续。
94
+
59
95
  ### 对话命令
60
96
 
61
97
  对话中输入的所有命令以 `/` 开头。输入 `/` 会在输入行下方实时列出可用命令及说明,继续输入即按前缀收敛候选:
@@ -65,54 +101,67 @@ zen 你好,请介绍一下你自己。
65
101
  /back 撤回消息(可修改后重发)
66
102
  ```
67
103
 
68
- > 提示仅作展示,不改变提交语义:回车始终提交当前输入原文,命令按完整名称精确匹配;输入未识别的 `/xxx` 命令会提示「未知命令」。
104
+ > 输入 `/` 会在输入行下方实时列出候选命令(↑↓ 选择、`Tab` 补全、`Enter` 提交/执行);命令按完整名称匹配,输入未识别的 `/xxx` 会提示「未知命令」。
69
105
 
70
106
  | 命令 | 说明 |
71
107
  |------|------|
72
- | `/exit` `/quit` | 退出对话(会提示是否保存) |
73
- | `/save` | 保存当前对话 |
108
+ | `/exit` `/quit` | 退出对话 |
109
+ | `/save` | 保存当前对话(会话本就每轮实时落盘) |
110
+ | `/load` | 加载已保存的对话(替换当前会话) |
74
111
  | `/new` | 重置会话(清空历史) |
75
112
  | `/back` | 撤回消息(回退到指定位置并可编辑后重发) |
76
113
  | `/editor` | 使用系统编辑器(vim/nano)输入长消息 |
77
114
  | `/clear` | 清屏 |
78
- | `/migrate` | 手动任务迁移(生成交接文档并开启新会话) |
115
+ | `/config` | 打开配置中心(端点 / 模型 / 图片模型 / MCP 服务器 / Agent 定义 / 默认项 / 工具上限) |
116
+ | `/key` | 设置当前端点的 API Key(保存后自动重建会话) |
117
+ | `/handoff` | 编写任务交接文档(会话照旧,不弹确认) |
118
+ | `/migrate` `/migration` | 交接 + 开启新会话(清空历史,需确认) |
79
119
  | `/help` | 显示可用命令 |
80
120
 
81
- ### 任务迁移
121
+ ### 任务交接与迁移
82
122
 
83
- 当 API 响应中的 `usage.prompt_tokens` 超过模型的 `maxContextTokens` 时,系统会先**二次确认**(展示当前用量与阈值,默认「是」;选择「否」则跳过本次迁移、当前对话不受影响),确认后生成**交接文档**,汇总已完成任务、待办事项和关键决策,然后创建新会话并将交接文档注入为上下文,实现无缝衔接。确认框仅在 stdin/stdout 均为 TTY 时出现;管道、重定向等非交互场景无确认通道,保持既有自动迁移行为。
123
+ 两条命令,同一条管道:
84
124
 
85
- 你也可以在对话中随时输入 `/migrate` 手动触发迁移,而无需等待 token 超限。手动与自动迁移均委托给 SDK 的 `TaskMigrationService`,交接文档生成始终一致。
125
+ - **`/handoff`** — 原 agent 停下手头工作,用自己的工具核实真实状态(分支、未提交改动、测试、端口),把交接文档写到 `<项目>/.ai-zen/handoffs/<时间戳>-<会话id>.md`。会话照旧运行,因此可以继续打磨这份文档。
126
+ - **`/migrate`** — 同一次交接,然后把历史清空、以该文档开启新会话(断点消息只带路径,由新 agent 自己读取)。
86
127
 
87
- 同样的上下文护栏也作用于**子 Agent**:每次委派边界(`onSubAgentStart`)CLI 都会把同一个 `ContextGuardPlugin`(同一 `maxTokens`)安插到新建的子 Agent 上,因此被委派的子 Agent(含 `call_skill_sub_agent` 创建的技能子 Agent)在上下文超出硬上限时同样会被中断。该过程是透明的,正常运行的子 Agent 不受影响。
128
+ 两种执行者:`self`(默认——原 agent 在会话内写,保真度最高)与 `summary`(一次独立模型调用,便宜但有损)。`self` 失败时**单向**降级为 `summary`。可用 `/handoff summary` 或 `/migrate self` 显式指定。
88
129
 
89
- 迁移提示词模板包含:
90
- - **对话断点** — 最后一段对话原文引用
91
- - **已完成的任务** — 任务标题和产出路径
92
- - **未完成的任务** — 描述、进度、下一步
93
- - **重要记忆** — 技术偏好、踩坑记录、架构决策
94
- - **文件索引** — 关键文件及用途说明
95
- - **接手指令** — 先读文件验真、再对状态、后行动的 SOP
130
+ 当 `usage.prompt_tokens` 超过模型的 `maxContextTokens`,交互式终端会弹出三选一选择器(自交接 / 独立摘要 / 跳过);管道等非交互场景按默认执行者迁移,不阻塞。
96
131
 
132
+ 文档模板不在代码里:来自 `handoff` Skill(`~/.ai-zen/skills/handoff/SKILL.md`,由 SDK 释放并随版本同步;在 frontmatter 写 `metadata.custom: "true"` 可保留你自己的版本,也可在项目内覆盖)。完整链路、成本说明与模板章节见 [任务交接与迁移](./docs/zh/migration.md)。
133
+
134
+ 同样的上下文护栏也作用于**子 Agent**:每次委派边界(`onSubAgentStart`)CLI 都会把同一个 `ContextGuardPlugin`(同一 `maxTokens`)安插到新建的子 Agent 上,因此被委派的子 Agent(含 `call_skill_sub_agent` 创建的技能子 Agent)在上下文超出硬上限时同样会被中断。该过程是透明的,正常运行的子 Agent 不受影响。
97
135
  ### Shell 兜底钩子
98
136
 
99
137
  当你在终端输入一个不存在的命令时,自动转发给 AI 处理:
100
138
 
101
139
  ```bash
102
140
  # 安装钩子
103
- zen hook install
141
+ ai hook install
104
142
 
105
143
  # 之后随便输入点什么:
106
144
  > 今天天气怎么样?
107
145
  # 这条消息会被转发给 AI,而不是显示 "command not found"
108
146
 
109
147
  # 卸载钩子
110
- zen hook uninstall
148
+ ai hook uninstall
111
149
  ```
112
150
 
151
+ 钩子函数体调用的是 `ai "$@"`(纯 stdio 模式),答案就地写入当前 shell 会话。若此前安装过旧版 `aiz` 钩子,重新执行 `ai hook install` 会自动升级;也可先 `ai hook uninstall` 再安装。
152
+
113
153
  ## 配置管理
114
154
 
115
- 配置文件存储在 `~/.ai-zen/config.json`(或 `$AI_ZEN_DIR/config.json`),与其他 AI-Zen 客户端共享。其中 `maxContextTokens` 是迁移触发阈值(通常设为模型实际上下文窗口的约 25%,例如 1M tokens 的模型设为 250,000)。
155
+ 配置文件存储在 `~/.ai-zen/config.json`(或 `$AI_ZEN_DIR/config.json`),与其他 AI-Zen 客户端共享,是**唯一数据源**。常用项可在 TUI 内直接编辑,无需手改 JSON:
156
+
157
+ | 场景 | 做法 |
158
+ |------|------|
159
+ | 首次启动、端点缺 Key | 启动时自动弹出**凭据设置屏** |
160
+ | 修改当前模型所用端点的 Key | 对话内 `/key`(保存后自动重建会话) |
161
+ | 端点 / 模型 / 图片模型、MCP 服务器、Agent 定义(含 Sub-agent)、默认项、工具输出上限 | 对话内 `/config`(配置中心,全面管理) |
162
+ | 其它高级项(Skill / 用户工具等) | 手动编辑 `~/.ai-zen/` 下的文件 |
163
+
164
+ 其中 `maxContextTokens` 是迁移触发阈值(通常设为模型实际上下文窗口的约 25%,例如 1M tokens 的模型设为 250,000)。
116
165
 
117
166
  ```jsonc
118
167
  {
@@ -126,11 +175,12 @@ zen hook uninstall
126
175
  ],
127
176
  "models": [
128
177
  {
129
- "id": "gpt-5.5",
130
- "name": "GPT-5.5",
178
+ "id": "gpt-6.1-sol",
179
+ "name": "GPT-6.1 Sol",
131
180
  "endpointId": "openai",
132
- "modelName": "gpt-5.5",
133
- "maxContextTokens": 250000
181
+ "modelName": "gpt-6.1-sol",
182
+ "maxContextTokens": 250000,
183
+ "custom": true
134
184
  }
135
185
  ],
136
186
  "imageModels": [
@@ -142,13 +192,15 @@ zen hook uninstall
142
192
  "defaultSize": "1024x1024"
143
193
  }
144
194
  ],
145
- "defaultModel": "deepseek-v4-flash",
195
+ "defaultModel": "deepseek-flash",
146
196
  "defaultImageModel": "cogview-4",
147
197
  "defaultAgent": "default",
148
- "defaultMigrationModel": "deepseek-v4-flash"
198
+ "defaultMigrationModel": "deepseek-flash"
149
199
  }
150
200
  ```
151
201
 
202
+ > 说明:`models` / `imageModels` 中**未标 `custom: true`** 的条目属于**出厂托管**——每次启动会与 SDK 出厂清单对齐、被替换为最新定义;自建模型请加 `"custom": true`。`endpoints` 始终保留用户配置,不受影响。
203
+
152
204
  ### 环境变量
153
205
 
154
206
  - `AI_ZEN_DIR` — 覆盖共享根目录(默认 `~/.ai-zen`)。CLI 运行时数据在 `$AI_ZEN_DIR/cli/`,共享资源(agents、skills、tools、MCP 等)在 `$AI_ZEN_DIR/`。
@@ -160,7 +212,7 @@ zen hook uninstall
160
212
  ├── config.json ← 端点与模型配置(与其他 AI-Zen 客户端共享)
161
213
  ├── cli/ ← CLI 运行时数据
162
214
  │ ├── conversations/ ← CLI 对话记录
163
- │ └── drafts/ ← CLI 草稿
215
+ │ └── last-session.json ← 「上一轮会话 id」指针
164
216
  ├── agents/ ← Agent 定义(共享)
165
217
  │ ├── default.json ← 默认 Agent(首次运行自动创建)
166
218
  │ └── my-custom-agent.json
@@ -209,25 +261,25 @@ CLI 提供 20 个内置工具,由 `@ai-zen/agents-sdk` 实现。工具可用
209
261
  | 工具 | 说明 |
210
262
  |------|------|
211
263
  | `cwd` | 获取当前工作目录 |
212
- | `readFile` | 读取文件内容(支持 `range` 分批读取) |
213
- | `inspectFile` | 勘察文件结构概况(行数、字符数、列宽分布、行尾风格),不读取内容 |
214
- | `writeFile` | 写入文件 |
264
+ | `read` | 读取文件内容(支持 `range` 分批读取) |
265
+ | `inspect_file` | 勘察文件结构概况(行数、字符数、列宽分布、行尾风格),不读取内容 |
266
+ | `write` | 写入文件 |
215
267
  | `edit` | 替换文件中的文本(单次替换) |
216
- | `batchEdit` | 批量编辑文本 |
268
+ | `batch_edit` | 批量编辑文本 |
217
269
  | `exec` | 执行 shell 命令 |
218
- | `exec_async` | 异步执行 shell 命令(立即返回,不等待结果) |
270
+ | `spawn` | 异步执行 shell 命令(立即返回,不等待结果) |
219
271
  | `mkdir` | 创建目录 |
220
272
  | `rm` | 删除文件或目录 |
221
273
  | `glob` | 通配符扫描文件 |
222
274
  | `ls` | 列出目录 |
223
275
  | `exist` | 检查路径是否存在 |
224
- | `findText` | 在文件中查找文本 |
225
- | `downloadFile` | 从 URL 下载文件 |
276
+ | `find_text` | 在文件中查找文本 |
277
+ | `download_file` | 从 URL 下载文件 |
226
278
  | `rename` | 重命名或移动文件 |
227
279
  | `copy` | 复制文件或目录 |
228
280
  | `sleep` | 等待指定毫秒数 |
229
- | `viewImage` | 查看/分析图片 — 仅视觉模型可用(`Model.vision`)。网络图片直接以 `image_url` 内容块返回;本地图片经 Files API 自动上传后以 `file` 内容块返回 |
230
- | `generateImage` | 根据描述生成图片 — 需配置 `defaultImageModel`;统一返回字符串(含图片 URL 列表与 `viewImage` / `downloadFile` 提示的 JSON),不再强制返回图片内容块 |
281
+ | `view_image` | 查看/分析图片 — 仅视觉模型可用(`Model.vision`)。网络图片直接以 `image_url` 内容块返回;本地图片经 Files API 自动上传后以 `file` 内容块返回 |
282
+ | `generate_image` | 根据描述生成图片 — 需配置 `defaultImageModel`;统一返回字符串(含图片 URL 列表与 `view_image` / `download_file` 提示的 JSON),不再强制返回图片内容块 |
231
283
 
232
284
  ### 动态工具
233
285
 
@@ -246,7 +298,7 @@ CLI 提供 20 个内置工具,由 `@ai-zen/agents-sdk` 实现。工具可用
246
298
  工具装配由 SDK 的 `Scope` 能力管线管理,分为三个阶段:
247
299
 
248
300
  1. **发现** — 扫描文件系统获取内置工具、用户工具、SubAgent、Skill 和 MCP 服务器。20 个内置工具全部无条件发现(此阶段不做过滤)
249
- 2. **过滤** — 应用权限(`allow`/`deny`)、安全排除(递归保护),以及各工具自声明的 `isAvailable(config, definition)`(在模型已知的构建阶段判断可用性;如 `viewImage` 仅视觉模型、`generateImage` 需配置 `defaultImageModel`)
301
+ 2. **过滤** — 应用权限(`allow`/`deny`)、安全排除(递归保护),以及各工具自声明的 `isAvailable(config, definition)`(在模型已知的构建阶段判断可用性;如 `view_image` 仅视觉模型、`generate_image` 需配置 `defaultImageModel`)
250
302
  3. **实例化** — 将过滤后的名称映射为 `Tool` 实例,注册动态加载器
251
303
 
252
304
  每个 Agent 拥有独立的权限配置,父 Agent 与 SubAgent 之间不继承权限。唯一的例外是 `call_skill_sub_agent` 创建的临时 Skill 子 Agent——它是临时的对话分身而非独立实体,因此沿用调用者的工具能力(不再走第二遍权限过滤)。
@@ -304,13 +356,14 @@ OAuth 2.0 授权流程(`mcp.json` 中的 `oauth` 字段)已定义类型和
304
356
 
305
357
  | ID | 名称 | 端点 |
306
358
  |----|------|------|
307
- | `gpt-5.5` | GPT-5.5 | OpenAI |
308
- | `glm-5.1` | GLM-5.1 | 智谱AI |
309
- | `glm-5v-turbo` | GLM-5V-Turbo(视觉) | 智谱AI |
359
+ | `gpt-6-astra` | GPT-6 Astra | OpenAI |
360
+ | `gpt-6.1-sol` | GPT-6.1 Sol | OpenAI |
361
+ | `gpt-6-luna` | GPT-6 Luna | OpenAI |
362
+ | `glm-5.3` | GLM-5.3 | 智谱AI |
363
+ | `glm-5.3-flash` | GLM-5.3-Flash(视觉) | 智谱AI |
364
+ | `glm-5.3-flashx` | GLM-5.3-FlashX(视觉) | 智谱AI |
310
365
  | `glm-4.7-flash` | GLM-4.7-Flash | 智谱AI |
311
- | `deepseek-v4-pro` | DeepSeek-V4-Pro | DeepSeek |
312
- | `deepseek-v4-flash` | DeepSeek-V4-Flash | DeepSeek(**默认模型**) |
313
- | `deepseek-v4-flash-vision-exp` | DeepSeek-V4-Flash-Vision-Exp(视觉) | DeepSeek |
366
+ | `deepseek-flash` | DeepSeek-V4.1-Flash(视觉) | DeepSeek(**默认模型**) |
314
367
 
315
368
  ## 开发
316
369
 
@@ -6,8 +6,25 @@
6
6
  */
7
7
  import { Scope, SdkAgent } from "@ai-zen/agents-sdk";
8
8
  import type { AgentNS } from "@ai-zen/agents-core";
9
+ /**
10
+ * Skill 目录列表(优先级从高到低):
11
+ * 1. 项目/.ai-zen/skills/
12
+ * 2. 项目/.agents/skills/ ← 业界通用规范
13
+ * 3. ~/.ai-zen/skills/
14
+ * 4. ~/.agents/skills/ ← 业界通用规范
15
+ *
16
+ * 同时供 Scope 装配与交接服务(读取 `handoff` Skill 正文)使用,避免两处各算一遍。
17
+ * 只返回**当前真实存在**的目录,不存在的不参与发现。
18
+ */
19
+ export declare function listSkillDirs(): string[];
9
20
  export declare function getScope(): Promise<Scope>;
10
- export declare function resetScope(): void;
21
+ /**
22
+ * 重置 Scope 单例:释放当前 Scope(断开 MCP 连接等),下次 `getScope()` 按磁盘配置重建。
23
+ *
24
+ * 配置变更后(如 TUI 的 `/config` 改了端点凭据)必须调用:Scope 的 `config` 只在创建时
25
+ * 读取一次,不重建则新配置不生效。`_scope` 是同步置空的,便于并发调用方立刻拿到新实例。
26
+ */
27
+ export declare function resetScope(): Promise<void>;
11
28
  export interface CreateAgentOptions {
12
29
  messages?: AgentNS.Message[];
13
30
  agentId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-creator.d.ts","sourceRoot":"","sources":["../src/agent-creator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EACL,KAAK,EAGL,QAAQ,EACT,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAiBnD,wBAAsB,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,CA8C/C;AAED,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAID,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAchF"}
1
+ {"version":3,"file":"agent-creator.d.ts","sourceRoot":"","sources":["../src/agent-creator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EACL,KAAK,EAGL,QAAQ,EACT,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAiBnD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAOxC;AAED,wBAAsB,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,CAqC/C;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAShD;AAID,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAchF"}
@@ -13,6 +13,24 @@ import { readConfig } from "./config.js";
13
13
  let _scope = null;
14
14
  /** existsSync 的别名,用于数组 .filter() 场景 */
15
15
  const exists = existsSync;
16
+ /**
17
+ * Skill 目录列表(优先级从高到低):
18
+ * 1. 项目/.ai-zen/skills/
19
+ * 2. 项目/.agents/skills/ ← 业界通用规范
20
+ * 3. ~/.ai-zen/skills/
21
+ * 4. ~/.agents/skills/ ← 业界通用规范
22
+ *
23
+ * 同时供 Scope 装配与交接服务(读取 `handoff` Skill 正文)使用,避免两处各算一遍。
24
+ * 只返回**当前真实存在**的目录,不存在的不参与发现。
25
+ */
26
+ export function listSkillDirs() {
27
+ return [
28
+ PROJECT_SKILLS_DIR,
29
+ PROJECT_AGENTS_SKILLS_DIR,
30
+ SKILLS_DIR,
31
+ USER_AGENTS_SKILLS_DIR,
32
+ ].filter(exists);
33
+ }
16
34
  export async function getScope() {
17
35
  if (_scope)
18
36
  return _scope;
@@ -30,17 +48,8 @@ export async function getScope() {
30
48
  join(AI_ZEN_DIR, "mcp.json"),
31
49
  USER_AGENTS_MCP_CONFIG_FILE,
32
50
  ].filter(exists);
33
- // Skills 目录优先级(从高到低):
34
- // 1. 项目/.ai-zen/skills/
35
- // 2. 项目/.agents/skills/ ← 业界通用规范
36
- // 3. ~/.ai-zen/skills/
37
- // 4. ~/.agents/skills/ ← 业界通用规范
38
- const skillsPaths = [
39
- PROJECT_SKILLS_DIR,
40
- PROJECT_AGENTS_SKILLS_DIR,
41
- SKILLS_DIR,
42
- USER_AGENTS_SKILLS_DIR,
43
- ].filter(exists);
51
+ // Skills 目录优先级(从高到低):见 listSkillDirs()
52
+ const skillsPaths = listSkillDirs();
44
53
  _scope = new Scope({
45
54
  config,
46
55
  agentsDir: AGENTS_DIR,
@@ -53,8 +62,23 @@ export async function getScope() {
53
62
  await _scope.init();
54
63
  return _scope;
55
64
  }
56
- export function resetScope() {
65
+ /**
66
+ * 重置 Scope 单例:释放当前 Scope(断开 MCP 连接等),下次 `getScope()` 按磁盘配置重建。
67
+ *
68
+ * 配置变更后(如 TUI 的 `/config` 改了端点凭据)必须调用:Scope 的 `config` 只在创建时
69
+ * 读取一次,不重建则新配置不生效。`_scope` 是同步置空的,便于并发调用方立刻拿到新实例。
70
+ */
71
+ export async function resetScope() {
72
+ const scope = _scope;
57
73
  _scope = null;
74
+ if (!scope)
75
+ return;
76
+ try {
77
+ await scope.dispose();
78
+ }
79
+ catch {
80
+ /* 释放失败不影响后续重建 */
81
+ }
58
82
  }
59
83
  export async function createAgent(options) {
60
84
  const { messages, agentId } = options;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-creator.js","sourceRoot":"","sources":["../src/agent-creator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EACL,KAAK,EACL,QAAQ,EACR,WAAW,IAAI,cAAc,GAE9B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EACjD,UAAU,EACV,sBAAsB,EAAE,kBAAkB,EAAE,iBAAiB,EAC7D,sBAAsB,EAAE,2BAA2B,EACnD,yBAAyB,EAAE,8BAA8B,GAC1D,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,wDAAwD;AAExD,IAAI,MAAM,GAAiB,IAAI,CAAC;AAEhC,uCAAuC;AACvC,MAAM,MAAM,GAAG,UAAU,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAElC,qBAAqB;IACrB,oBAAoB;IACpB,2BAA2B;IAC3B,8CAA8C;IAC9C,0BAA0B;IAC1B,gDAAgD;IAChD,MAAM,QAAQ,GAAG;QACf,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC;QAC1C,8BAA8B;QAC9B,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC;QAC5B,2BAA2B;KAC5B,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEjB,sBAAsB;IACtB,0BAA0B;IAC1B,8CAA8C;IAC9C,yBAAyB;IACzB,gDAAgD;IAChD,MAAM,WAAW,GAAG;QAClB,kBAAkB;QAClB,yBAAyB;QACzB,UAAU;QACV,sBAAsB;KACvB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEjB,MAAM,GAAG,IAAI,KAAK,CAAC;QACjB,MAAM;QACN,SAAS,EAAE,UAAU;KACtB,CAAC,CAAC,GAAG,CACJ,GAAG,QAAQ,CAAC;QACV,cAAc,EAAE,CAAC,sBAAsB,EAAE,cAAc,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;QACvE,WAAW;QACX,UAAU,EAAE,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;QACzD,QAAQ;KACT,CAAC,CACH,CAAC;IAEF,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IAEpB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,IAAI,CAAC;AAChB,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA2B;IAC3D,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACtC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAE/B,wCAAwC;IACxC,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,KAAK,EAAE,OAAO,IAAI,SAAS,CAAC,CAAC;IAEhE,wBAAwB;IACxB,kDAAkD;IAClD,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,KAAK,CAAC,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"agent-creator.js","sourceRoot":"","sources":["../src/agent-creator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Agent / Sub-agent 定义仓储 —— CLI 层
3
+ *
4
+ * 管理两处定义目录(均为「每实体一个 JSON,文件名 = `<id>.json`」):
5
+ * - 顶层 Agent:`~/.ai-zen/agents/*.json`(`/config`「默认 Agent」可选的那些)
6
+ * - 子 Agent: `~/.ai-zen/sub-agents/*.json`(可被委派,额外带 `function` 定义)
7
+ *
8
+ * 单文件读写委托 SDK 的 `AgentRepository`(`EntityRepository`),本模块只做「按 kind 分派」
9
+ * 与「快照 + 写操作」的组装,便于 TUI 与单测共用。
10
+ */
11
+ import type { AgentDefinition } from "@ai-zen/agents-sdk";
12
+ /** Agent 定义的类型:顶层 Agent / 子 Agent */
13
+ export type AgentKind = "agent" | "subagent";
14
+ /** 某个 kind 对应的定义目录 */
15
+ export declare function agentDir(kind: AgentKind): string;
16
+ /** kind 的中文名 */
17
+ export declare function agentKindLabel(kind: AgentKind): string;
18
+ /** 「Agent 定义」管理用的仓储:快照 + 写 / 删操作 */
19
+ export interface AgentStore {
20
+ agents: AgentDefinition[];
21
+ subAgents: AgentDefinition[];
22
+ save: (kind: AgentKind, def: AgentDefinition) => Promise<void>;
23
+ remove: (kind: AgentKind, id: string) => Promise<void>;
24
+ }
25
+ /** 取某 kind 的定义列表 */
26
+ export declare function agentList(store: AgentStore, kind: AgentKind): AgentDefinition[];
27
+ /** 按 id 查找某 kind 的定义 */
28
+ export declare function findAgentDefinition(store: AgentStore, kind: AgentKind, id: string | undefined): AgentDefinition | undefined;
29
+ /** 用给定快照 + 真实文件读写构造仓储 */
30
+ export declare function createAgentStore(agents: AgentDefinition[], subAgents: AgentDefinition[]): AgentStore;
31
+ /** 从磁盘读取 Agent / Sub-agent 快照,并附带真实读写能力 */
32
+ export declare function readAgentStore(): Promise<AgentStore>;
33
+ //# sourceMappingURL=agents-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-store.d.ts","sourceRoot":"","sources":["../src/agents-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D,qCAAqC;AACrC,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AAE7C,sBAAsB;AACtB,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAEhD;AAED,gBAAgB;AAChB,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAEtD;AAED,oCAAoC;AACpC,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,IAAI,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED,oBAAoB;AACpB,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,eAAe,EAAE,CAE/E;AAED,wBAAwB;AACxB,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,SAAS,EACf,EAAE,EAAE,MAAM,GAAG,SAAS,GACrB,eAAe,GAAG,SAAS,CAG7B;AAED,yBAAyB;AACzB,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,UAAU,CAWpG;AAED,2CAA2C;AAC3C,wBAAsB,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC,CAI1D"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Agent / Sub-agent 定义仓储 —— CLI 层
3
+ *
4
+ * 管理两处定义目录(均为「每实体一个 JSON,文件名 = `<id>.json`」):
5
+ * - 顶层 Agent:`~/.ai-zen/agents/*.json`(`/config`「默认 Agent」可选的那些)
6
+ * - 子 Agent: `~/.ai-zen/sub-agents/*.json`(可被委派,额外带 `function` 定义)
7
+ *
8
+ * 单文件读写委托 SDK 的 `AgentRepository`(`EntityRepository`),本模块只做「按 kind 分派」
9
+ * 与「快照 + 写操作」的组装,便于 TUI 与单测共用。
10
+ */
11
+ import { AgentRepository } from "@ai-zen/agents-sdk";
12
+ import { AGENTS_DIR, SUB_AGENTS_DIR } from "./config.js";
13
+ /** 某个 kind 对应的定义目录 */
14
+ export function agentDir(kind) {
15
+ return kind === "agent" ? AGENTS_DIR : SUB_AGENTS_DIR;
16
+ }
17
+ /** kind 的中文名 */
18
+ export function agentKindLabel(kind) {
19
+ return kind === "agent" ? "Agent" : "Sub-agent";
20
+ }
21
+ /** 取某 kind 的定义列表 */
22
+ export function agentList(store, kind) {
23
+ return kind === "agent" ? store.agents : store.subAgents;
24
+ }
25
+ /** 按 id 查找某 kind 的定义 */
26
+ export function findAgentDefinition(store, kind, id) {
27
+ if (!id)
28
+ return undefined;
29
+ return agentList(store, kind).find((def) => def.id === id);
30
+ }
31
+ /** 用给定快照 + 真实文件读写构造仓储 */
32
+ export function createAgentStore(agents, subAgents) {
33
+ return {
34
+ agents,
35
+ subAgents,
36
+ save: async (kind, def) => {
37
+ await new AgentRepository(agentDir(kind)).write(def);
38
+ },
39
+ remove: async (kind, id) => {
40
+ await new AgentRepository(agentDir(kind)).delete(id);
41
+ },
42
+ };
43
+ }
44
+ /** 从磁盘读取 Agent / Sub-agent 快照,并附带真实读写能力 */
45
+ export async function readAgentStore() {
46
+ const agents = await new AgentRepository(AGENTS_DIR).list();
47
+ const subAgents = await new AgentRepository(SUB_AGENTS_DIR).list();
48
+ return createAgentStore(agents, subAgents);
49
+ }
50
+ //# sourceMappingURL=agents-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-store.js","sourceRoot":"","sources":["../src/agents-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKzD,sBAAsB;AACtB,MAAM,UAAU,QAAQ,CAAC,IAAe;IACtC,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC;AACxD,CAAC;AAED,gBAAgB;AAChB,MAAM,UAAU,cAAc,CAAC,IAAe;IAC5C,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC;AAClD,CAAC;AAUD,oBAAoB;AACpB,MAAM,UAAU,SAAS,CAAC,KAAiB,EAAE,IAAe;IAC1D,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC;AAC3D,CAAC;AAED,wBAAwB;AACxB,MAAM,UAAU,mBAAmB,CACjC,KAAiB,EACjB,IAAe,EACf,EAAsB;IAEtB,IAAI,CAAC,EAAE;QAAE,OAAO,SAAS,CAAC;IAC1B,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,gBAAgB,CAAC,MAAyB,EAAE,SAA4B;IACtF,OAAO;QACL,MAAM;QACN,SAAS;QACT,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YACxB,MAAM,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvD,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE;YACzB,MAAM,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACvD,CAAC;KACF,CAAC;AACJ,CAAC;AAED,2CAA2C;AAC3C,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,MAAM,GAAG,MAAM,IAAI,eAAe,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5D,MAAM,SAAS,GAAG,MAAM,IAAI,eAAe,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,CAAC;IACnE,OAAO,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * 自动迁移的「执行者选择」入口(CLI 层)。
3
+ *
4
+ * 背景:SDK 的 `AutoMigratePlugin` 在 `usage.prompt_tokens` 超过阈值时触发迁移,
5
+ * 但「谁来写交接文档」是产品决策——保真度高的**原 agent 自交接**,还是便宜的**独立摘要**。
6
+ * SDK 已把该决策抽象为 `resolveMode` 回调,CLI 在这里把它接到「用户三选一」上:
7
+ * 原 agent 自交接 / 独立摘要 / 跳过本次迁移。
8
+ *
9
+ * 边界(保持 SDK 的分工,不重复实现「何时迁移」的语义):
10
+ * - **何时迁移**:`AutoMigratePlugin`(阈值判断 + busy 让行);
11
+ * - **用什么执行者**:本模块的 `resolveMode`;
12
+ * - **实际怎么交接**:共享的 `HandoffService`(与 `/migrate`、`/handoff` 同一条链路)。
13
+ *
14
+ * 交互约定:
15
+ * - 仅在 stdin 与 stdout **均为 TTY**(人类交互终端)时询问;
16
+ * - 非交互环境(管道、重定向、e2e 脚本)没有选择通道,直接按 `defaultMode` 迁移,
17
+ * 不阻塞等待输入、不额外输出,管道语义不变;
18
+ * - 选择器默认高亮 `self`(保真),Esc/取消 = 跳过本次迁移,不影响当前对话
19
+ * (历史未被剔除);只要仍处于超限状态,下次发送后还会再问。
20
+ */
21
+ import { AutoMigratePlugin, type AutoMigrateTriggerInfo, type HandoffMode, type HandoffService } from "@ai-zen/agents-sdk";
22
+ export interface AutoMigrateModeOptions {
23
+ /** 交接服务实例(与 `/migrate`、`/handoff` 共用同一实例) */
24
+ service: HandoffService;
25
+ /** 触发迁移的上下文阈值 */
26
+ maxTokens: number;
27
+ /**
28
+ * 用户的执行者选择(由调用方注入:TUI 用选择器浮层)。
29
+ * 返回 `null` 表示跳过本次迁移。
30
+ */
31
+ choose: (info: AutoMigrateTriggerInfo) => Promise<HandoffMode | null>;
32
+ /** 非交互环境下的执行者,默认 `self` */
33
+ defaultMode?: HandoffMode;
34
+ /** 是否需要向用户确认;默认「stdin 与 stdout 均为 TTY」。可注入,便于单测 */
35
+ shouldConfirm?: () => boolean;
36
+ /** 输出信息(如「已跳过本次迁移」);由调用方注入(TUI 走 Ink notice),默认丢弃 */
37
+ log?: (text: string) => void;
38
+ }
39
+ /** 默认交互判定:仅当 stdin 与 stdout 均为 TTY 时才具备选择通道 */
40
+ export declare function canPromptUser(): boolean;
41
+ /** 构造带「执行者选择」的自动迁移插件 */
42
+ export declare function createAutoMigratePlugin(options: AutoMigrateModeOptions): AutoMigratePlugin;
43
+ //# sourceMappingURL=auto-migrate-confirm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-migrate-confirm.d.ts","sourceRoot":"","sources":["../src/auto-migrate-confirm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EACL,iBAAiB,EACjB,KAAK,sBAAsB,EAC3B,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,sBAAsB;IACrC,6CAA6C;IAC7C,OAAO,EAAE,cAAc,CAAC;IACxB,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACtE,2BAA2B;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC;IAC9B,qDAAqD;IACrD,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED,+CAA+C;AAC/C,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,wBAAwB;AACxB,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,sBAAsB,GAAG,iBAAiB,CA4B1F"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * 自动迁移的「执行者选择」入口(CLI 层)。
3
+ *
4
+ * 背景:SDK 的 `AutoMigratePlugin` 在 `usage.prompt_tokens` 超过阈值时触发迁移,
5
+ * 但「谁来写交接文档」是产品决策——保真度高的**原 agent 自交接**,还是便宜的**独立摘要**。
6
+ * SDK 已把该决策抽象为 `resolveMode` 回调,CLI 在这里把它接到「用户三选一」上:
7
+ * 原 agent 自交接 / 独立摘要 / 跳过本次迁移。
8
+ *
9
+ * 边界(保持 SDK 的分工,不重复实现「何时迁移」的语义):
10
+ * - **何时迁移**:`AutoMigratePlugin`(阈值判断 + busy 让行);
11
+ * - **用什么执行者**:本模块的 `resolveMode`;
12
+ * - **实际怎么交接**:共享的 `HandoffService`(与 `/migrate`、`/handoff` 同一条链路)。
13
+ *
14
+ * 交互约定:
15
+ * - 仅在 stdin 与 stdout **均为 TTY**(人类交互终端)时询问;
16
+ * - 非交互环境(管道、重定向、e2e 脚本)没有选择通道,直接按 `defaultMode` 迁移,
17
+ * 不阻塞等待输入、不额外输出,管道语义不变;
18
+ * - 选择器默认高亮 `self`(保真),Esc/取消 = 跳过本次迁移,不影响当前对话
19
+ * (历史未被剔除);只要仍处于超限状态,下次发送后还会再问。
20
+ */
21
+ import { AutoMigratePlugin, } from "@ai-zen/agents-sdk";
22
+ /** 默认交互判定:仅当 stdin 与 stdout 均为 TTY 时才具备选择通道 */
23
+ export function canPromptUser() {
24
+ return Boolean(process.stdin.isTTY && process.stdout.isTTY);
25
+ }
26
+ /** 构造带「执行者选择」的自动迁移插件 */
27
+ export function createAutoMigratePlugin(options) {
28
+ const { service, maxTokens, choose, defaultMode = "self", shouldConfirm = canPromptUser, log = () => { }, } = options;
29
+ return new AutoMigratePlugin({
30
+ service,
31
+ maxTokens,
32
+ resolveMode: async (info) => {
33
+ // 非交互环境:没有选择通道,按默认执行者迁移(不阻塞、不额外输出)
34
+ if (!shouldConfirm())
35
+ return defaultMode;
36
+ const mode = await choose(info);
37
+ if (mode == null) {
38
+ log("⏭️ 已跳过本次任务迁移,继续当前对话。");
39
+ log("💡 上下文仍接近上限:可随时输入 /migrate 手动迁移;若继续增长至严重超限,对话会被安全护栏中断。");
40
+ return null;
41
+ }
42
+ return mode;
43
+ },
44
+ });
45
+ }
46
+ //# sourceMappingURL=auto-migrate-confirm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-migrate-confirm.js","sourceRoot":"","sources":["../src/auto-migrate-confirm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EACL,iBAAiB,GAIlB,MAAM,oBAAoB,CAAC;AAoB5B,+CAA+C;AAC/C,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,wBAAwB;AACxB,MAAM,UAAU,uBAAuB,CAAC,OAA+B;IACrE,MAAM,EACJ,OAAO,EACP,SAAS,EACT,MAAM,EACN,WAAW,GAAG,MAAM,EACpB,aAAa,GAAG,aAAa,EAC7B,GAAG,GAAG,GAAG,EAAE,GAAE,CAAC,GACf,GAAG,OAAO,CAAC;IAEZ,OAAO,IAAI,iBAAiB,CAAC;QAC3B,OAAO;QACP,SAAS;QACT,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YAC1B,mCAAmC;YACnC,IAAI,CAAC,aAAa,EAAE;gBAAE,OAAO,WAAW,CAAC;YAEzC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;gBACjB,GAAG,CAAC,sBAAsB,CAAC,CAAC;gBAC5B,GAAG,CACD,wDAAwD,CACzD,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}