@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
@@ -0,0 +1,198 @@
1
+ /**
2
+ * TUI 文本度量与折行 —— 纯函数(无 React / Ink 依赖)
3
+ *
4
+ * 从 `screens.tsx` 中抽出,供对话屏、凭据设置屏、配置中心共用,
5
+ * 避免 `screens.tsx ↔ config-wizard.tsx` 相互 import 形成循环依赖。
6
+ */
7
+ // ==================== 显示宽度 ====================
8
+ /** 是否宽字符(CJK / 全角 / 常见 Emoji),占 2 列 */
9
+ function isWide(cp) {
10
+ return ((cp >= 0x1100 && cp <= 0x115f) ||
11
+ (cp >= 0x2e80 && cp <= 0x303e) ||
12
+ (cp >= 0x3041 && cp <= 0x33ff) ||
13
+ (cp >= 0x3400 && cp <= 0x4dbf) ||
14
+ (cp >= 0x4e00 && cp <= 0x9fff) ||
15
+ (cp >= 0xa000 && cp <= 0xa4cf) ||
16
+ (cp >= 0xac00 && cp <= 0xd7a3) ||
17
+ (cp >= 0xf900 && cp <= 0xfaff) ||
18
+ (cp >= 0xfe30 && cp <= 0xfe6f) ||
19
+ (cp >= 0xff00 && cp <= 0xff60) ||
20
+ (cp >= 0xffe0 && cp <= 0xffe6) ||
21
+ (cp >= 0x1f300 && cp <= 0x1faff) ||
22
+ (cp >= 0x20000 && cp <= 0x3fffd));
23
+ }
24
+ /** 终端显示宽度(宽字符计 2,组合字符计 0) */
25
+ export function displayWidth(text) {
26
+ let width = 0;
27
+ for (const ch of text) {
28
+ const cp = ch.codePointAt(0);
29
+ if (cp >= 0x0300 && cp <= 0x036f)
30
+ continue; // 组合附加符号
31
+ width += isWide(cp) ? 2 : 1;
32
+ }
33
+ return width;
34
+ }
35
+ /**
36
+ * 按显示宽度把文本折成多行(保留显式换行)。
37
+ * 拉丁文优先在空格处断行,CJK / 超长词按字符硬断;保证每行显示宽度 ≤ limit。
38
+ */
39
+ export function wrapText(text, limit) {
40
+ const width = Math.max(1, limit);
41
+ const out = [];
42
+ for (const raw of text.split("\n")) {
43
+ if (raw === "") {
44
+ out.push("");
45
+ continue;
46
+ }
47
+ let line = "";
48
+ let lineWidth = 0;
49
+ for (const ch of raw) {
50
+ const w = displayWidth(ch);
51
+ if (lineWidth + w > width && line !== "") {
52
+ const space = line.lastIndexOf(" ");
53
+ if (space > 0) {
54
+ out.push(line.slice(0, space));
55
+ line = line.slice(space + 1);
56
+ lineWidth = displayWidth(line);
57
+ }
58
+ else {
59
+ out.push(line);
60
+ line = "";
61
+ lineWidth = 0;
62
+ }
63
+ }
64
+ line += ch;
65
+ lineWidth += w;
66
+ }
67
+ out.push(line);
68
+ }
69
+ return out.length > 0 ? out : [""];
70
+ }
71
+ /**
72
+ * 把输入文本按显示宽度折行,并定位光标(`cursor` 为字符索引,以 code point 计)。
73
+ * 折行采用逐字符硬断(不做空格优先),以保证光标映射精确、支持跨行编辑。
74
+ */
75
+ export function layoutInput(text, cursor, width) {
76
+ const limit = Math.max(1, width);
77
+ const chars = Array.from(text);
78
+ const pos = Math.max(0, Math.min(cursor, chars.length));
79
+ const lines = [];
80
+ let line = "";
81
+ let lineWidth = 0;
82
+ let row = 0;
83
+ let col = 0;
84
+ let cursorRow = 0;
85
+ let cursorCol = 0;
86
+ let processed = 0;
87
+ // 记录「处理完 processed 个字符后」的光标位置;processed === pos 即为光标处
88
+ const mark = () => {
89
+ if (processed === pos) {
90
+ cursorRow = row;
91
+ cursorCol = col;
92
+ }
93
+ };
94
+ mark();
95
+ for (const ch of chars) {
96
+ if (ch === "\n") {
97
+ lines.push(line);
98
+ line = "";
99
+ lineWidth = 0;
100
+ row += 1;
101
+ col = 0;
102
+ processed += 1;
103
+ mark();
104
+ continue;
105
+ }
106
+ const w = displayWidth(ch);
107
+ if (col > 0 && lineWidth + w > limit) {
108
+ lines.push(line);
109
+ line = "";
110
+ lineWidth = 0;
111
+ row += 1;
112
+ col = 0;
113
+ }
114
+ line += ch;
115
+ lineWidth += w;
116
+ col += 1;
117
+ processed += 1;
118
+ mark();
119
+ }
120
+ lines.push(line);
121
+ mark();
122
+ return { lines, cursorRow, cursorCol };
123
+ }
124
+ /** 单行输入左侧留白:Box paddingX(1) + 提示符 `❯ `(宽 2) */
125
+ export const INPUT_PREFIX_WIDTH = 3;
126
+ /**
127
+ * 判断一段输入是否为「终端应答序列」而非用户输入。
128
+ *
129
+ * 典型来源:
130
+ * - Kitty 键盘协议查询的应答:`CSI ? <flags> u`(Ink 开启 `kittyKeyboard` 时会发 `CSI ? u`);
131
+ * - 光标位置报告(CPR):`CSI <row>;<col> R`;
132
+ * - 设备状态报告:`CSI ? <n> n`。
133
+ *
134
+ * 这类序列本应由 Ink 的解析器整体吞掉。但当它被**拆包**时(前导 ESC 被 Ink 的
135
+ * 「待定转义刷新定时器」当作一次独立的 Escape 键消费),残留在后一个 chunk 里的
136
+ * `[?0u` 会退化成普通文本并被当作输入插入输入框(实测重现)。此处做一层护栏;
137
+ * 根因(不再向终端发查询)已在渲染选项里关闭。
138
+ */
139
+ export function isTerminalReply(sequence) {
140
+ return (/^\[\?\d+u$/.test(sequence) || // Kitty 键盘协议应答(CSI ? <flags> u)
141
+ /^\[\d+;\d+R$/.test(sequence) || // 光标位置报告(CSI <row>;<col> R)
142
+ /^\[\?\d+n$/.test(sequence) // 设备状态报告(CSI ? <n> n)
143
+ );
144
+ }
145
+ /**
146
+ * 按显示宽度裁剪文本:超出上限则截断并补省略号(宽字符计 2 列)。
147
+ *
148
+ * 用于列表项等「必须恰好占一行」的场景 —— 让 Ink 不会二次折行,
149
+ * 自底部向上布局时才能精确算出顶部留白。
150
+ */
151
+ export function clipWidth(text, max) {
152
+ const limit = Math.max(1, max);
153
+ if (displayWidth(text) <= limit)
154
+ return text;
155
+ let out = "";
156
+ let width = 0;
157
+ for (const ch of text) {
158
+ const w = displayWidth(ch);
159
+ if (width + w > limit - 1)
160
+ break; // 预留 1 列给省略号
161
+ out += ch;
162
+ width += w;
163
+ }
164
+ return `${out}…`;
165
+ }
166
+ // ==================== 整帧高度 ====================
167
+ /**
168
+ * 整帧可用高度 = 终端行数 − 1。
169
+ *
170
+ * Ink 在主输出高度 ≥ 终端行数时判定为「全屏」(`ink/build/ink.js`):Windows 控制台下
171
+ * 每帧强制 `clearTerminal`,且渲染串末尾不补换行;但硬件光标定位仍假设「光标停在最后
172
+ * 一行之后」,于是整体上移一行(IME 候选框随之偏上)。预留最后一行,让整帧高度严格小于
173
+ * 终端行数,即可避开该分支,硬件光标与自绘光标精确对齐。
174
+ */
175
+ export function usableFrameRows(terminalRows) {
176
+ return Math.max(1, terminalRows - 1);
177
+ }
178
+ /**
179
+ * 自底部向上布局时的**顶部留白行数**。
180
+ *
181
+ * 内容行数不足一帧时,用空白行把内容顶到下方(吸底),而不是让它飘在顶部:
182
+ * 短帧飘在顶部时,从「对话屏整帧」切过来的那一次重绘会因擦除/滚动错位被顶出视口,
183
+ * 在 VS Code 等终端里表现为内容被截掉。顶到下方后,两种屏幕的帧高一致、内容贴底,
184
+ * 既不会被裁剪,也顺带消掉了帧高突变带来的擦除错位。
185
+ *
186
+ * 传入行数超过一帧时返回 0(由调用方负责限制内容行数)。
187
+ */
188
+ export function bottomPadding(terminalRows, contentLines) {
189
+ return Math.max(0, usableFrameRows(terminalRows) - Math.max(0, contentLines));
190
+ }
191
+ /**
192
+ * 去掉 CwdTrackerPlugin 追加在用户消息末尾的工作目录提示。
193
+ * 该提示是喂给模型的上下文,不该显示给用户。
194
+ */
195
+ export function stripCwdNote(text) {
196
+ return text.replace(/\n+(?:\[工作目录变更\]\n)?当前工作目录: [^\n]*$/, "");
197
+ }
198
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/tui/text.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * TUI 主题与视觉元素 —— 颜色、渐变色与 ASCII Logo
3
+ *
4
+ * 设计原则:
5
+ * - 渐变只产出**每字符的 hex 颜色**,交由 Ink 的 `<Text color>` 渲染(不使用 chalk);
6
+ * - 颜色是否生效由 Ink 依终端能力决定(无色终端自动退化为纯文本);
7
+ * - Logo 提供「宽 / 窄」两套,按终端宽度选择,避免折行破坏构图。
8
+ */
9
+ /** 品牌色板(tailwind 近似色) */
10
+ export declare const theme: {
11
+ brand: readonly ["#22d3ee", "#818cf8", "#f472b6"];
12
+ accent: string;
13
+ user: string;
14
+ assistant: string;
15
+ reasoning: string;
16
+ tool: string;
17
+ error: string;
18
+ ok: string;
19
+ warn: string;
20
+ dim: string;
21
+ faint: string;
22
+ border: string;
23
+ highlight: string;
24
+ };
25
+ /** 语法高亮:一段文本的样式覆盖(缺省字段沿用所在行的基础色) */
26
+ export interface TextStyle {
27
+ color?: string;
28
+ dim?: boolean;
29
+ bold?: boolean;
30
+ italic?: boolean;
31
+ }
32
+ /**
33
+ * 语法高亮色板 —— 键为 highlight.js 的 scope(`highlight.ts` 已去掉 `hljs-` 前缀),
34
+ * 供工具调用参数(JSON)、围栏代码块与**正文 markdown 源码着色**共用。
35
+ *
36
+ * 约定:
37
+ * - **不写死近白 / 近黑**(如 #e2e8f0 / #000000)——在亮色或暗色终端之一里会看不见字;
38
+ * 无颜色的 token 一律回落到**终端默认前景色**,需要区分时用 `bold` / `italic` / `dim` 等
39
+ * **终端相对属性**(`strong` / `emphasis` / `quote` 即如此)。
40
+ * - 绝对色只用于**强调**(关键字、字符串、标题等),且尽量取中间调。
41
+ */
42
+ export declare const syntax: Record<string, TextStyle>;
43
+ /** 把 highlight.js 的 scope 映射为具体样式;未知 scope 返回空(沿用基础色) */
44
+ export declare function syntaxStyle(scope: string): TextStyle;
45
+ type RGB = [number, number, number];
46
+ export declare function parseHex(hex: string): RGB;
47
+ export declare function toHex([r, g, b]: RGB): string;
48
+ /** 在两色之间线性插值 */
49
+ export declare function mixColor(a: string, b: string, t: number): string;
50
+ /** 给定一组颜色停靠点,取 `t`(0..1) 处的颜色(超出范围按循环处理) */
51
+ export declare function gradientAt(stops: readonly string[], t: number): string;
52
+ /** 宽版 Logo(约 42 列) */
53
+ export declare const LOGO_WIDE: string[];
54
+ /** 宽版 Logo 的显示宽度 */
55
+ export declare const LOGO_WIDE_WIDTH: number;
56
+ /** 窄版 Logo(单行,用于窄终端) */
57
+ export declare const LOGO_COMPACT: string[];
58
+ /** 选择与终端宽度相匹配的 Logo 行 */
59
+ export declare function pickLogo(columns: number): string[];
60
+ /**
61
+ * 计算 Logo 每个字符的渐变色(hex),供 Ink `<Text color>` 渲染。
62
+ * 空格返回 `undefined`(不着色);其余为「对角渐变 + 扫光」色。
63
+ * @param lines Logo 文本行
64
+ * @param phase 扫光相位(0..1,随时间推进产生流动感)
65
+ */
66
+ export declare function logoGradientColors(lines: string[], phase?: number): (string | undefined)[][];
67
+ export {};
68
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/tui/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,yBAAyB;AACzB,eAAO,MAAM,KAAK;;;;;;;;;;;;;;CAcjB,CAAC;AAEF,oCAAoC;AACpC,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CA6B5C,CAAC;AAEF,yDAAyD;AACzD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAEpD;AAID,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAEpC,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAOzC;AAED,wBAAgB,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM,CAG5C;AAED,gBAAgB;AAChB,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAIhE;AAED,4CAA4C;AAC5C,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAQtE;AAID,sBAAsB;AACtB,eAAO,MAAM,SAAS,EAAE,MAAM,EAO7B,CAAC;AAEF,oBAAoB;AACpB,eAAO,MAAM,eAAe,QAA8C,CAAC;AAE3E,wBAAwB;AACxB,eAAO,MAAM,YAAY,EAAE,MAAM,EAAqB,CAAC;AAEvD,yBAAyB;AACzB,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAElD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,SAAI,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,EAAE,CAUvF"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * TUI 主题与视觉元素 —— 颜色、渐变色与 ASCII Logo
3
+ *
4
+ * 设计原则:
5
+ * - 渐变只产出**每字符的 hex 颜色**,交由 Ink 的 `<Text color>` 渲染(不使用 chalk);
6
+ * - 颜色是否生效由 Ink 依终端能力决定(无色终端自动退化为纯文本);
7
+ * - Logo 提供「宽 / 窄」两套,按终端宽度选择,避免折行破坏构图。
8
+ */
9
+ /** 品牌色板(tailwind 近似色) */
10
+ export const theme = {
11
+ brand: ["#22d3ee", "#818cf8", "#f472b6"],
12
+ accent: "#a78bfa",
13
+ user: "#22d3ee",
14
+ assistant: "#e2e8f0",
15
+ reasoning: "#8b9cb3",
16
+ tool: "#fbbf24",
17
+ error: "#f87171",
18
+ ok: "#34d399",
19
+ warn: "#fbbf24",
20
+ dim: "#64748b",
21
+ faint: "#475569",
22
+ border: "#334155",
23
+ highlight: "#c4b5fd",
24
+ };
25
+ /**
26
+ * 语法高亮色板 —— 键为 highlight.js 的 scope(`highlight.ts` 已去掉 `hljs-` 前缀),
27
+ * 供工具调用参数(JSON)、围栏代码块与**正文 markdown 源码着色**共用。
28
+ *
29
+ * 约定:
30
+ * - **不写死近白 / 近黑**(如 #e2e8f0 / #000000)——在亮色或暗色终端之一里会看不见字;
31
+ * 无颜色的 token 一律回落到**终端默认前景色**,需要区分时用 `bold` / `italic` / `dim` 等
32
+ * **终端相对属性**(`strong` / `emphasis` / `quote` 即如此)。
33
+ * - 绝对色只用于**强调**(关键字、字符串、标题等),且尽量取中间调。
34
+ */
35
+ export const syntax = {
36
+ keyword: { color: "#c4b5fd", bold: true },
37
+ built_in: { color: "#67e8f9" },
38
+ type: { color: "#5eead4" },
39
+ literal: { color: "#c4b5fd" },
40
+ number: { color: "#fca5a5" },
41
+ string: { color: "#86efac" },
42
+ comment: { color: "#64748b", italic: true, dim: true },
43
+ attr: { color: "#7dd3fc" },
44
+ attribute: { color: "#7dd3fc" },
45
+ property: { color: "#7dd3fc" },
46
+ title: { color: "#fbbf24" },
47
+ function: { color: "#fbbf24" },
48
+ selector: { color: "#fbbf24" },
49
+ tag: { color: "#f472b6" },
50
+ name: { color: "#f472b6" },
51
+ punctuation: { color: "#64748b" },
52
+ operator: { color: "#94a3b8" },
53
+ meta: { color: "#94a3b8" },
54
+ addition: { color: "#86efac" },
55
+ deletion: { color: "#f87171" },
56
+ // ---- markdown 源码着色(highlight.js 的 markdown 词法)----
57
+ section: { color: "#a78bfa", bold: true }, // 标题(#)
58
+ strong: { bold: true }, // 粗体 **x**(无颜色 → 终端默认前景色 + 加粗)
59
+ emphasis: { italic: true }, // 斜体 *x*
60
+ bullet: { color: "#a78bfa" }, // 列表标记 -
61
+ quote: { dim: true }, // 引用 >(终端相对变暗)
62
+ code: { color: "#7dd3fc" }, // 行内代码 `x`
63
+ link: { color: "#7dd3fc" }, // 链接地址
64
+ };
65
+ /** 把 highlight.js 的 scope 映射为具体样式;未知 scope 返回空(沿用基础色) */
66
+ export function syntaxStyle(scope) {
67
+ return scope ? (syntax[scope] ?? {}) : {};
68
+ }
69
+ export function parseHex(hex) {
70
+ const h = hex.replace("#", "");
71
+ return [
72
+ Number.parseInt(h.slice(0, 2), 16),
73
+ Number.parseInt(h.slice(2, 4), 16),
74
+ Number.parseInt(h.slice(4, 6), 16),
75
+ ];
76
+ }
77
+ export function toHex([r, g, b]) {
78
+ const c = (n) => Math.max(0, Math.min(255, Math.round(n))).toString(16).padStart(2, "0");
79
+ return `#${c(r)}${c(g)}${c(b)}`;
80
+ }
81
+ /** 在两色之间线性插值 */
82
+ export function mixColor(a, b, t) {
83
+ const [r1, g1, b1] = parseHex(a);
84
+ const [r2, g2, b2] = parseHex(b);
85
+ return toHex([r1 + (r2 - r1) * t, g1 + (g2 - g1) * t, b1 + (b2 - b1) * t]);
86
+ }
87
+ /** 给定一组颜色停靠点,取 `t`(0..1) 处的颜色(超出范围按循环处理) */
88
+ export function gradientAt(stops, t) {
89
+ const n = stops.length;
90
+ if (n === 1)
91
+ return stops[0];
92
+ const wrapped = ((t % 1) + 1) % 1;
93
+ const scaled = wrapped * (n - 1);
94
+ const i = Math.floor(scaled);
95
+ const f = scaled - i;
96
+ return mixColor(stops[i], stops[(i + 1) % n], f);
97
+ }
98
+ // ==================== ASCII Logo ====================
99
+ /** 宽版 Logo(约 42 列) */
100
+ export const LOGO_WIDE = [
101
+ " █████╗ ██╗ ███████╗███████╗███╗ ██╗",
102
+ "██╔══██╗██║ ╚══███╔╝██╔════╝████╗ ██║",
103
+ "███████║██║ ███╔╝ █████╗ ██╔██╗ ██║",
104
+ "██╔══██║██║ ███╔╝ ██╔══╝ ██║╚██╗██║",
105
+ "██║ ██║██║ ███████╗███████╗██║ ╚████║",
106
+ "╚═╝ ╚═╝╚═╝ ╚══════╝╚══════╝╚═╝ ╚═══╝",
107
+ ];
108
+ /** 宽版 Logo 的显示宽度 */
109
+ export const LOGO_WIDE_WIDTH = Math.max(...LOGO_WIDE.map((l) => l.length));
110
+ /** 窄版 Logo(单行,用于窄终端) */
111
+ export const LOGO_COMPACT = ["◢ AI · ZEN ◣"];
112
+ /** 选择与终端宽度相匹配的 Logo 行 */
113
+ export function pickLogo(columns) {
114
+ return columns >= LOGO_WIDE_WIDTH + 6 ? LOGO_WIDE : LOGO_COMPACT;
115
+ }
116
+ /**
117
+ * 计算 Logo 每个字符的渐变色(hex),供 Ink `<Text color>` 渲染。
118
+ * 空格返回 `undefined`(不着色);其余为「对角渐变 + 扫光」色。
119
+ * @param lines Logo 文本行
120
+ * @param phase 扫光相位(0..1,随时间推进产生流动感)
121
+ */
122
+ export function logoGradientColors(lines, phase = 0) {
123
+ const height = lines.length;
124
+ const width = Math.max(...lines.map((l) => l.length), 1);
125
+ return lines.map((line, y) => [...line].map((ch, x) => {
126
+ if (ch === " ")
127
+ return undefined;
128
+ const t = (x / width) * 0.7 + (y / Math.max(height - 1, 1)) * 0.3 + phase;
129
+ return gradientAt(theme.brand, t);
130
+ }));
131
+ }
132
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/tui/theme.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -2,12 +2,11 @@
2
2
  * CLI 类型定义
3
3
  *
4
4
  * 配置/Agent 等共享实体类型委托给 @ai-zen/agents-sdk。
5
- * 会话(Conversation)/草稿(Draft)是 CLI 的产品数据,定义在 conversation-repository.ts / draft-repository.ts。
5
+ * 会话(Conversation)是 CLI 的产品数据,定义在 conversation-repository.ts。
6
6
  */
7
7
  export type { AppConfig, Endpoint, Model, ImageModel, AgentDefinition, AgentPermissions, McpServerConfig, McpServerManifest, } from "@ai-zen/agents-sdk";
8
8
  export type { Conversation } from "./conversation-repository.js";
9
- export type { Draft } from "./draft-repository.js";
10
- import type { SdkAgent, TaskMigrationService } from "@ai-zen/agents-sdk";
9
+ import type { SdkAgent, HandoffService } from "@ai-zen/agents-sdk";
11
10
  export interface ConversationContext {
12
11
  agent: SdkAgent;
13
12
  input: string;
@@ -17,8 +16,11 @@ export interface ConversationContext {
17
16
  agentId: string | undefined;
18
17
  running: boolean;
19
18
  shouldSend?: boolean;
20
- /** 迁移服务实例:自动迁移(AutoMigratePlugin)与手动迁移(/migrate 命令)共用同一实例。先建 ctx 再回填(migrate 前必已赋值) */
21
- migrationService?: TaskMigrationService;
19
+ /**
20
+ * 交接服务实例:自动迁移、`/migrate`、`/handoff` 共用同一实例。
21
+ * 先建 ctx 再回填(交接前必已赋值)。
22
+ */
23
+ handoffService?: HandoffService;
22
24
  }
23
25
  export type CommandHandler = (ctx: ConversationContext) => Promise<void>;
24
26
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY,EACV,SAAS,EACT,QAAQ,EACR,KAAK,EACL,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,KAAK,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAEzE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;CACzC;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY,EACV,SAAS,EACT,QAAQ,EACR,KAAK,EACL,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEnE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC"}
package/dist/types.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * CLI 类型定义
3
3
  *
4
4
  * 配置/Agent 等共享实体类型委托给 @ai-zen/agents-sdk。
5
- * 会话(Conversation)/草稿(Draft)是 CLI 的产品数据,定义在 conversation-repository.ts / draft-repository.ts。
5
+ * 会话(Conversation)是 CLI 的产品数据,定义在 conversation-repository.ts。
6
6
  */
7
7
  export {};
8
8
  //# sourceMappingURL=types.js.map
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@ai-zen/cli",
3
- "version": "0.9.0",
4
- "description": "AI-ZEN CLI - interactive conversation terminal with file tools and draft recovery",
3
+ "version": "1.0.0-alpha.10",
4
+ "description": "AI-ZEN CLI - dual-mode AI terminal: pure stdio pipelines and an interactive TUI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "type": "module",
8
8
  "bin": {
9
+ "ai": "dist/index.js",
9
10
  "aiz": "dist/index.js",
10
11
  "zen": "dist/index.js"
11
12
  },
@@ -20,18 +21,22 @@
20
21
  "author": "LZQCN",
21
22
  "license": "MIT",
22
23
  "dependencies": {
23
- "@ai-zen/agents-core": "^4.3.0",
24
- "@ai-zen/agents-sdk": "1.0.0-alpha.0",
24
+ "@ai-zen/agents-core": "^4.5.1",
25
+ "@ai-zen/agents-sdk": "1.0.0-alpha.10",
25
26
  "@modelcontextprotocol/sdk": "^1.29.0",
26
- "chalk": "^5.3.0",
27
27
  "dayjs": "^1.11.21",
28
- "inquirer": "^9.2.12",
28
+ "highlight.js": "^11.12.0",
29
+ "ink": "^7.1.1",
30
+ "lowlight": "^3.3.0",
31
+ "react": "^19.3.0",
29
32
  "zod": "^4.4.3"
30
33
  },
31
34
  "devDependencies": {
32
- "@types/inquirer": "^9.0.7",
35
+ "@types/hast": "^3.0.5",
33
36
  "@types/node": "^24.12.2",
37
+ "@types/react": "^19.3.0",
34
38
  "dotenv": "^17.4.2",
39
+ "ink-testing-library": "^4.0.0",
35
40
  "rimraf": "^6.0.0",
36
41
  "typescript": "^5.3.3",
37
42
  "vitest": "^4.1.9"
@@ -1,58 +0,0 @@
1
- /**
2
- * AutoMigrateConfirmPlugin — 自动迁移「二次确认」插件(CLI 层)。
3
- *
4
- * 背景:SDK 的 `AutoMigratePlugin` 在 `usage.prompt_tokens` 超过阈值时**静默**触发迁移,
5
- * 而迁移会保存当前对话并以交接文档开启新会话。为让用户对这次「上下文切换」有知情权与
6
- * 否决权,CLI 在自动迁移前补一道二次确认。
7
- *
8
- * 职责边界(沿用 SDK 的分工,不重复实现「何时迁移」的语义):
9
- * - 是否触发:本插件先向用户确认,得到许可后委托基类的 `onAfterSend` 完成阈值判断与迁移调用;
10
- * - 实际迁移:仍由共享的 `TaskMigrationService` 实例执行(与 /migrate 手动迁移同一条链路)。
11
- * 因此本插件的增量仅有一处:在超阈值与调用迁移之间插入一次确认。
12
- *
13
- * 交互约定:
14
- * - 仅在 stdin 与 stdout **均为 TTY**(人类交互终端)时询问;
15
- * - 非交互环境(管道、重定向、e2e 脚本)没有确认通道,保持既有行为——直接自动迁移,
16
- * 不阻塞等待输入、不额外输出,管道语义不变;
17
- * - 确认框默认「是」(回车即迁移),与 /migrate 手动迁移的默认值保持一致;
18
- * - 用户拒绝时仅跳过**本次**迁移,不记录任何隐式状态:只要仍处于超限状态,下次发送后
19
- * 会再次询问;跳过不影响当前对话(历史未被剔除,语义与迁移前一致)。
20
- */
21
- import { AutoMigratePlugin } from "@ai-zen/agents-sdk";
22
- import type { SendContext, TaskMigrationService } from "@ai-zen/agents-sdk";
23
- /** 触发自动迁移时的用量信息(供确认文案与自定义询问实现使用) */
24
- export interface AutoMigrateTriggerInfo {
25
- /** 当前 prompt token 用量 */
26
- promptTokens: number;
27
- /** 上下文阈值(当前模型的 maxContextTokens) */
28
- maxTokens: number;
29
- }
30
- export interface AutoMigrateConfirmOptions {
31
- /** 迁移服务实例(与手动迁移 /migrate 共用同一实例) */
32
- service: TaskMigrationService;
33
- /** 触发迁移的上下文阈值 */
34
- maxTokens: number;
35
- /** 是否需要向用户确认;默认「stdin 与 stdout 均为 TTY」。可注入,便于单测 */
36
- shouldConfirm?: () => boolean;
37
- /** 确认实现;默认为 inquirer 确认框。可注入,便于单测 */
38
- confirm?: (info: AutoMigrateTriggerInfo) => Promise<boolean>;
39
- }
40
- /** 默认交互判定:仅当 stdin 与 stdout 均为 TTY 时才具备确认通道 */
41
- export declare function canPromptUser(): boolean;
42
- /**
43
- * 默认确认实现:inquirer 确认框。
44
- * 默认「是」——回车即迁移,保持自动迁移的既有默认行为不被阻塞。
45
- */
46
- export declare function confirmAutoMigrate(info: AutoMigrateTriggerInfo): Promise<boolean>;
47
- /**
48
- * 自动迁移二次确认插件。
49
- *
50
- * 继承 SDK 的 `AutoMigratePlugin` 以复用其触发语义(阈值判断 + 委托共享迁移服务),
51
- * 仅在「超阈值」与「调用迁移」之间插入一次用户确认。
52
- */
53
- export declare class AutoMigrateConfirmPlugin extends AutoMigratePlugin {
54
- private readonly confirmOptions;
55
- constructor(options: AutoMigrateConfirmOptions);
56
- onAfterSend(ctx: SendContext): Promise<void>;
57
- }
58
- //# sourceMappingURL=auto-migrate-confirm-plugin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auto-migrate-confirm-plugin.d.ts","sourceRoot":"","sources":["../src/auto-migrate-confirm-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE5E,oCAAoC;AACpC,MAAM,WAAW,sBAAsB;IACrC,yBAAyB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,oCAAoC;IACpC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC;IAC9B,qCAAqC;IACrC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D;AAED,+CAA+C;AAC/C,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAalB;AAED;;;;;GAKG;AACH,qBAAa,wBAAyB,SAAQ,iBAAiB;IAC7D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA4B;gBAE/C,OAAO,EAAE,yBAAyB;IAKxC,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAmCnD"}