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

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 (298) hide show
  1. package/CHANGELOG.md +42 -1
  2. package/README.md +94 -40
  3. package/README.zh.md +94 -40
  4. package/dist/agent-creator.d.ts +7 -1
  5. package/dist/agent-creator.d.ts.map +1 -1
  6. package/dist/agent-creator.js +16 -1
  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-plugin.d.ts +7 -7
  13. package/dist/auto-migrate-confirm-plugin.d.ts.map +1 -1
  14. package/dist/auto-migrate-confirm-plugin.js +3 -21
  15. package/dist/auto-migrate-confirm-plugin.js.map +1 -1
  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 +41 -16
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/config.js +32 -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 +9 -6
  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/hook.d.ts.map +1 -1
  39. package/dist/hook.js +58 -46
  40. package/dist/hook.js.map +1 -1
  41. package/dist/index.js +65 -36
  42. package/dist/index.js.map +1 -1
  43. package/dist/migration-service.d.ts +3 -1
  44. package/dist/migration-service.d.ts.map +1 -1
  45. package/dist/migration-service.js +26 -23
  46. package/dist/migration-service.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 +22 -0
  52. package/dist/session-pointer.d.ts.map +1 -0
  53. package/dist/session-pointer.js +49 -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 +100 -0
  60. package/dist/tui/chat-session.d.ts.map +1 -0
  61. package/dist/tui/chat-session.js +263 -0
  62. package/dist/tui/chat-session.js.map +1 -0
  63. package/dist/tui/components.d.ts +44 -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 +138 -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 +33 -0
  150. package/dist/tui/config-wizard/wizard.js.map +1 -0
  151. package/dist/tui/highlight.d.ts +34 -0
  152. package/dist/tui/highlight.d.ts.map +1 -0
  153. package/dist/tui/highlight.js +116 -0
  154. package/dist/tui/highlight.js.map +1 -0
  155. package/dist/tui/index.d.ts +33 -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 +27 -0
  160. package/dist/tui/screens/chat-commands.d.ts.map +1 -0
  161. package/dist/tui/screens/chat-commands.js +176 -0
  162. package/dist/tui/screens/chat-commands.js.map +1 -0
  163. package/dist/tui/screens/chat.d.ts +25 -0
  164. package/dist/tui/screens/chat.d.ts.map +1 -0
  165. package/dist/tui/screens/chat.js +494 -0
  166. package/dist/tui/screens/chat.js.map +1 -0
  167. package/dist/tui/screens/index.d.ts +13 -0
  168. package/dist/tui/screens/index.d.ts.map +1 -0
  169. package/dist/tui/screens/index.js +14 -0
  170. package/dist/tui/screens/index.js.map +1 -0
  171. package/dist/tui/screens/input.d.ts +29 -0
  172. package/dist/tui/screens/input.d.ts.map +1 -0
  173. package/dist/tui/screens/input.js +54 -0
  174. package/dist/tui/screens/input.js.map +1 -0
  175. package/dist/tui/screens/layout.d.ts +42 -0
  176. package/dist/tui/screens/layout.d.ts.map +1 -0
  177. package/dist/tui/screens/layout.js +45 -0
  178. package/dist/tui/screens/layout.js.map +1 -0
  179. package/dist/tui/screens/lines.d.ts +71 -0
  180. package/dist/tui/screens/lines.d.ts.map +1 -0
  181. package/dist/tui/screens/lines.js +198 -0
  182. package/dist/tui/screens/lines.js.map +1 -0
  183. package/dist/tui/screens/overlays.d.ts +12 -0
  184. package/dist/tui/screens/overlays.d.ts.map +1 -0
  185. package/dist/tui/screens/overlays.js +34 -0
  186. package/dist/tui/screens/overlays.js.map +1 -0
  187. package/dist/tui/screens/render.d.ts +9 -0
  188. package/dist/tui/screens/render.d.ts.map +1 -0
  189. package/dist/tui/screens/render.js +97 -0
  190. package/dist/tui/screens/render.js.map +1 -0
  191. package/dist/tui/screens/splash.d.ts +5 -0
  192. package/dist/tui/screens/splash.d.ts.map +1 -0
  193. package/dist/tui/screens/splash.js +51 -0
  194. package/dist/tui/screens/splash.js.map +1 -0
  195. package/dist/tui/screens/state.d.ts +13 -0
  196. package/dist/tui/screens/state.d.ts.map +1 -0
  197. package/dist/tui/screens/state.js +75 -0
  198. package/dist/tui/screens/state.js.map +1 -0
  199. package/dist/tui/text.d.ts +71 -0
  200. package/dist/tui/text.d.ts.map +1 -0
  201. package/dist/tui/text.js +191 -0
  202. package/dist/tui/text.js.map +1 -0
  203. package/dist/tui/theme.d.ts +62 -0
  204. package/dist/tui/theme.d.ts.map +1 -0
  205. package/dist/tui/theme.js +120 -0
  206. package/dist/tui/theme.js.map +1 -0
  207. package/dist/types.d.ts +1 -2
  208. package/dist/types.d.ts.map +1 -1
  209. package/dist/types.js +1 -1
  210. package/package.json +11 -6
  211. package/dist/config-wizard.d.ts +0 -6
  212. package/dist/config-wizard.d.ts.map +0 -1
  213. package/dist/config-wizard.js +0 -46
  214. package/dist/config-wizard.js.map +0 -1
  215. package/dist/conversation-commands/back.d.ts +0 -3
  216. package/dist/conversation-commands/back.d.ts.map +0 -1
  217. package/dist/conversation-commands/back.js +0 -144
  218. package/dist/conversation-commands/back.js.map +0 -1
  219. package/dist/conversation-commands/clear.d.ts +0 -3
  220. package/dist/conversation-commands/clear.d.ts.map +0 -1
  221. package/dist/conversation-commands/clear.js +0 -8
  222. package/dist/conversation-commands/clear.js.map +0 -1
  223. package/dist/conversation-commands/editor.d.ts +0 -3
  224. package/dist/conversation-commands/editor.d.ts.map +0 -1
  225. package/dist/conversation-commands/editor.js +0 -15
  226. package/dist/conversation-commands/editor.js.map +0 -1
  227. package/dist/conversation-commands/exit.d.ts +0 -3
  228. package/dist/conversation-commands/exit.d.ts.map +0 -1
  229. package/dist/conversation-commands/exit.js +0 -37
  230. package/dist/conversation-commands/exit.js.map +0 -1
  231. package/dist/conversation-commands/help.d.ts +0 -3
  232. package/dist/conversation-commands/help.d.ts.map +0 -1
  233. package/dist/conversation-commands/help.js +0 -10
  234. package/dist/conversation-commands/help.js.map +0 -1
  235. package/dist/conversation-commands/index.d.ts +0 -13
  236. package/dist/conversation-commands/index.d.ts.map +0 -1
  237. package/dist/conversation-commands/index.js +0 -66
  238. package/dist/conversation-commands/index.js.map +0 -1
  239. package/dist/conversation-commands/migrate.d.ts +0 -12
  240. package/dist/conversation-commands/migrate.d.ts.map +0 -1
  241. package/dist/conversation-commands/migrate.js +0 -56
  242. package/dist/conversation-commands/migrate.js.map +0 -1
  243. package/dist/conversation-commands/new.d.ts +0 -3
  244. package/dist/conversation-commands/new.d.ts.map +0 -1
  245. package/dist/conversation-commands/new.js +0 -45
  246. package/dist/conversation-commands/new.js.map +0 -1
  247. package/dist/conversation-commands/save.d.ts +0 -3
  248. package/dist/conversation-commands/save.d.ts.map +0 -1
  249. package/dist/conversation-commands/save.js +0 -32
  250. package/dist/conversation-commands/save.js.map +0 -1
  251. package/dist/conversation-runner.d.ts +0 -17
  252. package/dist/conversation-runner.d.ts.map +0 -1
  253. package/dist/conversation-runner.js +0 -176
  254. package/dist/conversation-runner.js.map +0 -1
  255. package/dist/delta-renderer.d.ts +0 -33
  256. package/dist/delta-renderer.d.ts.map +0 -1
  257. package/dist/delta-renderer.js +0 -120
  258. package/dist/delta-renderer.js.map +0 -1
  259. package/dist/draft-plugin.d.ts +0 -19
  260. package/dist/draft-plugin.d.ts.map +0 -1
  261. package/dist/draft-plugin.js +0 -30
  262. package/dist/draft-plugin.js.map +0 -1
  263. package/dist/draft-repository.d.ts +0 -34
  264. package/dist/draft-repository.d.ts.map +0 -1
  265. package/dist/draft-repository.js +0 -64
  266. package/dist/draft-repository.js.map +0 -1
  267. package/dist/menus/agents.d.ts +0 -5
  268. package/dist/menus/agents.d.ts.map +0 -1
  269. package/dist/menus/agents.js +0 -219
  270. package/dist/menus/agents.js.map +0 -1
  271. package/dist/menus/common.d.ts +0 -41
  272. package/dist/menus/common.d.ts.map +0 -1
  273. package/dist/menus/common.js +0 -104
  274. package/dist/menus/common.js.map +0 -1
  275. package/dist/menus/config-display.d.ts +0 -2
  276. package/dist/menus/config-display.d.ts.map +0 -1
  277. package/dist/menus/config-display.js +0 -82
  278. package/dist/menus/config-display.js.map +0 -1
  279. package/dist/menus/config.d.ts +0 -8
  280. package/dist/menus/config.d.ts.map +0 -1
  281. package/dist/menus/config.js +0 -407
  282. package/dist/menus/config.js.map +0 -1
  283. package/dist/menus/conversations.d.ts +0 -20
  284. package/dist/menus/conversations.d.ts.map +0 -1
  285. package/dist/menus/conversations.js +0 -83
  286. package/dist/menus/conversations.js.map +0 -1
  287. package/dist/menus/index.d.ts +0 -5
  288. package/dist/menus/index.d.ts.map +0 -1
  289. package/dist/menus/index.js +0 -59
  290. package/dist/menus/index.js.map +0 -1
  291. package/dist/menus/start-conversation.d.ts +0 -16
  292. package/dist/menus/start-conversation.d.ts.map +0 -1
  293. package/dist/menus/start-conversation.js +0 -176
  294. package/dist/menus/start-conversation.js.map +0 -1
  295. package/dist/slash-hint-prompt.d.ts +0 -41
  296. package/dist/slash-hint-prompt.d.ts.map +0 -1
  297. package/dist/slash-hint-prompt.js +0 -92
  298. package/dist/slash-hint-prompt.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splash.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/splash.tsx"],"names":[],"mappings":"AASA,eAAO,MAAM,OAAO,mDAAgB,CAAC;AAErC,wBAAgB,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,+BA4EzD"}
@@ -0,0 +1,51 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // 由 src/tui/screens.tsx 拆分而来 —— 启动界面 Splash
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { Box, Text, useApp, useInput, useWindowSize } from "ink";
5
+ import { theme, pickLogo, logoGradientColors } from "../theme.js";
6
+ import { Spinner } from "../components.js";
7
+ import { CLI_VERSION, SDK_VERSION, CORE_VERSION } from "../../version.js";
8
+ // ==================== Splash(启动界面)====================
9
+ export const TAGLINE = "终端里的 AI 协作台";
10
+ export function Splash({ onDone }) {
11
+ const { exit } = useApp();
12
+ const { columns, rows } = useWindowSize();
13
+ const logo = pickLogo(columns ?? 80);
14
+ const [revealed, setRevealed] = useState(0);
15
+ const [phase, setPhase] = useState(0);
16
+ const [ready, setReady] = useState(false);
17
+ const doneRef = useRef(false);
18
+ const finish = () => {
19
+ if (doneRef.current)
20
+ return;
21
+ doneRef.current = true;
22
+ onDone?.();
23
+ exit("done");
24
+ };
25
+ useEffect(() => {
26
+ const revealTimer = setInterval(() => setRevealed((r) => Math.min(r + 1, logo.length)), 55);
27
+ const sweepTimer = setInterval(() => setPhase((p) => Math.min(p + 0.05, 1)), 35);
28
+ return () => {
29
+ clearInterval(revealTimer);
30
+ clearInterval(sweepTimer);
31
+ };
32
+ }, [logo.length]);
33
+ useEffect(() => {
34
+ if (revealed >= logo.length && phase >= 1)
35
+ setReady(true);
36
+ }, [revealed, phase, logo.length]);
37
+ useEffect(() => {
38
+ if (!ready)
39
+ return;
40
+ const timer = setTimeout(finish, 1100);
41
+ return () => clearTimeout(timer);
42
+ // eslint-disable-next-line react-hooks/exhaustive-deps
43
+ }, [ready]);
44
+ useInput(() => finish());
45
+ const totalRows = rows ?? 24;
46
+ const padTop = Math.max(0, Math.floor((totalRows - (logo.length + 9)) / 2));
47
+ const visibleLogo = logo.slice(0, revealed);
48
+ const logoColors = logoGradientColors(visibleLogo, phase);
49
+ return (_jsxs(Box, { flexDirection: "column", alignItems: "center", paddingTop: padTop, width: columns, children: [_jsx(Box, { flexDirection: "column", alignItems: "center", children: visibleLogo.map((line, i) => (_jsx(Text, { children: [...line].map((ch, x) => (_jsx(Text, { color: logoColors[i]?.[x], children: ch }, x))) }, i))) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.accent, children: TAGLINE }) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: theme.dim, children: ["v", CLI_VERSION, " \u00B7 sdk ", SDK_VERSION, " \u00B7 core ", CORE_VERSION] }) }), _jsx(Box, { marginTop: 2, flexDirection: "column", alignItems: "center", children: ready ? (_jsx(Text, { color: theme.faint, children: "\u6309\u4EFB\u610F\u952E\u5F00\u59CB\u2026" })) : (_jsx(Spinner, { label: "\u6B63\u5728\u51C6\u5907" })) })] }));
50
+ }
51
+ //# sourceMappingURL=splash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splash.js","sourceRoot":"","sources":["../../../src/tui/screens/splash.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { ChatEvent } from "../chat-session.js";
2
+ import { Block, LiveAssistant } from "./lines.js";
3
+ export interface ChatState {
4
+ blocks: Block[];
5
+ live: LiveAssistant | null;
6
+ }
7
+ export type ChatAction = ChatEvent | {
8
+ type: "clear";
9
+ };
10
+ export declare let blockSeq: number;
11
+ export declare const nextId: () => number;
12
+ export declare function chatReducer(state: ChatState, action: ChatAction): ChatState;
13
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIlD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEvD,eAAO,IAAI,QAAQ,QAAI,CAAC;AACxB,eAAO,MAAM,MAAM,cAAmB,CAAC;AAEvC,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,CAmE3E"}
@@ -0,0 +1,75 @@
1
+ export let blockSeq = 0;
2
+ export const nextId = () => ++blockSeq;
3
+ export function chatReducer(state, action) {
4
+ switch (action.type) {
5
+ case "clear":
6
+ return { blocks: [], live: null };
7
+ case "user":
8
+ return {
9
+ blocks: [...state.blocks, { id: nextId(), kind: "user", text: action.text }],
10
+ live: { reasoning: "", content: "", tools: [], sub: null, roundBase: 0 },
11
+ };
12
+ case "assistant-start":
13
+ // 每次 API 请求(含一轮内并行调用后的后续轮次)都会触发:把本轮工具调用的
14
+ // 起始下标锚到当前已收集的工具数,使新一轮 index 从 0 起也落到新的一行。
15
+ return {
16
+ ...state,
17
+ live: state.live
18
+ ? { ...state.live, roundBase: state.live.tools.length }
19
+ : { reasoning: "", content: "", tools: [], sub: null, roundBase: 0 },
20
+ };
21
+ case "reasoning":
22
+ return state.live
23
+ ? { ...state, live: { ...state.live, reasoning: state.live.reasoning + action.text } }
24
+ : state;
25
+ case "content":
26
+ return state.live
27
+ ? { ...state, live: { ...state.live, content: state.live.content + action.text } }
28
+ : state;
29
+ case "tool": {
30
+ if (!state.live)
31
+ return state;
32
+ // 落到「本轮起始下标 + 本轮内 index」:同一轮内的分片按 index 归并(并行调用
33
+ // 各占一行),跨轮的同 index 因 roundBase 不同而分段,不再相互拼接。
34
+ const pos = (state.live.roundBase ?? 0) + Math.max(0, action.index ?? 0);
35
+ const tools = [...state.live.tools];
36
+ // 保持数组稠密(避免稀疏空位在渲染时被 for...of 迭代为 undefined)
37
+ while (tools.length < pos)
38
+ tools.push({ name: "", args: "" });
39
+ const prev = tools[pos] ?? { name: "", args: "" };
40
+ tools[pos] = {
41
+ name: prev.name + (action.name ?? ""),
42
+ args: prev.args + (action.args ?? ""),
43
+ };
44
+ return { ...state, live: { ...state.live, tools } };
45
+ }
46
+ case "subagent-start":
47
+ return state.live ? { ...state, live: { ...state.live, sub: action.name } } : state;
48
+ case "subagent-end":
49
+ return state.live ? { ...state, live: { ...state.live, sub: null } } : state;
50
+ case "notice":
51
+ return {
52
+ ...state,
53
+ blocks: [...state.blocks, { id: nextId(), kind: "notice", tone: "info", text: action.text }],
54
+ };
55
+ case "error":
56
+ return {
57
+ ...state,
58
+ blocks: [...state.blocks, { id: nextId(), kind: "notice", tone: "error", text: action.text }],
59
+ };
60
+ case "done": {
61
+ if (!state.live)
62
+ return state;
63
+ const { reasoning, content, tools } = state.live;
64
+ // 请求失败时 live 可能为空壳(无思考/内容/工具)——不产生空白的 AI 块
65
+ const isEmpty = !reasoning.trim() && !content.trim() && !tools.some((t) => t.name);
66
+ if (isEmpty)
67
+ return { ...state, live: null };
68
+ const finished = { id: nextId(), kind: "assistant", reasoning, content, tools };
69
+ return { blocks: [...state.blocks, finished], live: null };
70
+ }
71
+ default:
72
+ return state;
73
+ }
74
+ }
75
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/tui/screens/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * TUI 文本度量与折行 —— 纯函数(无 React / Ink 依赖)
3
+ *
4
+ * 从 `screens.tsx` 中抽出,供对话屏、凭据设置屏、配置中心共用,
5
+ * 避免 `screens.tsx ↔ config-wizard.tsx` 相互 import 形成循环依赖。
6
+ */
7
+ /** 终端显示宽度(宽字符计 2,组合字符计 0) */
8
+ export declare function displayWidth(text: string): number;
9
+ /**
10
+ * 按显示宽度把文本折成多行(保留显式换行)。
11
+ * 拉丁文优先在空格处断行,CJK / 超长词按字符硬断;保证每行显示宽度 ≤ limit。
12
+ */
13
+ export declare function wrapText(text: string, limit: number): string[];
14
+ /** 带光标位置的输入区折行结果 */
15
+ export interface InputLayout {
16
+ /** 折行后的各行文本(不含提示符) */
17
+ lines: string[];
18
+ /** 光标所在行(0 起始) */
19
+ cursorRow: number;
20
+ /** 光标在该行内的字符偏移(code point 计) */
21
+ cursorCol: number;
22
+ }
23
+ /**
24
+ * 把输入文本按显示宽度折行,并定位光标(`cursor` 为字符索引,以 code point 计)。
25
+ * 折行采用逐字符硬断(不做空格优先),以保证光标映射精确、支持跨行编辑。
26
+ */
27
+ export declare function layoutInput(text: string, cursor: number, width: number): InputLayout;
28
+ /** 单行输入左侧留白:Box paddingX(1) + 提示符 `❯ `(宽 2) */
29
+ export declare const INPUT_PREFIX_WIDTH = 3;
30
+ /**
31
+ * 判断一段输入是否为「终端应答序列」而非用户输入。
32
+ *
33
+ * 典型来源:
34
+ * - Kitty 键盘协议查询的应答:`CSI ? <flags> u`(Ink 开启 `kittyKeyboard` 时会发 `CSI ? u`);
35
+ * - 光标位置报告(CPR):`CSI <row>;<col> R`;
36
+ * - 设备状态报告:`CSI ? <n> n`。
37
+ *
38
+ * 这类序列本应由 Ink 的解析器整体吞掉。但当它被**拆包**时(前导 ESC 被 Ink 的
39
+ * 「待定转义刷新定时器」当作一次独立的 Escape 键消费),残留在后一个 chunk 里的
40
+ * `[?0u` 会退化成普通文本并被当作输入插入输入框(实测重现)。此处做一层护栏;
41
+ * 根因(不再向终端发查询)已在渲染选项里关闭。
42
+ */
43
+ export declare function isTerminalReply(sequence: string): boolean;
44
+ /**
45
+ * 按显示宽度裁剪文本:超出上限则截断并补省略号(宽字符计 2 列)。
46
+ *
47
+ * 用于列表项等「必须恰好占一行」的场景 —— 让 Ink 不会二次折行,
48
+ * 自底部向上布局时才能精确算出顶部留白。
49
+ */
50
+ export declare function clipWidth(text: string, max: number): string;
51
+ /**
52
+ * 整帧可用高度 = 终端行数 − 1。
53
+ *
54
+ * Ink 在主输出高度 ≥ 终端行数时判定为「全屏」(`ink/build/ink.js`):Windows 控制台下
55
+ * 每帧强制 `clearTerminal`,且渲染串末尾不补换行;但硬件光标定位仍假设「光标停在最后
56
+ * 一行之后」,于是整体上移一行(IME 候选框随之偏上)。预留最后一行,让整帧高度严格小于
57
+ * 终端行数,即可避开该分支,硬件光标与自绘光标精确对齐。
58
+ */
59
+ export declare function usableFrameRows(terminalRows: number): number;
60
+ /**
61
+ * 自底部向上布局时的**顶部留白行数**。
62
+ *
63
+ * 内容行数不足一帧时,用空白行把内容顶到下方(吸底),而不是让它飘在顶部:
64
+ * 短帧飘在顶部时,从「对话屏整帧」切过来的那一次重绘会因擦除/滚动错位被顶出视口,
65
+ * 在 VS Code 等终端里表现为内容被截掉。顶到下方后,两种屏幕的帧高一致、内容贴底,
66
+ * 既不会被裁剪,也顺带消掉了帧高突变带来的擦除错位。
67
+ *
68
+ * 传入行数超过一帧时返回 0(由调用方负责限制内容行数)。
69
+ */
70
+ export declare function bottomPadding(terminalRows: number, contentLines: number): number;
71
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/tui/text.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuBH,6BAA6B;AAC7B,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQjD;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA8B9D;AAID,oBAAoB;AACpB,MAAM,WAAW,WAAW;IAC1B,sBAAsB;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAgDpF;AAED,+CAA+C;AAC/C,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMzD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAY3D;AAID;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEhF"}
@@ -0,0 +1,191 @@
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
+ //# 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,62 @@
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)与围栏代码块共用。暗色主题友好(tailwind 近似色)。
35
+ */
36
+ export declare const syntax: Record<string, TextStyle>;
37
+ /** 把 highlight.js 的 scope 映射为具体样式;未知 scope 返回空(沿用基础色) */
38
+ export declare function syntaxStyle(scope: string): TextStyle;
39
+ type RGB = [number, number, number];
40
+ export declare function parseHex(hex: string): RGB;
41
+ export declare function toHex([r, g, b]: RGB): string;
42
+ /** 在两色之间线性插值 */
43
+ export declare function mixColor(a: string, b: string, t: number): string;
44
+ /** 给定一组颜色停靠点,取 `t`(0..1) 处的颜色(超出范围按循环处理) */
45
+ export declare function gradientAt(stops: readonly string[], t: number): string;
46
+ /** 宽版 Logo(约 42 列) */
47
+ export declare const LOGO_WIDE: string[];
48
+ /** 宽版 Logo 的显示宽度 */
49
+ export declare const LOGO_WIDE_WIDTH: number;
50
+ /** 窄版 Logo(单行,用于窄终端) */
51
+ export declare const LOGO_COMPACT: string[];
52
+ /** 选择与终端宽度相匹配的 Logo 行 */
53
+ export declare function pickLogo(columns: number): string[];
54
+ /**
55
+ * 计算 Logo 每个字符的渐变色(hex),供 Ink `<Text color>` 渲染。
56
+ * 空格返回 `undefined`(不着色);其余为「对角渐变 + 扫光」色。
57
+ * @param lines Logo 文本行
58
+ * @param phase 扫光相位(0..1,随时间推进产生流动感)
59
+ */
60
+ export declare function logoGradientColors(lines: string[], phase?: number): (string | undefined)[][];
61
+ export {};
62
+ //# 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;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAuB5C,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,120 @@
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)与围栏代码块共用。暗色主题友好(tailwind 近似色)。
28
+ */
29
+ export const syntax = {
30
+ keyword: { color: "#c4b5fd", bold: true },
31
+ built_in: { color: "#67e8f9" },
32
+ type: { color: "#5eead4" },
33
+ literal: { color: "#c4b5fd" },
34
+ number: { color: "#fca5a5" },
35
+ string: { color: "#86efac" },
36
+ comment: { color: "#64748b", italic: true, dim: true },
37
+ attr: { color: "#7dd3fc" },
38
+ attribute: { color: "#7dd3fc" },
39
+ property: { color: "#7dd3fc" },
40
+ variable: { color: "#cbd5e1" },
41
+ params: { color: "#cbd5e1" },
42
+ title: { color: "#fbbf24" },
43
+ function: { color: "#fbbf24" },
44
+ selector: { color: "#fbbf24" },
45
+ tag: { color: "#f472b6" },
46
+ name: { color: "#f472b6" },
47
+ punctuation: { color: "#64748b" },
48
+ operator: { color: "#94a3b8" },
49
+ meta: { color: "#94a3b8" },
50
+ addition: { color: "#86efac" },
51
+ deletion: { color: "#f87171" },
52
+ };
53
+ /** 把 highlight.js 的 scope 映射为具体样式;未知 scope 返回空(沿用基础色) */
54
+ export function syntaxStyle(scope) {
55
+ return scope ? (syntax[scope] ?? {}) : {};
56
+ }
57
+ export function parseHex(hex) {
58
+ const h = hex.replace("#", "");
59
+ return [
60
+ Number.parseInt(h.slice(0, 2), 16),
61
+ Number.parseInt(h.slice(2, 4), 16),
62
+ Number.parseInt(h.slice(4, 6), 16),
63
+ ];
64
+ }
65
+ export function toHex([r, g, b]) {
66
+ const c = (n) => Math.max(0, Math.min(255, Math.round(n))).toString(16).padStart(2, "0");
67
+ return `#${c(r)}${c(g)}${c(b)}`;
68
+ }
69
+ /** 在两色之间线性插值 */
70
+ export function mixColor(a, b, t) {
71
+ const [r1, g1, b1] = parseHex(a);
72
+ const [r2, g2, b2] = parseHex(b);
73
+ return toHex([r1 + (r2 - r1) * t, g1 + (g2 - g1) * t, b1 + (b2 - b1) * t]);
74
+ }
75
+ /** 给定一组颜色停靠点,取 `t`(0..1) 处的颜色(超出范围按循环处理) */
76
+ export function gradientAt(stops, t) {
77
+ const n = stops.length;
78
+ if (n === 1)
79
+ return stops[0];
80
+ const wrapped = ((t % 1) + 1) % 1;
81
+ const scaled = wrapped * (n - 1);
82
+ const i = Math.floor(scaled);
83
+ const f = scaled - i;
84
+ return mixColor(stops[i], stops[(i + 1) % n], f);
85
+ }
86
+ // ==================== ASCII Logo ====================
87
+ /** 宽版 Logo(约 42 列) */
88
+ export const LOGO_WIDE = [
89
+ " █████╗ ██╗ ███████╗███████╗███╗ ██╗",
90
+ "██╔══██╗██║ ╚══███╔╝██╔════╝████╗ ██║",
91
+ "███████║██║ ███╔╝ █████╗ ██╔██╗ ██║",
92
+ "██╔══██║██║ ███╔╝ ██╔══╝ ██║╚██╗██║",
93
+ "██║ ██║██║ ███████╗███████╗██║ ╚████║",
94
+ "╚═╝ ╚═╝╚═╝ ╚══════╝╚══════╝╚═╝ ╚═══╝",
95
+ ];
96
+ /** 宽版 Logo 的显示宽度 */
97
+ export const LOGO_WIDE_WIDTH = Math.max(...LOGO_WIDE.map((l) => l.length));
98
+ /** 窄版 Logo(单行,用于窄终端) */
99
+ export const LOGO_COMPACT = ["◢ AI · ZEN ◣"];
100
+ /** 选择与终端宽度相匹配的 Logo 行 */
101
+ export function pickLogo(columns) {
102
+ return columns >= LOGO_WIDE_WIDTH + 6 ? LOGO_WIDE : LOGO_COMPACT;
103
+ }
104
+ /**
105
+ * 计算 Logo 每个字符的渐变色(hex),供 Ink `<Text color>` 渲染。
106
+ * 空格返回 `undefined`(不着色);其余为「对角渐变 + 扫光」色。
107
+ * @param lines Logo 文本行
108
+ * @param phase 扫光相位(0..1,随时间推进产生流动感)
109
+ */
110
+ export function logoGradientColors(lines, phase = 0) {
111
+ const height = lines.length;
112
+ const width = Math.max(...lines.map((l) => l.length), 1);
113
+ return lines.map((line, y) => [...line].map((ch, x) => {
114
+ if (ch === " ")
115
+ return undefined;
116
+ const t = (x / width) * 0.7 + (y / Math.max(height - 1, 1)) * 0.3 + phase;
117
+ return gradientAt(theme.brand, t);
118
+ }));
119
+ }
120
+ //# 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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"}