@emqo/claudebridge 0.6.1 → 0.6.3

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.
@@ -240,8 +240,8 @@ export class DiscordAdapter {
240
240
  await channel.send(t(this.locale, "auto_starting", { id: task.id, desc: task.description }));
241
241
  console.log(`[discord] auto-task #${task.id} for ${task.user_id}`);
242
242
  const res = this.maxParallel > 1
243
- ? await this.engine.runParallel(task.user_id, task.description, "discord", task.chat_id)
244
- : await this.engine.runStream(task.user_id, task.description, "discord", task.chat_id);
243
+ ? await this.engine.runParallel(task.user_id, task.description, "discord", task.chat_id, undefined, 0)
244
+ : await this.engine.runStream(task.user_id, task.description, "discord", task.chat_id, undefined, 0);
245
245
  if (res.timedOut) {
246
246
  this.store.markTaskResult(task.id, "failed");
247
247
  if (res.text)
@@ -394,8 +394,8 @@ export class TelegramAdapter {
394
394
  try {
395
395
  console.log(`[telegram] auto-task #${task.id} for ${task.user_id}`);
396
396
  const res = this.maxParallel > 1
397
- ? await this.engine.runParallel(task.user_id, task.description, "telegram", task.chat_id)
398
- : await this.engine.runStream(task.user_id, task.description, "telegram", task.chat_id);
397
+ ? await this.engine.runParallel(task.user_id, task.description, "telegram", task.chat_id, undefined, 0)
398
+ : await this.engine.runStream(task.user_id, task.description, "telegram", task.chat_id, undefined, 0);
399
399
  if (res.timedOut) {
400
400
  this.store.markTaskResult(task.id, "failed");
401
401
  if (res.text)
@@ -26,8 +26,8 @@ export declare class AgentEngine {
26
26
  getMaxParallel(): number;
27
27
  getWorkDir(userId: string): string;
28
28
  isLocked(userId: string): boolean;
29
- runStream(userId: string, prompt: string, platform: string, chatId: string, onChunk?: StreamCallback): Promise<AgentResponse>;
30
- runParallel(userId: string, prompt: string, platform: string, chatId: string, onChunk?: StreamCallback): Promise<AgentResponse>;
29
+ runStream(userId: string, prompt: string, platform: string, chatId: string, onChunk?: StreamCallback, overrideTimeoutMs?: number): Promise<AgentResponse>;
30
+ runParallel(userId: string, prompt: string, platform: string, chatId: string, onChunk?: StreamCallback, overrideTimeoutMs?: number): Promise<AgentResponse>;
31
31
  private _executeWithRetry;
32
32
  private _execute;
33
33
  private _executeNoSession;
@@ -46,13 +46,13 @@ export class AgentEngine {
46
46
  isLocked(userId) {
47
47
  return this.lock.isLocked(userId);
48
48
  }
49
- async runStream(userId, prompt, platform, chatId, onChunk) {
49
+ async runStream(userId, prompt, platform, chatId, onChunk, overrideTimeoutMs) {
50
50
  const release = await this.lock.acquire(userId);
51
51
  try {
52
52
  this.store.addHistory(userId, platform, "user", prompt);
53
53
  const memories = this.config.agent.memory?.enabled ? this.store.getMemories(userId) : [];
54
54
  const memoryPrompt = memories.length ? memories.map(m => `- ${m.content}`).join("\n") : "";
55
- const res = await this._executeWithRetry(userId, prompt, platform, chatId, onChunk, memoryPrompt);
55
+ const res = await this._executeWithRetry(userId, prompt, platform, chatId, onChunk, memoryPrompt, overrideTimeoutMs);
56
56
  this.store.addHistory(userId, platform, "assistant", res.text);
57
57
  this.store.recordUsage(userId, platform, res.cost || 0);
58
58
  if (this.config.agent.memory?.auto_summary)
@@ -63,7 +63,7 @@ export class AgentEngine {
63
63
  release();
64
64
  }
65
65
  }
66
- async runParallel(userId, prompt, platform, chatId, onChunk) {
66
+ async runParallel(userId, prompt, platform, chatId, onChunk, overrideTimeoutMs) {
67
67
  // No per-user lock — parallel tasks are independent
68
68
  // No session resume — fresh session to prevent conflicts
69
69
  const memories = this.config.agent.memory?.enabled ? this.store.getMemories(userId) : [];
@@ -75,7 +75,7 @@ export class AgentEngine {
75
75
  ? this.rotator.next()
76
76
  : { name: "cli-default", api_key: "", base_url: "", model: "" };
77
77
  try {
78
- const res = await this._executeNoSession(userId, prompt, platform, chatId, ep, onChunk, memoryPrompt);
78
+ const res = await this._executeNoSession(userId, prompt, platform, chatId, ep, onChunk, memoryPrompt, overrideTimeoutMs);
79
79
  this.store.recordUsage(userId, platform, res.cost || 0);
80
80
  return res;
81
81
  }
@@ -92,7 +92,7 @@ export class AgentEngine {
92
92
  }
93
93
  throw lastErr;
94
94
  }
95
- async _executeWithRetry(userId, prompt, platform, chatId, onChunk, memoryPrompt) {
95
+ async _executeWithRetry(userId, prompt, platform, chatId, onChunk, memoryPrompt, overrideTimeoutMs) {
96
96
  const maxRetries = Math.max(Math.min(this.rotator.count, 3), 1);
97
97
  let lastErr;
98
98
  for (let i = 0; i < maxRetries; i++) {
@@ -100,7 +100,7 @@ export class AgentEngine {
100
100
  ? this.rotator.next()
101
101
  : { name: "cli-default", api_key: "", base_url: "", model: "" };
102
102
  try {
103
- return await this._execute(userId, prompt, platform, chatId, ep, onChunk, memoryPrompt);
103
+ return await this._execute(userId, prompt, platform, chatId, ep, onChunk, memoryPrompt, overrideTimeoutMs);
104
104
  }
105
105
  catch (err) {
106
106
  lastErr = err;
@@ -115,7 +115,7 @@ export class AgentEngine {
115
115
  }
116
116
  throw lastErr;
117
117
  }
118
- _execute(userId, prompt, platform, chatId, ep, onChunk, memoryPrompt) {
118
+ _execute(userId, prompt, platform, chatId, ep, onChunk, memoryPrompt, overrideTimeoutMs) {
119
119
  return new Promise((resolve, reject) => {
120
120
  const sessionId = this.store.getSession(userId) || "";
121
121
  const cwd = this.getWorkDir(userId);
@@ -150,11 +150,11 @@ export class AgentEngine {
150
150
  const child = spawn("claude", args, { cwd, env, stdio: ["pipe", "pipe", "pipe"] });
151
151
  child.stdin.end();
152
152
  console.log(`[agent] spawned claude pid=${child.pid} cwd=${cwd} args=${args.join(" ")}`);
153
- const timeoutMs = (this.config.agent.timeout_seconds || 600) * 1000;
154
- const timer = setTimeout(() => { try {
153
+ const timeoutMs = overrideTimeoutMs !== undefined ? overrideTimeoutMs : (this.config.agent.timeout_seconds || 600) * 1000;
154
+ const timer = timeoutMs > 0 ? setTimeout(() => { try {
155
155
  child.kill("SIGTERM");
156
156
  }
157
- catch { } }, timeoutMs);
157
+ catch { } }, timeoutMs) : null;
158
158
  let fullText = "";
159
159
  let newSessionId = sessionId;
160
160
  let cost = 0;
@@ -202,7 +202,8 @@ export class AgentEngine {
202
202
  console.log(`[agent] stderr: ${s.slice(0, 200)}`);
203
203
  });
204
204
  child.on("close", (code, signal) => {
205
- clearTimeout(timer);
205
+ if (timer)
206
+ clearTimeout(timer);
206
207
  console.log(`[agent] claude exited code=${code} signal=${signal} fullText=${fullText.length}chars stderr=${stderr.slice(0, 200)}`);
207
208
  if (signal === "SIGTERM") {
208
209
  console.warn(`[agent] claude timed out after ${timeoutMs / 1000}s`);
@@ -225,7 +226,7 @@ export class AgentEngine {
225
226
  child.on("error", reject);
226
227
  });
227
228
  }
228
- _executeNoSession(userId, prompt, platform, chatId, ep, onChunk, memoryPrompt) {
229
+ _executeNoSession(userId, prompt, platform, chatId, ep, onChunk, memoryPrompt, overrideTimeoutMs) {
229
230
  return new Promise((resolve, reject) => {
230
231
  const cwd = this.getWorkDir(userId);
231
232
  const args = ["-p", prompt, "--verbose", "--output-format", "stream-json", "--permission-mode", this.config.agent.permission_mode || "acceptEdits"];
@@ -257,11 +258,11 @@ export class AgentEngine {
257
258
  const child = spawn("claude", args, { cwd, env, stdio: ["pipe", "pipe", "pipe"] });
258
259
  child.stdin.end();
259
260
  console.log(`[agent] spawned claude (parallel) pid=${child.pid} cwd=${cwd}`);
260
- const timeoutMs = (this.config.agent.timeout_seconds || 600) * 1000;
261
- const timer = setTimeout(() => { try {
261
+ const timeoutMs = overrideTimeoutMs !== undefined ? overrideTimeoutMs : (this.config.agent.timeout_seconds || 600) * 1000;
262
+ const timer = timeoutMs > 0 ? setTimeout(() => { try {
262
263
  child.kill("SIGTERM");
263
264
  }
264
- catch { } }, timeoutMs);
265
+ catch { } }, timeoutMs) : null;
265
266
  let fullText = "";
266
267
  let sessionId = "";
267
268
  let cost = 0;
@@ -300,7 +301,8 @@ export class AgentEngine {
300
301
  let stderr = "";
301
302
  child.stderr.on("data", (data) => { stderr += data.toString(); });
302
303
  child.on("close", (code, signal) => {
303
- clearTimeout(timer);
304
+ if (timer)
305
+ clearTimeout(timer);
304
306
  console.log(`[agent] claude (parallel) exited code=${code} signal=${signal} text=${fullText.length}chars`);
305
307
  if (signal === "SIGTERM") {
306
308
  console.warn(`[agent] claude (parallel) timed out after ${timeoutMs / 1000}s`);
package/dist/ctl.js CHANGED
@@ -165,8 +165,15 @@ else if (category === "auto") {
165
165
  db.prepare("UPDATE tasks SET status = 'cancelled' WHERE id = ?").run(parseInt(taskId));
166
166
  output({ ok: true, message: "Auto task cancelled" });
167
167
  }
168
+ else if (action === "clear") {
169
+ const [userId] = rest;
170
+ if (!userId)
171
+ fail("Usage: auto clear <user_id>");
172
+ const r = db.prepare("DELETE FROM tasks WHERE user_id = ? AND status IN ('done','failed','cancelled')").run(userId);
173
+ output({ ok: true, deleted: r.changes, message: `Cleared ${r.changes} completed/failed/cancelled task(s)` });
174
+ }
168
175
  else {
169
- fail("Usage: auto <add|add-approval|result|list|cancel> ...");
176
+ fail("Usage: auto <add|add-approval|result|list|cancel|clear> ...");
170
177
  }
171
178
  }
172
179
  else {
@@ -33,6 +33,7 @@ export function generateSkillDoc(ctx) {
33
33
  `- 创建定时自动任务: \`${ctl} auto add ${ctx.userId} ${ctx.platform} ${ctx.chatId} "任务描述" --delay <分钟数>\``,
34
34
  `- 查看自动任务: \`${ctl} auto list ${ctx.userId}\``,
35
35
  `- 取消自动任务: \`${ctl} auto cancel <任务ID>\``,
36
+ `- 清除已完成任务: \`${ctl} auto clear ${ctx.userId}\``,
36
37
  ``,
37
38
  `### 使用指南`,
38
39
  `- 用户要你记住某事 → 使用 memory add`,
@@ -141,6 +142,7 @@ export function generateSkillDoc(ctx) {
141
142
  `- Schedule a delayed auto task: \`${ctl} auto add ${ctx.userId} ${ctx.platform} ${ctx.chatId} "description" --delay <minutes>\``,
142
143
  `- List auto tasks: \`${ctl} auto list ${ctx.userId}\``,
143
144
  `- Cancel an auto task: \`${ctl} auto cancel <task_id>\``,
145
+ `- Clear completed tasks: \`${ctl} auto clear ${ctx.userId}\``,
144
146
  ``,
145
147
  `### Guidelines`,
146
148
  `- User wants you to remember something → use memory add`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emqo/claudebridge",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "Bridge claude CLI to chat platforms (Telegram, Discord) with scheduled auto-tasks, autonomous project management, HITL approval, conditional branching, webhook triggers, parallel execution, and observability",
5
5
  "main": "dist/index.js",
6
6
  "bin": {