chatccc 0.2.242 → 0.2.243

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 (56) hide show
  1. package/README.md +5 -5
  2. package/bin/cccagent.mjs +17 -17
  3. package/deepccc-agent/bin/deepccc.mjs +26 -26
  4. package/deepccc-agent/package.json +62 -62
  5. package/deepccc-agent/src/__tests__/chat-session.test.ts +578 -522
  6. package/deepccc-agent/src/__tests__/cli-json.test.ts +49 -49
  7. package/deepccc-agent/src/__tests__/config.test.ts +26 -26
  8. package/deepccc-agent/src/__tests__/context.test.ts +319 -319
  9. package/deepccc-agent/src/__tests__/file-tools.test.ts +240 -240
  10. package/deepccc-agent/src/__tests__/permissions.test.ts +195 -195
  11. package/deepccc-agent/src/__tests__/progress-reducer.test.ts +121 -121
  12. package/deepccc-agent/src/__tests__/session-search.test.ts +262 -262
  13. package/deepccc-agent/src/__tests__/session-select.test.ts +116 -116
  14. package/deepccc-agent/src/__tests__/sigint.test.ts +56 -56
  15. package/deepccc-agent/src/__tests__/skills.test.ts +284 -284
  16. package/deepccc-agent/src/__tests__/terminal-renderer.test.ts +247 -247
  17. package/deepccc-agent/src/__tests__/web-tools.test.ts +220 -220
  18. package/deepccc-agent/src/config.ts +84 -84
  19. package/deepccc-agent/src/context.ts +465 -465
  20. package/deepccc-agent/src/file-log.ts +38 -38
  21. package/deepccc-agent/src/index.ts +22 -0
  22. package/deepccc-agent/src/proc-tree-kill.ts +61 -61
  23. package/deepccc-agent/src/progress/cards-helpers.ts +76 -76
  24. package/deepccc-agent/src/progress/reducer.ts +113 -113
  25. package/deepccc-agent/src/progress/terminal-renderer.ts +294 -294
  26. package/deepccc-agent/src/progress/view.ts +77 -77
  27. package/deepccc-agent/src/raw-stream-log.ts +124 -124
  28. package/deepccc-agent/src/session-search.ts +370 -370
  29. package/deepccc-agent/src/session-select.ts +48 -48
  30. package/deepccc-agent/src/sigint.ts +50 -50
  31. package/deepccc-agent/src/skills.ts +205 -205
  32. package/deepccc-agent/src/web-tools.ts +313 -313
  33. package/deepccc-agent/tsconfig.build.json +13 -13
  34. package/deepccc-agent/tsconfig.json +13 -13
  35. package/deepccc-agent/vitest.config.ts +7 -7
  36. package/package.json +1 -1
  37. package/src/__tests__/builtin-chat-session.test.ts +522 -522
  38. package/src/__tests__/builtin-config.test.ts +26 -26
  39. package/src/__tests__/builtin-context.test.ts +319 -319
  40. package/src/__tests__/builtin-file-tools.test.ts +240 -240
  41. package/src/__tests__/builtin-permissions.test.ts +211 -211
  42. package/src/__tests__/builtin-session-search.test.ts +262 -262
  43. package/src/__tests__/builtin-session-select.test.ts +116 -116
  44. package/src/__tests__/builtin-sigint.test.ts +56 -56
  45. package/src/__tests__/builtin-skills.test.ts +284 -284
  46. package/src/__tests__/builtin-web-tools.test.ts +220 -220
  47. package/src/__tests__/config.test.ts +17 -17
  48. package/src/__tests__/progress-reducer.test.ts +121 -121
  49. package/src/__tests__/session-ccc-config.test.ts +45 -45
  50. package/src/__tests__/session.test.ts +298 -298
  51. package/src/adapters/ccc-adapter.ts +145 -145
  52. package/src/config-utils.ts +13 -13
  53. package/src/config.ts +13 -13
  54. package/src/progress/reducer.ts +113 -113
  55. package/src/session-chat-binding.ts +83 -83
  56. package/src/session.ts +311 -311
@@ -5,8 +5,8 @@
5
5
  // 由 session.ts 在初始化时调用 rebuildSessionChatsFromRegistry 重建
6
6
  // ---------------------------------------------------------------------------
7
7
 
8
- import type { PlatformAdapter } from "./platform-adapter.ts";
9
- import type { ResponseProgressObservation } from "./response-stall.ts";
8
+ import type { PlatformAdapter } from "./platform-adapter.ts";
9
+ import type { ResponseProgressObservation } from "./response-stall.ts";
10
10
 
11
11
  const sessionChatsMap = new Map<string, Set<string>>();
12
12
 
@@ -53,51 +53,51 @@ export function hasChatsForSession(sessionId: string): boolean {
53
53
  return (sessionChatsMap.get(sessionId)?.size ?? 0) > 0;
54
54
  }
55
55
 
56
- // Agent generator 退出后,最终卡片、registry、头像等仍可能在异步收尾。该阶段
57
- // 也必须阻止下一轮提前进入,否则旧会话的落盘可能覆盖新会话绑定。
58
- const finalizingSessions = new Set<string>();
59
-
60
- // response-stall 自动恢复预约只存在于当前进程内:用户已明确 ChatCCC 重启后
61
- // 不需要补发恢复 prompt。预约从检测到第一次停滞起一直持有到恢复轮同步进入
62
- // runAgentSession,填补旧轮收尾和新轮 activePrompts.set 之间的空窗,保证此时
63
- // 到达的普通用户消息只能进入缓存队列,不能抢在恢复 prompt 前执行。
64
- const autoRecoveryReservations = new Set<string>();
65
-
66
- /** 检查 sessionId 是否有活跃 prompt、正在收尾或已预约自动恢复。 */
67
- export function isSessionRunning(sessionId: string): boolean {
68
- return activePrompts.has(sessionId)
69
- || finalizingSessions.has(sessionId)
70
- || autoRecoveryReservations.has(sessionId);
71
- }
72
-
73
- export function markSessionFinalizing(sessionId: string): void {
74
- finalizingSessions.add(sessionId);
75
- }
76
-
77
- export function clearSessionFinalizing(sessionId: string): void {
78
- finalizingSessions.delete(sessionId);
79
- }
80
-
81
- /** 为 response-stall 后的内部恢复轮预留下一次执行权。 */
82
- export function reserveAutoRecovery(sessionId: string): boolean {
83
- if (autoRecoveryReservations.has(sessionId)) return false;
84
- autoRecoveryReservations.add(sessionId);
85
- return true;
86
- }
87
-
88
- /** 恢复轮启动前原子消费预约;返回 false 表示已被 /stop 取消。 */
89
- export function consumeAutoRecoveryReservation(sessionId: string): boolean {
90
- return autoRecoveryReservations.delete(sessionId);
91
- }
92
-
93
- /** 取消尚未启动的恢复轮。 */
94
- export function cancelAutoRecoveryReservation(sessionId: string): boolean {
95
- return autoRecoveryReservations.delete(sessionId);
96
- }
97
-
98
- export function hasAutoRecoveryReservation(sessionId: string): boolean {
99
- return autoRecoveryReservations.has(sessionId);
100
- }
56
+ // Agent generator 退出后,最终卡片、registry、头像等仍可能在异步收尾。该阶段
57
+ // 也必须阻止下一轮提前进入,否则旧会话的落盘可能覆盖新会话绑定。
58
+ const finalizingSessions = new Set<string>();
59
+
60
+ // response-stall 自动恢复预约只存在于当前进程内:用户已明确 ChatCCC 重启后
61
+ // 不需要补发恢复 prompt。预约从检测到第一次停滞起一直持有到恢复轮同步进入
62
+ // runAgentSession,填补旧轮收尾和新轮 activePrompts.set 之间的空窗,保证此时
63
+ // 到达的普通用户消息只能进入缓存队列,不能抢在恢复 prompt 前执行。
64
+ const autoRecoveryReservations = new Set<string>();
65
+
66
+ /** 检查 sessionId 是否有活跃 prompt、正在收尾或已预约自动恢复。 */
67
+ export function isSessionRunning(sessionId: string): boolean {
68
+ return activePrompts.has(sessionId)
69
+ || finalizingSessions.has(sessionId)
70
+ || autoRecoveryReservations.has(sessionId);
71
+ }
72
+
73
+ export function markSessionFinalizing(sessionId: string): void {
74
+ finalizingSessions.add(sessionId);
75
+ }
76
+
77
+ export function clearSessionFinalizing(sessionId: string): void {
78
+ finalizingSessions.delete(sessionId);
79
+ }
80
+
81
+ /** 为 response-stall 后的内部恢复轮预留下一次执行权。 */
82
+ export function reserveAutoRecovery(sessionId: string): boolean {
83
+ if (autoRecoveryReservations.has(sessionId)) return false;
84
+ autoRecoveryReservations.add(sessionId);
85
+ return true;
86
+ }
87
+
88
+ /** 恢复轮启动前原子消费预约;返回 false 表示已被 /stop 取消。 */
89
+ export function consumeAutoRecoveryReservation(sessionId: string): boolean {
90
+ return autoRecoveryReservations.delete(sessionId);
91
+ }
92
+
93
+ /** 取消尚未启动的恢复轮。 */
94
+ export function cancelAutoRecoveryReservation(sessionId: string): boolean {
95
+ return autoRecoveryReservations.delete(sessionId);
96
+ }
97
+
98
+ export function hasAutoRecoveryReservation(sessionId: string): boolean {
99
+ return autoRecoveryReservations.has(sessionId);
100
+ }
101
101
 
102
102
  // ---------------------------------------------------------------------------
103
103
  // activePrompts: sessionId → 活跃 prompt 控制
@@ -108,29 +108,29 @@ export interface ActivePrompt {
108
108
  stopped: boolean;
109
109
  startTime: number;
110
110
  /** Root PID for the CLI process currently serving this prompt, if the adapter exposes one. */
111
- processPid?: number;
112
- processMonitor?: ReturnType<typeof setInterval>;
113
- responseStallMonitor?: ReturnType<typeof setInterval>;
114
- avatarRefreshTimer?: ReturnType<typeof setInterval>;
115
- /** Grace timer that force-closes a stream which stays open after its authoritative final event. */
116
- finalResponseCloseTimer?: ReturnType<typeof setTimeout>;
117
- /** Character-count progress observed only while the activity is "responding". */
118
- responseProgress?: ResponseProgressObservation;
119
- /** Set before a response-stall auto-end begins so competing monitors cannot win the race. */
120
- autoEnded?: boolean;
121
- autoEndedAt?: number;
111
+ processPid?: number;
112
+ processMonitor?: ReturnType<typeof setInterval>;
113
+ responseStallMonitor?: ReturnType<typeof setInterval>;
114
+ avatarRefreshTimer?: ReturnType<typeof setInterval>;
115
+ /** Grace timer that force-closes a stream which stays open after its authoritative final event. */
116
+ finalResponseCloseTimer?: ReturnType<typeof setTimeout>;
117
+ /** Character-count progress observed only while the activity is "responding". */
118
+ responseProgress?: ResponseProgressObservation;
119
+ /** Set before a response-stall auto-end begins so competing monitors cannot win the race. */
120
+ autoEnded?: boolean;
121
+ autoEndedAt?: number;
122
122
  /** Set when the watchdog detects that the CLI process disappeared before stream finalization. */
123
123
  abnormalExit?: boolean;
124
124
  abnormalExitNotified?: boolean;
125
- /** Set when the resource monitor detects CPU + memory unchanged for 3 minutes. */
126
- resourceStuck?: boolean;
127
- /** True only for the single internal continuation turn after a response stall. */
128
- autoRecovery?: boolean;
129
- /** Adapter observed an authoritative completed final-response event. */
130
- finalResponseObserved?: boolean;
131
- /** Adapter-provided callback to close the underlying SDK session / subprocess.
132
- * Called by stop-stuck-loop before controller.abort() to terminate the CLI
133
- * process immediately, rather than waiting for the async generator to unblock. */
125
+ /** Set when the resource monitor detects CPU + memory unchanged for 3 minutes. */
126
+ resourceStuck?: boolean;
127
+ /** True only for the single internal continuation turn after a response stall. */
128
+ autoRecovery?: boolean;
129
+ /** Adapter observed an authoritative completed final-response event. */
130
+ finalResponseObserved?: boolean;
131
+ /** Adapter-provided callback to close the underlying SDK session / subprocess.
132
+ * Called by stop-stuck-loop before controller.abort() to terminate the CLI
133
+ * process immediately, rather than waiting for the async generator to unblock. */
134
134
  closeSession?: () => void;
135
135
  }
136
136
 
@@ -194,10 +194,10 @@ export interface DisplayCardState {
194
194
  cardId: string;
195
195
  sequence: number;
196
196
  cardBusy: boolean;
197
- cardCreatedAt: number;
198
- lastSentContent: string;
199
- /** Last rendered activity header; elapsed time can change without body output. */
200
- lastSentHeaderTitle?: string;
197
+ cardCreatedAt: number;
198
+ lastSentContent: string;
199
+ /** Last rendered activity header; elapsed time can change without body output. */
200
+ lastSentHeaderTitle?: string;
201
201
  streamErrorNotified: boolean;
202
202
  /** 所属 session */
203
203
  sessionId: string;
@@ -210,8 +210,8 @@ export interface DisplayCardState {
210
210
  lastSentAccLen?: number;
211
211
  /** WeChat delta: 上次发送时的 finalReply */
212
212
  lastSentFinalReply?: string;
213
- /** Liveness animation counter; the explicit activity header conveys Agent state. */
214
- dotCount: number;
213
+ /** Liveness animation counter; the explicit activity header conveys Agent state. */
214
+ dotCount: number;
215
215
  }
216
216
 
217
217
  export const displayCards = new Map<string, DisplayCardState>();
@@ -275,18 +275,18 @@ export function consumeQueuedMessage(platform: PlatformAdapter, msg: QueuedMessa
275
275
  export function resetBindingState(): void {
276
276
  sessionChatsMap.clear();
277
277
  lastActiveChatMap.clear();
278
- for (const prompt of activePrompts.values()) {
279
- if (prompt.processMonitor) clearInterval(prompt.processMonitor);
280
- if (prompt.responseStallMonitor) clearInterval(prompt.responseStallMonitor);
281
- if (prompt.finalResponseCloseTimer) clearTimeout(prompt.finalResponseCloseTimer);
282
- }
283
- activePrompts.clear();
284
- finalizingSessions.clear();
285
- autoRecoveryReservations.clear();
286
- queuedMessages.clear();
278
+ for (const prompt of activePrompts.values()) {
279
+ if (prompt.processMonitor) clearInterval(prompt.processMonitor);
280
+ if (prompt.responseStallMonitor) clearInterval(prompt.responseStallMonitor);
281
+ if (prompt.finalResponseCloseTimer) clearTimeout(prompt.finalResponseCloseTimer);
282
+ }
283
+ activePrompts.clear();
284
+ finalizingSessions.clear();
285
+ autoRecoveryReservations.clear();
286
+ queuedMessages.clear();
287
287
  displayCards.clear();
288
288
  if (unifiedDisplayLoopHandle !== null) {
289
289
  clearInterval(unifiedDisplayLoopHandle);
290
290
  unifiedDisplayLoopHandle = null;
291
291
  }
292
- }
292
+ }