@wukonglabs/wukong 0.0.19 → 0.0.21

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 (135) hide show
  1. package/dist/cli/help.js +1 -1
  2. package/dist/cli/session-commands.d.ts.map +1 -1
  3. package/dist/cli/session-commands.js +4 -3
  4. package/dist/cli/session-commands.js.map +1 -1
  5. package/dist/index.js +73 -12
  6. package/dist/index.js.map +1 -1
  7. package/dist/tui/activity-verb.d.ts +29 -0
  8. package/dist/tui/activity-verb.d.ts.map +1 -0
  9. package/dist/tui/activity-verb.js +81 -0
  10. package/dist/tui/activity-verb.js.map +1 -0
  11. package/dist/tui/app.d.ts +29 -28
  12. package/dist/tui/app.d.ts.map +1 -1
  13. package/dist/tui/app.js +259 -132
  14. package/dist/tui/app.js.map +1 -1
  15. package/dist/tui/diff-count.d.ts +14 -0
  16. package/dist/tui/diff-count.d.ts.map +1 -0
  17. package/dist/tui/diff-count.js +21 -0
  18. package/dist/tui/diff-count.js.map +1 -0
  19. package/dist/tui/hint-bar.d.ts +12 -0
  20. package/dist/tui/hint-bar.d.ts.map +1 -0
  21. package/dist/tui/hint-bar.js +14 -0
  22. package/dist/tui/hint-bar.js.map +1 -0
  23. package/dist/tui/history-entry.d.ts +11 -0
  24. package/dist/tui/history-entry.d.ts.map +1 -0
  25. package/dist/tui/history-entry.js +35 -0
  26. package/dist/tui/history-entry.js.map +1 -0
  27. package/dist/tui/history-item.d.ts +40 -0
  28. package/dist/tui/history-item.d.ts.map +1 -0
  29. package/dist/tui/history-item.js +8 -0
  30. package/dist/tui/history-item.js.map +1 -0
  31. package/dist/tui/keys-help.d.ts +5 -0
  32. package/dist/tui/keys-help.d.ts.map +1 -0
  33. package/dist/tui/keys-help.js +36 -0
  34. package/dist/tui/keys-help.js.map +1 -0
  35. package/dist/tui/live-block.d.ts +54 -0
  36. package/dist/tui/live-block.d.ts.map +1 -0
  37. package/dist/tui/live-block.js +72 -0
  38. package/dist/tui/live-block.js.map +1 -0
  39. package/dist/tui/main-area.d.ts +40 -0
  40. package/dist/tui/main-area.d.ts.map +1 -0
  41. package/dist/tui/main-area.js +9 -0
  42. package/dist/tui/main-area.js.map +1 -0
  43. package/dist/tui/markdown.d.ts +14 -0
  44. package/dist/tui/markdown.d.ts.map +1 -0
  45. package/dist/tui/markdown.js +134 -0
  46. package/dist/tui/markdown.js.map +1 -0
  47. package/dist/tui/notice-panel.d.ts +20 -0
  48. package/dist/tui/notice-panel.d.ts.map +1 -0
  49. package/dist/tui/notice-panel.js +19 -0
  50. package/dist/tui/notice-panel.js.map +1 -0
  51. package/dist/tui/response-panel.d.ts +12 -16
  52. package/dist/tui/response-panel.d.ts.map +1 -1
  53. package/dist/tui/response-panel.js +8 -11
  54. package/dist/tui/response-panel.js.map +1 -1
  55. package/dist/tui/run-ink.d.ts +12 -0
  56. package/dist/tui/run-ink.d.ts.map +1 -1
  57. package/dist/tui/run-ink.js +2 -1
  58. package/dist/tui/run-ink.js.map +1 -1
  59. package/dist/tui/slash/menu.d.ts +16 -0
  60. package/dist/tui/slash/menu.d.ts.map +1 -0
  61. package/dist/tui/slash/menu.js +11 -0
  62. package/dist/tui/slash/menu.js.map +1 -0
  63. package/dist/tui/slash/parse.d.ts +21 -0
  64. package/dist/tui/slash/parse.d.ts.map +1 -0
  65. package/dist/tui/slash/parse.js +32 -0
  66. package/dist/tui/slash/parse.js.map +1 -0
  67. package/dist/tui/slash/registry.d.ts +20 -0
  68. package/dist/tui/slash/registry.d.ts.map +1 -0
  69. package/dist/tui/slash/registry.js +28 -0
  70. package/dist/tui/slash/registry.js.map +1 -0
  71. package/dist/tui/spinner.d.ts +11 -0
  72. package/dist/tui/spinner.d.ts.map +1 -0
  73. package/dist/tui/spinner.js +21 -0
  74. package/dist/tui/spinner.js.map +1 -0
  75. package/dist/tui/status-bar.d.ts +42 -0
  76. package/dist/tui/status-bar.d.ts.map +1 -0
  77. package/dist/tui/status-bar.js +32 -0
  78. package/dist/tui/status-bar.js.map +1 -0
  79. package/dist/tui/tail-visual.d.ts +11 -0
  80. package/dist/tui/tail-visual.d.ts.map +1 -0
  81. package/dist/tui/tail-visual.js +30 -0
  82. package/dist/tui/tail-visual.js.map +1 -0
  83. package/dist/tui/text-input.d.ts +20 -22
  84. package/dist/tui/text-input.d.ts.map +1 -1
  85. package/dist/tui/text-input.js +211 -81
  86. package/dist/tui/text-input.js.map +1 -1
  87. package/dist/tui/theme/context.d.ts +16 -0
  88. package/dist/tui/theme/context.d.ts.map +1 -0
  89. package/dist/tui/theme/context.js +28 -0
  90. package/dist/tui/theme/context.js.map +1 -0
  91. package/dist/tui/theme/persist.d.ts +11 -0
  92. package/dist/tui/theme/persist.d.ts.map +1 -0
  93. package/dist/tui/theme/persist.js +41 -0
  94. package/dist/tui/theme/persist.js.map +1 -0
  95. package/dist/tui/theme/theme.d.ts +26 -0
  96. package/dist/tui/theme/theme.d.ts.map +1 -0
  97. package/dist/tui/theme/theme.js +51 -0
  98. package/dist/tui/theme/theme.js.map +1 -0
  99. package/dist/tui/thinking-panel.d.ts +11 -20
  100. package/dist/tui/thinking-panel.d.ts.map +1 -1
  101. package/dist/tui/thinking-panel.js +29 -7
  102. package/dist/tui/thinking-panel.js.map +1 -1
  103. package/dist/tui/tool-cards.d.ts +5 -17
  104. package/dist/tui/tool-cards.d.ts.map +1 -1
  105. package/dist/tui/tool-cards.js +4 -5
  106. package/dist/tui/tool-cards.js.map +1 -1
  107. package/dist/tui/tool-summary.d.ts +2 -0
  108. package/dist/tui/tool-summary.d.ts.map +1 -0
  109. package/dist/tui/tool-summary.js +93 -0
  110. package/dist/tui/tool-summary.js.map +1 -0
  111. package/dist/tui/use-elapsed.d.ts +2 -0
  112. package/dist/tui/use-elapsed.d.ts.map +1 -0
  113. package/dist/tui/use-elapsed.js +22 -0
  114. package/dist/tui/use-elapsed.js.map +1 -0
  115. package/dist/tui/use-plan-state.d.ts +20 -1
  116. package/dist/tui/use-plan-state.d.ts.map +1 -1
  117. package/dist/tui/use-plan-state.js +52 -46
  118. package/dist/tui/use-plan-state.js.map +1 -1
  119. package/dist/tui/use-terminal-width.d.ts +2 -0
  120. package/dist/tui/use-terminal-width.d.ts.map +1 -0
  121. package/dist/tui/use-terminal-width.js +23 -0
  122. package/dist/tui/use-terminal-width.js.map +1 -0
  123. package/dist/tui/use-viewport.d.ts +15 -0
  124. package/dist/tui/use-viewport.d.ts.map +1 -0
  125. package/dist/tui/use-viewport.js +37 -0
  126. package/dist/tui/use-viewport.js.map +1 -0
  127. package/dist/tui/welcome.d.ts +29 -0
  128. package/dist/tui/welcome.d.ts.map +1 -0
  129. package/dist/tui/welcome.js +41 -0
  130. package/dist/tui/welcome.js.map +1 -0
  131. package/package.json +3 -2
  132. package/dist/tui/header.d.ts +0 -24
  133. package/dist/tui/header.d.ts.map +0 -1
  134. package/dist/tui/header.js +0 -26
  135. package/dist/tui/header.js.map +0 -1
@@ -1,4 +1,23 @@
1
1
  import type { EventBus } from '@wukonglabs/wukong-agent-sdk';
2
2
  import type { TodoItem } from './plan-panel.js';
3
- export declare function usePlanState(eventBus: EventBus): TodoItem[];
3
+ export type PlanAction = {
4
+ action: 'add';
5
+ todoId?: string;
6
+ content?: string;
7
+ status?: TodoItem['status'];
8
+ } | {
9
+ action: 'update';
10
+ todoId?: string;
11
+ content?: string;
12
+ status?: TodoItem['status'];
13
+ } | {
14
+ action: 'complete';
15
+ todoId?: string;
16
+ } | {
17
+ action: 'remove';
18
+ todoId?: string;
19
+ };
20
+ /** plan_update 事件 → todos 状态的纯函数 reducer(便于单测,避免依赖 React 重绘时序) */
21
+ export declare function planReducer(prev: TodoItem[], action: PlanAction): TodoItem[];
22
+ export declare function usePlanState(eventBus: EventBus, resetSignal?: number): TodoItem[];
4
23
  //# sourceMappingURL=use-plan-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-plan-state.d.ts","sourceRoot":"","sources":["../../src/tui/use-plan-state.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAc,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAqD3D"}
1
+ {"version":3,"file":"use-plan-state.d.ts","sourceRoot":"","sources":["../../src/tui/use-plan-state.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAc,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;CAAE,GACjF;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;CAAE,GACpF;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,UAAU,GAAG,QAAQ,EAAE,CAwC5E;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CAkBjF"}
@@ -17,58 +17,64 @@
17
17
  * 纯展示组件 PlanPanel 的单测覆盖所有渲染分支。
18
18
  */
19
19
  import { useState, useEffect } from 'react';
20
- export function usePlanState(eventBus) {
20
+ /** plan_update 事件 → todos 状态的纯函数 reducer(便于单测,避免依赖 React 重绘时序) */
21
+ export function planReducer(prev, action) {
22
+ switch (action.action) {
23
+ case 'add': {
24
+ if (!action.todoId)
25
+ return prev;
26
+ if (prev.some((t) => t.id === action.todoId))
27
+ return prev;
28
+ // §3.6 修复:空 content 的 todo 不入库(避免空行占满 PlanPanel)
29
+ const resolvedContent = action.content ?? '';
30
+ if (!resolvedContent.trim())
31
+ return prev;
32
+ return [
33
+ ...prev,
34
+ {
35
+ id: action.todoId,
36
+ content: resolvedContent,
37
+ status: action.status ?? 'pending',
38
+ },
39
+ ];
40
+ }
41
+ case 'update': {
42
+ if (!action.todoId)
43
+ return prev;
44
+ return prev.map((t) => t.id === action.todoId
45
+ ? {
46
+ ...t,
47
+ ...(action.content !== undefined ? { content: action.content } : {}),
48
+ ...(action.status !== undefined ? { status: action.status } : {}),
49
+ }
50
+ : t);
51
+ }
52
+ case 'complete': {
53
+ if (!action.todoId)
54
+ return prev;
55
+ return prev.map((t) => (t.id === action.todoId ? { ...t, status: 'completed' } : t));
56
+ }
57
+ case 'remove': {
58
+ if (!action.todoId)
59
+ return [];
60
+ return prev.filter((t) => t.id !== action.todoId);
61
+ }
62
+ default:
63
+ return prev;
64
+ }
65
+ }
66
+ export function usePlanState(eventBus, resetSignal) {
21
67
  const [todos, setTodos] = useState([]);
68
+ // resetSignal 变化(如 /clear)时清空计划树
69
+ useEffect(() => {
70
+ setTodos([]);
71
+ }, [resetSignal]);
22
72
  useEffect(() => {
23
73
  const unsub = eventBus.on((event) => {
24
74
  if (event.type !== 'plan_update')
25
75
  return;
26
76
  const { action, todoId, content, status } = event.data;
27
- setTodos((prev) => {
28
- switch (action) {
29
- case 'add': {
30
- if (!todoId)
31
- return prev;
32
- if (prev.some((t) => t.id === todoId))
33
- return prev;
34
- // §3.6 修复:空 content 的 todo 不入库(避免空行占满 PlanPanel)
35
- const resolvedContent = content ?? '';
36
- if (!resolvedContent.trim())
37
- return prev;
38
- return [
39
- ...prev,
40
- {
41
- id: todoId,
42
- content: resolvedContent,
43
- status: status ?? 'pending',
44
- },
45
- ];
46
- }
47
- case 'update': {
48
- if (!todoId)
49
- return prev;
50
- return prev.map((t) => t.id === todoId
51
- ? {
52
- ...t,
53
- ...(content !== undefined ? { content } : {}),
54
- ...(status !== undefined ? { status } : {}),
55
- }
56
- : t);
57
- }
58
- case 'complete': {
59
- if (!todoId)
60
- return prev;
61
- return prev.map((t) => (t.id === todoId ? { ...t, status: 'completed' } : t));
62
- }
63
- case 'remove': {
64
- if (!todoId)
65
- return [];
66
- return prev.filter((t) => t.id !== todoId);
67
- }
68
- default:
69
- return prev;
70
- }
71
- });
77
+ setTodos((prev) => planReducer(prev, { action, todoId, content, status }));
72
78
  });
73
79
  return unsub;
74
80
  }, [eventBus]);
@@ -1 +1 @@
1
- {"version":3,"file":"use-plan-state.js","sourceRoot":"","sources":["../../src/tui/use-plan-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI5C,MAAM,UAAU,YAAY,CAAC,QAAkB;IAC7C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAa,EAAE,CAAC,CAAC;IAEnD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAiB,EAAE,EAAE;YAC9C,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa;gBAAE,OAAO;YACzC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;YACvD,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE;gBAChB,QAAQ,MAAM,EAAE,CAAC;oBACf,KAAK,KAAK,CAAC,CAAC,CAAC;wBACX,IAAI,CAAC,MAAM;4BAAE,OAAO,IAAI,CAAC;wBACzB,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC;4BAAE,OAAO,IAAI,CAAC;wBACnD,iDAAiD;wBACjD,MAAM,eAAe,GAAG,OAAO,IAAI,EAAE,CAAC;wBACtC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE;4BAAE,OAAO,IAAI,CAAC;wBACzC,OAAO;4BACL,GAAG,IAAI;4BACP;gCACE,EAAE,EAAE,MAAM;gCACV,OAAO,EAAE,eAAe;gCACxB,MAAM,EAAE,MAAM,IAAI,SAAS;6BAC5B;yBACF,CAAC;oBACJ,CAAC;oBACD,KAAK,QAAQ,CAAC,CAAC,CAAC;wBACd,IAAI,CAAC,MAAM;4BAAE,OAAO,IAAI,CAAC;wBACzB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpB,CAAC,CAAC,EAAE,KAAK,MAAM;4BACb,CAAC,CAAC;gCACE,GAAG,CAAC;gCACJ,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gCAC7C,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;6BAC5C;4BACH,CAAC,CAAC,CAAC,CACN,CAAC;oBACJ,CAAC;oBACD,KAAK,UAAU,CAAC,CAAC,CAAC;wBAChB,IAAI,CAAC,MAAM;4BAAE,OAAO,IAAI,CAAC;wBACzB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAChF,CAAC;oBACD,KAAK,QAAQ,CAAC,CAAC,CAAC;wBACd,IAAI,CAAC,MAAM;4BAAE,OAAO,EAAE,CAAC;wBACvB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;oBAC7C,CAAC;oBACD;wBACE,OAAO,IAAI,CAAC;gBAChB,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"use-plan-state.js","sourceRoot":"","sources":["../../src/tui/use-plan-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function useTerminalWidth(): number;
2
+ //# sourceMappingURL=use-terminal-width.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-terminal-width.d.ts","sourceRoot":"","sources":["../../src/tui/use-terminal-width.ts"],"names":[],"mappings":"AASA,wBAAgB,gBAAgB,IAAI,MAAM,CAYzC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 订阅终端宽度变化,返回当前列数。
3
+ *
4
+ * M3:流式区需要按列数折算视觉行,避免超宽单行撑破动态区高度。
5
+ * stdout 在测试环境可能为 undefined,此时回退到 80。
6
+ */
7
+ import { useState, useEffect } from 'react';
8
+ import { useStdout } from 'ink';
9
+ export function useTerminalWidth() {
10
+ const { stdout } = useStdout();
11
+ const [cols, setCols] = useState(stdout?.columns ?? 80);
12
+ useEffect(() => {
13
+ if (!stdout)
14
+ return;
15
+ const onResize = () => setCols(stdout.columns);
16
+ stdout.on('resize', onResize);
17
+ return () => {
18
+ stdout.off('resize', onResize);
19
+ };
20
+ }, [stdout]);
21
+ return cols;
22
+ }
23
+ //# sourceMappingURL=use-terminal-width.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-terminal-width.js","sourceRoot":"","sources":["../../src/tui/use-terminal-width.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAEhC,MAAM,UAAU,gBAAgB;IAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAC/B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;IACxD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC9B,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjC,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACb,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,15 @@
1
+ export interface Viewport {
2
+ /** 终端总行数 */
3
+ rows: number;
4
+ /** 终端总列数 */
5
+ cols: number;
6
+ /** 弹性主区可用行数(已扣除 header 与 footer) */
7
+ mainHeight: number;
8
+ }
9
+ export declare const HEADER_ROWS = 1;
10
+ /** footer 基础行数:inputBox(round 边框上下各 1 + 内容 1) + hint 1 */
11
+ export declare const FOOTER_ROWS_BASE = 4;
12
+ /** mainHeight 兜底值,防止极小终端下把 UI 压没 */
13
+ export declare const MAIN_HEIGHT_MIN = 6;
14
+ export declare function useViewport(footerRows?: number): Viewport;
15
+ //# sourceMappingURL=use-viewport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-viewport.d.ts","sourceRoot":"","sources":["../../src/tui/use-viewport.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,QAAQ;IACvB,YAAY;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,YAAY;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,oCAAoC;AACpC,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC,wBAAgB,WAAW,CAAC,UAAU,GAAE,MAAyB,GAAG,QAAQ,CAsB3E"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * useViewport —— 读取终端尺寸,动态计算主区可用高度。
3
+ *
4
+ * 用于三段式视口(24-tui-redesign-viewport.md):
5
+ * mainHeight = rows - HEADER_ROWS - footerRows
6
+ * 让 StatusBar/InputBox 永远钉在屏幕底部可见,而非随终端 scrollback 被顶出。
7
+ *
8
+ * 终端尺寸随时可变为 0(unmount 早期)或极小,这里做了兜底:
9
+ * - 行高低于 12 时 mainHeight 兜底 6 行,不再进一步压缩;
10
+ * - 监听 stdout 'resize' 事件做自适应重绘。
11
+ */
12
+ import { useState, useEffect } from 'react';
13
+ import { useStdout } from 'ink';
14
+ export const HEADER_ROWS = 1;
15
+ /** footer 基础行数:inputBox(round 边框上下各 1 + 内容 1) + hint 1 */
16
+ export const FOOTER_ROWS_BASE = 4;
17
+ /** mainHeight 兜底值,防止极小终端下把 UI 压没 */
18
+ export const MAIN_HEIGHT_MIN = 6;
19
+ export function useViewport(footerRows = FOOTER_ROWS_BASE) {
20
+ const { stdout } = useStdout();
21
+ const [size, setSize] = useState(() => ({
22
+ rows: stdout?.rows ?? 24,
23
+ cols: stdout?.columns ?? 80,
24
+ }));
25
+ useEffect(() => {
26
+ if (!stdout)
27
+ return;
28
+ const onResize = () => setSize({ rows: stdout.rows, cols: stdout.columns });
29
+ stdout.on('resize', onResize);
30
+ return () => {
31
+ stdout.off('resize', onResize);
32
+ };
33
+ }, [stdout]);
34
+ const mainHeight = Math.max(MAIN_HEIGHT_MIN, size.rows - HEADER_ROWS - footerRows);
35
+ return { rows: size.rows, cols: size.cols, mainHeight };
36
+ }
37
+ //# sourceMappingURL=use-viewport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-viewport.js","sourceRoot":"","sources":["../../src/tui/use-viewport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAWhC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAC7B,0DAA0D;AAC1D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAClC,oCAAoC;AACpC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AAEjC,MAAM,UAAU,WAAW,CAAC,aAAqB,gBAAgB;IAC/D,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAC/B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QACtC,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,EAAE;QACxB,IAAI,EAAE,MAAM,EAAE,OAAO,IAAI,EAAE;KAC5B,CAAC,CAAC,CAAC;IAEJ,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5E,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC9B,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjC,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CACzB,eAAe,EACf,IAAI,CAAC,IAAI,GAAG,WAAW,GAAG,UAAU,CACrC,CAAC;IAEF,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Welcome —— 启动 / /clear 后的欢迎首页。
3
+ *
4
+ * 目标:把原先散落在欢迎框上方的启动摘要(品牌 / 版本 / 配置来源 / 会话状态)
5
+ * 收敛回欢迎容器内部,避免首屏出现“日志 + 欢迎框”两块割裂的信息区。
6
+ */
7
+ import React from 'react';
8
+ export interface WelcomeProps {
9
+ /** CLI 版本号 */
10
+ appVersion?: string;
11
+ /** 当前 workspace 根目录 */
12
+ cwd?: string;
13
+ /** 已解析到的配置文件路径(若有) */
14
+ configPath?: string;
15
+ /** 当前模型名 */
16
+ model?: string;
17
+ /** 当前 session 短 ID */
18
+ sessionUuidShort?: string;
19
+ /** 当前会话已有记录数 */
20
+ sessionRecordCount?: number;
21
+ /** 当前会话是否本次刚创建 */
22
+ sessionCreated?: boolean;
23
+ /** 已注册工具数量 */
24
+ toolsCount?: number;
25
+ /** 已加载且可用的技能数量 */
26
+ skillsLoaded?: number;
27
+ }
28
+ export declare function Welcome({ appVersion, cwd, configPath, model, sessionUuidShort, sessionRecordCount, sessionCreated, toolsCount, skillsLoaded, }: WelcomeProps): React.ReactElement;
29
+ //# sourceMappingURL=welcome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"welcome.d.ts","sourceRoot":"","sources":["../../src/tui/welcome.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,MAAM,WAAW,YAAY;IAC3B,cAAc;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,OAAO,CAAC,EACtB,UAAU,EACV,GAAG,EACH,UAAU,EACV,KAAK,EACL,gBAAgB,EAChB,kBAAsB,EACtB,cAAsB,EACtB,UAAU,EACV,YAAY,GACb,EAAE,YAAY,GAAG,KAAK,CAAC,YAAY,CA0EnC"}
@@ -0,0 +1,41 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { useTheme } from './theme/context.js';
4
+ import { useTerminalWidth } from './use-terminal-width.js';
5
+ export function Welcome({ appVersion, cwd, configPath, model, sessionUuidShort, sessionRecordCount = 0, sessionCreated = false, toolsCount, skillsLoaded, }) {
6
+ const { theme } = useTheme();
7
+ const cols = useTerminalWidth();
8
+ const runtimeParts = [];
9
+ if (model)
10
+ runtimeParts.push(model);
11
+ if (toolsCount !== undefined)
12
+ runtimeParts.push(`${toolsCount} 个工具`);
13
+ if (skillsLoaded !== undefined)
14
+ runtimeParts.push(`${skillsLoaded} 个技能`);
15
+ const sessionState = sessionRecordCount === 0
16
+ ? (sessionCreated ? '新会话' : '已清空')
17
+ : '已载入';
18
+ const sessionSummary = [
19
+ sessionUuidShort,
20
+ `${sessionRecordCount} 条记录`,
21
+ sessionState,
22
+ ].filter(Boolean).join(' · ');
23
+ const configSummary = configPath ?? '未找到配置文件,使用 env / 默认配置';
24
+ // 外框上边框: ╭─ wukong vx.x.x ───╮ (标题嵌入左上角缺口)
25
+ const titleStr = appVersion ? ` wukong v${appVersion} ` : ` wukong `;
26
+ const titleLen = titleStr.length;
27
+ const topDashes = Math.max(0, cols - titleLen - 3);
28
+ const topBorder = `╭─${titleStr}${'─'.repeat(topDashes)}╮`;
29
+ const bottomBorder = `╰${'─'.repeat(Math.max(0, cols - 2))}╯`;
30
+ return (_jsxs(Box, { flexDirection: "column", width: cols, marginY: 1, children: [_jsx(Text, { color: theme.status, children: topBorder }), _jsx(Box, { borderStyle: "round", borderTop: false, borderBottom: false, borderColor: theme.status, paddingX: 2, paddingY: 1, width: cols, children: _jsxs(Box, { children: [_jsxs(Box, { width: "35%", flexDirection: "column", alignItems: "center", justifyContent: "center", height: 7, children: [_jsx(Text, { color: theme.status, bold: true, children: " _/\\_ " }), _jsx(Text, { color: theme.status, bold: true, children: " .-' '-. " }), _jsxs(Text, { color: theme.status, bold: true, children: [" C( ", _jsx(Text, { color: "white", children: "\u2022" }), " ", _jsx(Text, { color: "white", children: "\u2022" }), " )D "] }), _jsxs(Text, { color: theme.status, bold: true, children: [" \\ ", _jsx(Text, { color: "white", children: "\u25E1" }), " / "] }), _jsx(Text, { color: theme.status, bold: true, children: " '-____-' " })] }), _jsxs(Box, { flexDirection: "column", marginX: 4, justifyContent: "center", height: 7, children: [_jsx(Text, { color: theme.status, children: "\u2502" }), _jsx(Text, { color: theme.status, children: "\u2502" }), _jsx(Text, { color: theme.status, children: "\u2502" }), _jsx(Text, { color: theme.status, children: "\u2502" }), _jsx(Text, { color: theme.status, children: "\u2502" })] }), _jsxs(Box, { width: "60%", flexDirection: "column", paddingLeft: 2, justifyContent: "center", height: 7, children: [_jsx(MetaRow, { label: "workspace", value: cwd }), _jsx(MetaRow, { label: "session", value: sessionSummary }), _jsx(MetaRow, { label: "config", value: configSummary, isLast: runtimeParts.length === 0 }), runtimeParts.length > 0 && _jsx(MetaRow, { label: "runtime", value: runtimeParts.join(' · '), isLast: true })] })] }) }), _jsx(Text, { color: theme.status, children: bottomBorder })] }));
31
+ }
32
+ function MetaRow({ label, value, isLast }) {
33
+ const { theme } = useTheme();
34
+ if (!value)
35
+ return null;
36
+ return (_jsxs(Box, { marginBottom: isLast ? 0 : 1, children: [_jsxs(Text, { color: theme.status, children: [padLabel(label), " "] }), _jsx(Text, { color: theme.dim, children: value })] }));
37
+ }
38
+ function padLabel(label) {
39
+ return label.padEnd(9, ' ');
40
+ }
41
+ //# sourceMappingURL=welcome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"welcome.js","sourceRoot":"","sources":["../../src/tui/welcome.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wukonglabs/wukong",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "description": "AI Coding Agent — CLI 交互 + TUI 可视化界面,支持 CI 自动化(ReAct 循环 + 内置工具 + 技能系统)",
5
5
  "bin": {
6
6
  "wukong": "dist/index.js"
@@ -33,8 +33,9 @@
33
33
  "license": "MIT",
34
34
  "dependencies": {
35
35
  "ink": "^5.2.1",
36
+ "marked": "^14.1.4",
36
37
  "react": "^18.3.1",
37
- "@wukonglabs/wukong-agent-sdk": "0.0.19"
38
+ "@wukonglabs/wukong-agent-sdk": "0.0.21"
38
39
  },
39
40
  "devDependencies": {
40
41
  "@types/node": "^25.3.2",
@@ -1,24 +0,0 @@
1
- /**
2
- * Header 组件 —— 顶部状态栏(model / session / step counter / cache / duration)。
3
- *
4
- * Phase B M2:增加 step counter + cache 命中率(由 App 订阅 step_start/cache_stat
5
- * 事件后传入)。
6
- */
7
- import React from 'react';
8
- export interface HeaderProps {
9
- model: string;
10
- sessionUuidShort: string;
11
- workspaceRoot: string;
12
- /** 当前是否在等待 agent 响应 */
13
- busy: boolean;
14
- /** 最近一次 run 的耗时(ms);undefined 表示尚未完成任何 run */
15
- lastDurationMs?: number;
16
- /** 当前 step(从 1 开始);0 表示尚未开始或已结束 */
17
- currentStep?: number;
18
- /** 最大 step 数;用于显示 "3/100" */
19
- maxSteps?: number;
20
- /** 累计 cache 命中率(0-1);undefined 表示无 cache 数据 */
21
- cacheHitRate?: number;
22
- }
23
- export declare function Header({ model, sessionUuidShort, workspaceRoot, busy, lastDurationMs, currentStep, maxSteps, cacheHitRate, }: HeaderProps): React.ReactElement;
24
- //# sourceMappingURL=header.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../src/tui/header.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,gBAAgB,EAChB,aAAa,EACb,IAAI,EACJ,cAAc,EACd,WAAe,EACf,QAAQ,EACR,YAAY,GACb,EAAE,WAAW,GAAG,KAAK,CAAC,YAAY,CAkClC"}
@@ -1,26 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Text, Box } from 'ink';
3
- export function Header({ model, sessionUuidShort, workspaceRoot, busy, lastDurationMs, currentStep = 0, maxSteps, cacheHitRate, }) {
4
- const shortRoot = shortenPath(workspaceRoot, 40);
5
- const durationStr = lastDurationMs !== undefined ? `${(lastDurationMs / 1000).toFixed(1)}s` : '—';
6
- const stepStr = currentStep > 0
7
- ? maxSteps ? `🎯 ${currentStep}/${maxSteps}` : `🎯 ${currentStep}`
8
- : '🎯 —';
9
- const cacheStr = cacheHitRate !== undefined
10
- ? `💾 ${(cacheHitRate * 100).toFixed(0)}%`
11
- : null;
12
- return (_jsxs(Box, { paddingX: 0, children: [_jsx(Text, { color: "cyan", bold: true, children: "\uD83D\uDC12 Wukong" }), _jsx(Text, { dimColor: true, children: " \u2502 " }), _jsxs(Text, { color: "blue", children: ["\uD83D\uDCE1 ", model] }), _jsx(Text, { dimColor: true, children: " \u2502 " }), _jsxs(Text, { color: "magenta", children: ["\uD83D\uDCC2 ", sessionUuidShort] }), _jsx(Text, { dimColor: true, children: " @ " }), _jsx(Text, { color: "gray", children: shortRoot }), _jsx(Text, { dimColor: true, children: " \u2502 " }), _jsx(Text, { color: "cyan", children: stepStr }), cacheStr && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: " \u2502 " }), _jsx(Text, { color: "green", children: cacheStr })] })), _jsx(Text, { dimColor: true, children: " \u2502 " }), _jsx(Text, { color: busy ? 'yellow' : 'green', children: busy ? '⏳ 思考中…' : '✓ 就绪' }), _jsx(Text, { dimColor: true, children: " \u2502 " }), _jsxs(Text, { dimColor: true, children: ["\u23F1 ", durationStr] })] }));
13
- }
14
- /** 把长路径缩短,保留首段 + 末尾两段 */
15
- function shortenPath(p, maxLen) {
16
- if (p.length <= maxLen)
17
- return p;
18
- const parts = p.split('/');
19
- if (parts.length <= 3)
20
- return p;
21
- const tail = parts.slice(-2).join('/');
22
- const head = parts[0] || '/';
23
- const shortened = `${head}/…/${tail}`;
24
- return shortened.length <= maxLen ? shortened : `…/${tail}`;
25
- }
26
- //# sourceMappingURL=header.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"header.js","sourceRoot":"","sources":["../../src/tui/header.tsx"],"names":[],"mappings":";AAOA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAkBhC,MAAM,UAAU,MAAM,CAAC,EACrB,KAAK,EACL,gBAAgB,EAChB,aAAa,EACb,IAAI,EACJ,cAAc,EACd,WAAW,GAAG,CAAC,EACf,QAAQ,EACR,YAAY,GACA;IACZ,MAAM,SAAS,GAAG,WAAW,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IACjD,MAAM,WAAW,GACf,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAChF,MAAM,OAAO,GAAG,WAAW,GAAG,CAAC;QAC7B,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,WAAW,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,WAAW,EAAE;QAClE,CAAC,CAAC,MAAM,CAAC;IACX,MAAM,QAAQ,GAAG,YAAY,KAAK,SAAS;QACzC,CAAC,CAAC,MAAM,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAC1C,CAAC,CAAC,IAAI,CAAC;IAET,OAAO,CACL,MAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,aACd,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,0CAAiB,EACxC,KAAC,IAAI,IAAC,QAAQ,+BAAW,EACzB,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,8BAAK,KAAK,IAAQ,EACpC,KAAC,IAAI,IAAC,QAAQ,+BAAW,EACzB,MAAC,IAAI,IAAC,KAAK,EAAC,SAAS,8BAAK,gBAAgB,IAAQ,EAClD,KAAC,IAAI,IAAC,QAAQ,0BAAW,EACzB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,SAAS,GAAQ,EACrC,KAAC,IAAI,IAAC,QAAQ,+BAAW,EACzB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,OAAO,GAAQ,EAClC,QAAQ,IAAI,CACX,8BACE,KAAC,IAAI,IAAC,QAAQ,+BAAW,EACzB,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,QAAQ,GAAQ,IACpC,CACJ,EACD,KAAC,IAAI,IAAC,QAAQ,+BAAW,EACzB,KAAC,IAAI,IAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,YAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAQ,EACzE,KAAC,IAAI,IAAC,QAAQ,+BAAW,EACzB,MAAC,IAAI,IAAC,QAAQ,8BAAI,WAAW,IAAQ,IACjC,CACP,CAAC;AACJ,CAAC;AAED,yBAAyB;AACzB,SAAS,WAAW,CAAC,CAAS,EAAE,MAAc;IAC5C,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;IAC7B,MAAM,SAAS,GAAG,GAAG,IAAI,MAAM,IAAI,EAAE,CAAC;IACtC,OAAO,SAAS,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;AAC9D,CAAC"}