@rallycry/conveyor-agent 2.6.0 → 2.7.0
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.
- package/dist/{chunk-DLQG36T4.js → chunk-JWIGEYRD.js} +117 -17
- package/dist/chunk-JWIGEYRD.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +22 -4
- package/dist/index.js +5 -1
- package/package.json +1 -1
- package/dist/chunk-DLQG36T4.js.map +0 -1
|
@@ -336,12 +336,47 @@ function cleanDevcontainerFromGit(workspaceDir, taskBranch, baseBranch) {
|
|
|
336
336
|
}
|
|
337
337
|
}
|
|
338
338
|
|
|
339
|
+
// src/worktree.ts
|
|
340
|
+
import { execSync as execSync2 } from "child_process";
|
|
341
|
+
import { existsSync } from "fs";
|
|
342
|
+
import { join as join2 } from "path";
|
|
343
|
+
var WORKTREE_DIR = ".worktrees";
|
|
344
|
+
function ensureWorktree(projectDir, taskId, branch) {
|
|
345
|
+
const worktreePath = join2(projectDir, WORKTREE_DIR, taskId);
|
|
346
|
+
if (existsSync(worktreePath)) {
|
|
347
|
+
if (branch) {
|
|
348
|
+
try {
|
|
349
|
+
execSync2(`git checkout ${branch}`, { cwd: worktreePath, stdio: "ignore" });
|
|
350
|
+
} catch {
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return worktreePath;
|
|
354
|
+
}
|
|
355
|
+
const target = branch ?? "HEAD";
|
|
356
|
+
execSync2(`git worktree add "${worktreePath}" ${target}`, {
|
|
357
|
+
cwd: projectDir,
|
|
358
|
+
stdio: "ignore"
|
|
359
|
+
});
|
|
360
|
+
return worktreePath;
|
|
361
|
+
}
|
|
362
|
+
function removeWorktree(projectDir, taskId) {
|
|
363
|
+
const worktreePath = join2(projectDir, WORKTREE_DIR, taskId);
|
|
364
|
+
if (!existsSync(worktreePath)) return;
|
|
365
|
+
try {
|
|
366
|
+
execSync2(`git worktree remove "${worktreePath}" --force`, {
|
|
367
|
+
cwd: projectDir,
|
|
368
|
+
stdio: "ignore"
|
|
369
|
+
});
|
|
370
|
+
} catch {
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
339
374
|
// src/runner.ts
|
|
340
375
|
import { randomUUID } from "crypto";
|
|
341
|
-
import { execSync as
|
|
376
|
+
import { execSync as execSync3 } from "child_process";
|
|
342
377
|
import { readdirSync, statSync, readFileSync } from "fs";
|
|
343
378
|
import { homedir } from "os";
|
|
344
|
-
import { join as
|
|
379
|
+
import { join as join3 } from "path";
|
|
345
380
|
import {
|
|
346
381
|
query,
|
|
347
382
|
tool,
|
|
@@ -351,6 +386,7 @@ import { z } from "zod";
|
|
|
351
386
|
var API_ERROR_PATTERN = /API Error: [45]\d\d/;
|
|
352
387
|
var RETRY_DELAYS_MS = [6e4, 12e4, 18e4, 3e5];
|
|
353
388
|
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
389
|
+
var PM_DENIED_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit", "MultiEdit", "NotebookEdit", "Bash"]);
|
|
354
390
|
var AgentRunner = class _AgentRunner {
|
|
355
391
|
config;
|
|
356
392
|
connection;
|
|
@@ -363,7 +399,8 @@ var AgentRunner = class _AgentRunner {
|
|
|
363
399
|
setupLog = [];
|
|
364
400
|
heartbeatTimer = null;
|
|
365
401
|
taskContext = null;
|
|
366
|
-
|
|
402
|
+
planFileSnapshot = /* @__PURE__ */ new Map();
|
|
403
|
+
worktreeActive = false;
|
|
367
404
|
static MAX_SETUP_LOG_LINES = 50;
|
|
368
405
|
constructor(config, callbacks) {
|
|
369
406
|
this.config = config;
|
|
@@ -417,6 +454,17 @@ var AgentRunner = class _AgentRunner {
|
|
|
417
454
|
}
|
|
418
455
|
}
|
|
419
456
|
this.initRtk();
|
|
457
|
+
if (this.config.mode === "pm" || process.env.CONVEYOR_USE_WORKTREE === "true") {
|
|
458
|
+
try {
|
|
459
|
+
const worktreePath = ensureWorktree(this.config.workspaceDir, this.config.taskId);
|
|
460
|
+
this.config = { ...this.config, workspaceDir: worktreePath };
|
|
461
|
+
this.worktreeActive = true;
|
|
462
|
+
this.setupLog.push(`[conveyor] Using worktree: ${worktreePath}`);
|
|
463
|
+
} catch (error) {
|
|
464
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
465
|
+
this.setupLog.push(`[conveyor] Worktree creation failed, using shared workspace: ${msg}`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
420
468
|
await this.setState("fetching_context");
|
|
421
469
|
try {
|
|
422
470
|
this.taskContext = await this.connection.fetchTaskContext();
|
|
@@ -439,6 +487,27 @@ var AgentRunner = class _AgentRunner {
|
|
|
439
487
|
this.setupLog.push(`[conveyor] ${result.message}`);
|
|
440
488
|
}
|
|
441
489
|
}
|
|
490
|
+
if (!this.worktreeActive && this.taskContext.useWorktree) {
|
|
491
|
+
try {
|
|
492
|
+
const worktreePath = ensureWorktree(this.config.workspaceDir, this.config.taskId);
|
|
493
|
+
this.config = { ...this.config, workspaceDir: worktreePath };
|
|
494
|
+
this.worktreeActive = true;
|
|
495
|
+
this.setupLog.push(`[conveyor] Using worktree (from task config): ${worktreePath}`);
|
|
496
|
+
} catch (error) {
|
|
497
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
498
|
+
this.setupLog.push(`[conveyor] Worktree creation failed, using shared workspace: ${msg}`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (this.worktreeActive && this.taskContext.githubBranch) {
|
|
502
|
+
try {
|
|
503
|
+
const branch = this.taskContext.githubBranch;
|
|
504
|
+
execSync3(`git fetch origin ${branch} && git checkout ${branch}`, {
|
|
505
|
+
cwd: this.config.workspaceDir,
|
|
506
|
+
stdio: "ignore"
|
|
507
|
+
});
|
|
508
|
+
} catch {
|
|
509
|
+
}
|
|
510
|
+
}
|
|
442
511
|
const isPm = this.config.mode === "pm";
|
|
443
512
|
if (isPm) {
|
|
444
513
|
await this.setState("idle");
|
|
@@ -535,8 +604,8 @@ The agent cannot start until this is resolved.`
|
|
|
535
604
|
}
|
|
536
605
|
initRtk() {
|
|
537
606
|
try {
|
|
538
|
-
|
|
539
|
-
|
|
607
|
+
execSync3("rtk --version", { stdio: "ignore" });
|
|
608
|
+
execSync3("rtk init --global --auto-patch", { stdio: "ignore" });
|
|
540
609
|
} catch {
|
|
541
610
|
}
|
|
542
611
|
}
|
|
@@ -1029,8 +1098,8 @@ You have access to Conveyor MCP tools to interact with the task management syste
|
|
|
1029
1098
|
});
|
|
1030
1099
|
this.currentTurnToolCalls = [];
|
|
1031
1100
|
}
|
|
1032
|
-
if (this.config.mode === "pm"
|
|
1033
|
-
this.syncPlanFile(
|
|
1101
|
+
if (this.config.mode === "pm") {
|
|
1102
|
+
this.syncPlanFile();
|
|
1034
1103
|
}
|
|
1035
1104
|
break;
|
|
1036
1105
|
}
|
|
@@ -1091,11 +1160,31 @@ You have access to Conveyor MCP tools to interact with the task management syste
|
|
|
1091
1160
|
return { retriable };
|
|
1092
1161
|
}
|
|
1093
1162
|
/**
|
|
1094
|
-
*
|
|
1095
|
-
*
|
|
1163
|
+
* Snapshot current plan files so syncPlanFile can distinguish files created
|
|
1164
|
+
* by THIS session from ones created by a concurrent agent.
|
|
1096
1165
|
*/
|
|
1097
|
-
|
|
1098
|
-
const plansDir =
|
|
1166
|
+
snapshotPlanFiles() {
|
|
1167
|
+
const plansDir = join3(homedir(), ".claude", "plans");
|
|
1168
|
+
this.planFileSnapshot.clear();
|
|
1169
|
+
try {
|
|
1170
|
+
for (const file of readdirSync(plansDir).filter((f) => f.endsWith(".md"))) {
|
|
1171
|
+
try {
|
|
1172
|
+
const stat = statSync(join3(plansDir, file));
|
|
1173
|
+
this.planFileSnapshot.set(file, stat.mtimeMs);
|
|
1174
|
+
} catch {
|
|
1175
|
+
continue;
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
} catch {
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
/**
|
|
1182
|
+
* After a PM-mode query, scan ~/.claude/plans/ for plan files that were
|
|
1183
|
+
* created or modified by THIS session (not present in the pre-query snapshot)
|
|
1184
|
+
* and push the newest one to the task.
|
|
1185
|
+
*/
|
|
1186
|
+
syncPlanFile() {
|
|
1187
|
+
const plansDir = join3(homedir(), ".claude", "plans");
|
|
1099
1188
|
let files;
|
|
1100
1189
|
try {
|
|
1101
1190
|
files = readdirSync(plansDir).filter((f) => f.endsWith(".md"));
|
|
@@ -1104,10 +1193,12 @@ You have access to Conveyor MCP tools to interact with the task management syste
|
|
|
1104
1193
|
}
|
|
1105
1194
|
let newest = null;
|
|
1106
1195
|
for (const file of files) {
|
|
1107
|
-
const fullPath =
|
|
1196
|
+
const fullPath = join3(plansDir, file);
|
|
1108
1197
|
try {
|
|
1109
1198
|
const stat = statSync(fullPath);
|
|
1110
|
-
|
|
1199
|
+
const prevMtime = this.planFileSnapshot.get(file);
|
|
1200
|
+
const isNew = prevMtime === void 0 || stat.mtimeMs > prevMtime;
|
|
1201
|
+
if (isNew && (!newest || stat.mtimeMs > newest.mtime)) {
|
|
1111
1202
|
newest = { path: fullPath, mtime: stat.mtimeMs };
|
|
1112
1203
|
}
|
|
1113
1204
|
} catch {
|
|
@@ -1142,8 +1233,9 @@ You have access to Conveyor MCP tools to interact with the task management syste
|
|
|
1142
1233
|
const pmDisallowedTools = this.config.mode === "pm" ? ["TodoWrite", "TodoRead"] : [];
|
|
1143
1234
|
const disallowedTools = [...settings.disallowedTools ?? [], ...pmDisallowedTools];
|
|
1144
1235
|
const isPm = this.config.mode === "pm";
|
|
1145
|
-
|
|
1146
|
-
|
|
1236
|
+
if (isPm) {
|
|
1237
|
+
this.snapshotPlanFiles();
|
|
1238
|
+
}
|
|
1147
1239
|
const QUESTION_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
1148
1240
|
const canUseTool = async (toolName, input) => {
|
|
1149
1241
|
if (toolName === "AskUserQuestion") {
|
|
@@ -1172,6 +1264,12 @@ You have access to Conveyor MCP tools to interact with the task management syste
|
|
|
1172
1264
|
updatedInput: { questions: input.questions, answers }
|
|
1173
1265
|
};
|
|
1174
1266
|
}
|
|
1267
|
+
if (isPm && PM_DENIED_TOOLS.has(toolName)) {
|
|
1268
|
+
return {
|
|
1269
|
+
behavior: "deny",
|
|
1270
|
+
message: "PM mode is plan-only. Use the update_task tool to save your plan."
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1175
1273
|
return { behavior: "allow", updatedInput: input };
|
|
1176
1274
|
};
|
|
1177
1275
|
const commonOptions = {
|
|
@@ -1216,7 +1314,7 @@ ${followUpContent}` : followUpContent;
|
|
|
1216
1314
|
await this.runWithRetry(agentQuery, context, commonOptions);
|
|
1217
1315
|
}
|
|
1218
1316
|
if (isPm) {
|
|
1219
|
-
this.syncPlanFile(
|
|
1317
|
+
this.syncPlanFile();
|
|
1220
1318
|
}
|
|
1221
1319
|
}
|
|
1222
1320
|
/**
|
|
@@ -1292,6 +1390,8 @@ export {
|
|
|
1292
1390
|
loadConveyorConfig,
|
|
1293
1391
|
runSetupCommand,
|
|
1294
1392
|
runStartCommand,
|
|
1393
|
+
ensureWorktree,
|
|
1394
|
+
removeWorktree,
|
|
1295
1395
|
AgentRunner
|
|
1296
1396
|
};
|
|
1297
|
-
//# sourceMappingURL=chunk-
|
|
1397
|
+
//# sourceMappingURL=chunk-JWIGEYRD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/connection.ts","../src/setup.ts","../src/worktree.ts","../src/runner.ts"],"sourcesContent":["import { io, type Socket } from \"socket.io-client\";\nimport type { AgentRunnerConfig, TaskContext, AgentEvent } from \"./types.js\";\n\ninterface AgentQuestionOption {\n label: string;\n description: string;\n preview?: string;\n}\n\ninterface AgentQuestion {\n question: string;\n header: string;\n options: AgentQuestionOption[];\n multiSelect?: boolean;\n}\n\nexport class ConveyorConnection {\n private socket: Socket | null = null;\n private config: AgentRunnerConfig;\n private eventBuffer: { taskId: string; event: AgentEvent }[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private static readonly EVENT_BATCH_MS = 500;\n\n private earlyMessages: { content: string; userId: string }[] = [];\n private earlyStop = false;\n private chatMessageCallback: ((msg: { content: string; userId: string }) => void) | null = null;\n private stopCallback: (() => void) | null = null;\n private pendingQuestionResolvers = new Map<string, (answers: Record<string, string>) => void>();\n\n constructor(config: AgentRunnerConfig) {\n this.config = config;\n }\n\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n let settled = false;\n let attempts = 0;\n const maxInitialAttempts = 30;\n\n this.socket = io(this.config.conveyorApiUrl, {\n auth: { taskToken: this.config.taskToken, runnerMode: this.config.mode ?? \"task\" },\n transports: [\"websocket\"],\n reconnection: true,\n reconnectionAttempts: Infinity,\n reconnectionDelay: 2000,\n reconnectionDelayMax: 30000,\n randomizationFactor: 0.3,\n extraHeaders: {\n \"ngrok-skip-browser-warning\": \"true\",\n },\n });\n\n // Register listeners immediately so we capture messages the server\n // flushes during registerHandlers (before connect() resolves).\n this.socket.on(\"agentRunner:incomingMessage\", (msg: { content: string; userId: string }) => {\n if (this.chatMessageCallback) {\n this.chatMessageCallback(msg);\n } else {\n this.earlyMessages.push(msg);\n }\n });\n\n this.socket.on(\"agentRunner:stop\", () => {\n if (this.stopCallback) {\n this.stopCallback();\n } else {\n this.earlyStop = true;\n }\n });\n\n this.socket.on(\n \"agentRunner:questionAnswer\",\n (data: { requestId: string; answers: Record<string, string> }) => {\n const resolver = this.pendingQuestionResolvers.get(data.requestId);\n if (resolver) {\n this.pendingQuestionResolvers.delete(data.requestId);\n resolver(data.answers);\n }\n },\n );\n\n this.socket.on(\"connect\", () => {\n if (!settled) {\n settled = true;\n resolve();\n }\n });\n\n this.socket.io.on(\"reconnect_attempt\", () => {\n attempts++;\n if (!settled && attempts >= maxInitialAttempts) {\n settled = true;\n reject(new Error(`Failed to connect after ${maxInitialAttempts} attempts`));\n }\n });\n });\n }\n\n fetchChatMessages(\n limit?: number,\n ): Promise<\n { role: string; content: string; userId: string | null; userName?: string; createdAt: string }[]\n > {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getChatMessages\",\n { taskId: this.config.taskId, limit },\n (response: {\n success: boolean;\n data?: {\n role: string;\n content: string;\n userId: string | null;\n userName?: string;\n createdAt: string;\n }[];\n error?: string;\n }): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch chat messages\"));\n }\n },\n );\n });\n }\n\n fetchTaskContext(): Promise<TaskContext> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getTaskContext\",\n { taskId: this.config.taskId },\n (response: { success: boolean; data?: TaskContext; error?: string }): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch task context\"));\n }\n },\n );\n });\n }\n\n sendEvent(event: AgentEvent): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.eventBuffer.push({ taskId: this.config.taskId, event });\n if (!this.flushTimer) {\n this.flushTimer = setTimeout(() => this.flushEvents(), ConveyorConnection.EVENT_BATCH_MS);\n }\n }\n\n flushEvents(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n if (!this.socket || this.eventBuffer.length === 0) return;\n for (const entry of this.eventBuffer) {\n this.socket.emit(\"agentRunner:event\", entry);\n }\n this.eventBuffer = [];\n }\n\n updateStatus(status: string): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:statusUpdate\", {\n taskId: this.config.taskId,\n status,\n });\n }\n\n postChatMessage(content: string): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:chatMessage\", {\n taskId: this.config.taskId,\n content,\n });\n }\n\n createPR(params: {\n title: string;\n body: string;\n baseBranch?: string;\n }): Promise<{ url: string; number: number }> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:createPR\",\n { taskId: this.config.taskId, ...params },\n (response: {\n success: boolean;\n data?: { url: string; number: number };\n error?: string;\n }): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to create pull request\"));\n }\n },\n );\n });\n }\n\n askUserQuestion(requestId: string, questions: AgentQuestion[]): Promise<Record<string, string>> {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:askUserQuestion\", {\n taskId: this.config.taskId,\n requestId,\n questions,\n });\n\n return new Promise((resolve) => {\n this.pendingQuestionResolvers.set(requestId, resolve);\n });\n }\n\n cancelPendingQuestions(): void {\n this.pendingQuestionResolvers.clear();\n }\n\n storeSessionId(sessionId: string): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:storeSessionId\", {\n taskId: this.config.taskId,\n sessionId,\n });\n }\n\n updateTaskFields(fields: { plan?: string; description?: string }): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"agentRunner:updateTaskFields\", {\n taskId: this.config.taskId,\n fields,\n });\n }\n\n onChatMessage(callback: (message: { content: string; userId: string }) => void): void {\n this.chatMessageCallback = callback;\n for (const msg of this.earlyMessages) {\n callback(msg);\n }\n this.earlyMessages = [];\n }\n\n onStopRequested(callback: () => void): void {\n this.stopCallback = callback;\n if (this.earlyStop) {\n callback();\n this.earlyStop = false;\n }\n }\n\n trackSpending(params: {\n agentId: string;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n totalCostUsd: number;\n onSubscription: boolean;\n }): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:trackSpending\", {\n taskId: this.config.taskId,\n ...params,\n });\n }\n\n emitStatus(status: string): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:statusUpdate\", {\n taskId: this.config.taskId,\n status,\n });\n }\n\n sendHeartbeat(): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:heartbeat\", {\n taskId: this.config.taskId,\n });\n }\n\n sendTypingStart(): void {\n this.sendEvent({ type: \"agent_typing_start\" });\n }\n\n sendTypingStop(): void {\n this.sendEvent({ type: \"agent_typing_stop\" });\n }\n\n disconnect(): void {\n this.flushEvents();\n this.socket?.disconnect();\n this.socket = null;\n }\n}\n","import { execSync } from \"node:child_process\";\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport interface ConveyorConfig {\n setupCommand?: string;\n startCommand?: string;\n previewPort?: number;\n}\n\nconst CONVEYOR_CONFIG_PATH = \".conveyor/config.json\";\nconst DEVCONTAINER_PATH = \".devcontainer/conveyor/devcontainer.json\";\n\nexport async function loadForwardPorts(workspaceDir: string): Promise<number[]> {\n try {\n const raw = await readFile(join(workspaceDir, DEVCONTAINER_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as { forwardPorts?: number[] };\n return parsed.forwardPorts ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function loadConveyorConfig(workspaceDir: string): Promise<ConveyorConfig | null> {\n // Primary: .conveyor/config.json\n try {\n const raw = await readFile(join(workspaceDir, CONVEYOR_CONFIG_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as ConveyorConfig;\n if (parsed.setupCommand || parsed.startCommand) return parsed;\n } catch {\n // Not found or invalid — try fallback\n }\n\n // Fallback: devcontainer.json \"conveyor\" section\n try {\n const raw = await readFile(join(workspaceDir, DEVCONTAINER_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as { conveyor?: ConveyorConfig };\n if (parsed.conveyor && (parsed.conveyor.startCommand || parsed.conveyor.setupCommand)) {\n return parsed.conveyor;\n }\n } catch {\n // Not found or invalid\n }\n\n return null;\n}\n\n/**\n * Runs a command synchronously (waits for exit). Streams stdout/stderr\n * line-by-line via the onOutput callback.\n */\nexport function runSetupCommand(\n cmd: string,\n cwd: string,\n onOutput: (stream: \"stdout\" | \"stderr\", data: string) => void,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"sh\", [\"-c\", cmd], {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env },\n });\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n onOutput(\"stdout\", chunk.toString());\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n onOutput(\"stderr\", chunk.toString());\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`Setup command exited with code ${code}`));\n }\n });\n\n child.on(\"error\", (err) => {\n reject(err);\n });\n });\n}\n\n/**\n * Runs a command in the background (does not wait for exit). Returns the\n * ChildProcess so it can be cleaned up on agent shutdown. Streams\n * stdout/stderr via the onOutput callback.\n */\nexport function runStartCommand(\n cmd: string,\n cwd: string,\n onOutput: (stream: \"stdout\" | \"stderr\", data: string) => void,\n): ChildProcess {\n const child = spawn(\"sh\", [\"-c\", cmd], {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: true,\n env: { ...process.env },\n });\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n onOutput(\"stdout\", chunk.toString());\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n onOutput(\"stderr\", chunk.toString());\n });\n\n child.unref();\n return child;\n}\n\n/**\n * Reset `.devcontainer/conveyor/devcontainer.json` to match the base branch\n * and remove the cloud-build \"configure\" commit from git history. This runs\n * AFTER the codespace has started (env vars are already in process memory)\n * so the agent sees a branch identical to base — no spurious diffs, no\n * rebase conflicts on devcontainer.json.\n */\nexport function cleanDevcontainerFromGit(\n workspaceDir: string,\n taskBranch: string,\n baseBranch: string,\n): { cleaned: boolean; message: string } {\n const git = (cmd: string): string =>\n execSync(cmd, { cwd: workspaceDir, encoding: \"utf-8\", timeout: 30_000 }).trim();\n\n try {\n git(`git fetch origin ${baseBranch}`);\n } catch {\n return { cleaned: false, message: `Failed to fetch origin/${baseBranch}` };\n }\n\n // Check if devcontainer.json differs from base\n try {\n git(`git diff --quiet origin/${baseBranch} -- ${DEVCONTAINER_PATH}`);\n return { cleaned: false, message: \"devcontainer.json already matches base\" };\n } catch {\n // diff --quiet exits non-zero when there IS a diff — expected path\n }\n\n try {\n const ahead = parseInt(git(`git rev-list --count origin/${baseBranch}..HEAD`), 10);\n\n if (ahead <= 1) {\n // Fresh start: only the devcontainer commit exists — hard reset to base\n git(`git reset --hard origin/${baseBranch}`);\n } else {\n // Relaunch: agent has prior commits — restore file and add fixup commit\n git(`git checkout origin/${baseBranch} -- ${DEVCONTAINER_PATH}`);\n git(`git add ${DEVCONTAINER_PATH}`);\n\n try {\n git(`git diff --cached --quiet -- ${DEVCONTAINER_PATH}`);\n return { cleaned: false, message: \"devcontainer.json already clean in working tree\" };\n } catch {\n git(`git commit -m \"chore: reset devcontainer config\"`);\n }\n }\n\n git(`git push --force-with-lease origin ${taskBranch}`);\n return { cleaned: true, message: \"devcontainer.json cleaned from git history\" };\n } catch (err) {\n const msg = err instanceof Error ? err.message : \"Unknown error\";\n return { cleaned: false, message: `Git cleanup failed: ${msg}` };\n }\n}\n","import { execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst WORKTREE_DIR = \".worktrees\";\n\n/**\n * Ensure a git worktree exists for the given task. Creates one if it doesn't\n * exist, reuses the existing one otherwise. Returns the absolute worktree path.\n */\nexport function ensureWorktree(projectDir: string, taskId: string, branch?: string): string {\n const worktreePath = join(projectDir, WORKTREE_DIR, taskId);\n\n if (existsSync(worktreePath)) {\n if (branch) {\n try {\n execSync(`git checkout ${branch}`, { cwd: worktreePath, stdio: \"ignore\" });\n } catch {\n /* already on branch or branch doesn't exist locally yet */\n }\n }\n return worktreePath;\n }\n\n const target = branch ?? \"HEAD\";\n execSync(`git worktree add \"${worktreePath}\" ${target}`, {\n cwd: projectDir,\n stdio: \"ignore\",\n });\n\n return worktreePath;\n}\n\n/**\n * Remove a task's git worktree. Best-effort — silently ignores failures.\n */\nexport function removeWorktree(projectDir: string, taskId: string): void {\n const worktreePath = join(projectDir, WORKTREE_DIR, taskId);\n if (!existsSync(worktreePath)) return;\n try {\n execSync(`git worktree remove \"${worktreePath}\" --force`, {\n cwd: projectDir,\n stdio: \"ignore\",\n });\n } catch {\n /* best effort */\n }\n}\n","// oxlint-disable max-lines\nimport { randomUUID } from \"node:crypto\";\nimport { execSync } from \"node:child_process\";\nimport { readdirSync, statSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n query,\n tool,\n createSdkMcpServer,\n type SDKMessage,\n type SDKUserMessage,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod\";\nimport type {\n AgentRunnerConfig,\n AgentRunnerCallbacks,\n AgentRunnerStatus,\n AgentEvent,\n TaskContext,\n ActivityEventSummary,\n} from \"./types.js\";\nimport { ConveyorConnection } from \"./connection.js\";\nimport {\n cleanDevcontainerFromGit,\n loadConveyorConfig,\n loadForwardPorts,\n runSetupCommand,\n runStartCommand,\n type ConveyorConfig,\n} from \"./setup.js\";\nimport { ensureWorktree } from \"./worktree.js\";\n\nconst API_ERROR_PATTERN = /API Error: [45]\\d\\d/;\nconst RETRY_DELAYS_MS = [60_000, 120_000, 180_000, 300_000]; // 1, 2, 3, 5 minutes\nconst HEARTBEAT_INTERVAL_MS = 30_000;\n\nconst PM_DENIED_TOOLS = new Set([\"Write\", \"Edit\", \"MultiEdit\", \"NotebookEdit\", \"Bash\"]);\n\nexport class AgentRunner {\n private config: AgentRunnerConfig;\n private connection: ConveyorConnection;\n private callbacks: AgentRunnerCallbacks;\n private _state: AgentRunnerStatus = \"connecting\";\n private stopped = false;\n private inputResolver: ((msg: SDKUserMessage) => void) | null = null;\n private pendingMessages: SDKUserMessage[] = [];\n private currentTurnToolCalls: ActivityEventSummary[] = [];\n private setupLog: string[] = [];\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private taskContext: TaskContext | null = null;\n private planFileSnapshot = new Map<string, number>();\n private worktreeActive = false;\n private static readonly MAX_SETUP_LOG_LINES = 50;\n\n constructor(config: AgentRunnerConfig, callbacks: AgentRunnerCallbacks) {\n this.config = config;\n this.connection = new ConveyorConnection(config);\n this.callbacks = callbacks;\n }\n\n get state(): AgentRunnerStatus {\n return this._state;\n }\n\n private async setState(status: AgentRunnerStatus): Promise<void> {\n this._state = status;\n this.connection.emitStatus(status);\n await this.callbacks.onStatusChange(status);\n }\n\n private startHeartbeat(): void {\n this.heartbeatTimer = setInterval(() => {\n if (!this.stopped) {\n this.connection.sendHeartbeat();\n }\n }, HEARTBEAT_INTERVAL_MS);\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n // oxlint-disable-next-line max-lines-per-function\n async start(): Promise<void> {\n // --- Phase 1: Connect ---\n await this.setState(\"connecting\");\n await this.connection.connect();\n\n this.connection.onStopRequested(() => {\n this.stop();\n });\n\n this.connection.onChatMessage((message) => {\n this.injectHumanMessage(message.content);\n });\n\n await this.setState(\"connected\");\n this.connection.sendEvent({\n type: \"connected\",\n taskId: this.config.taskId,\n });\n this.startHeartbeat();\n\n // --- Phase 2: Setup (task mode + codespace only) ---\n if (this.config.mode !== \"pm\" && process.env.CODESPACES === \"true\") {\n const setupOk = await this.runSetupSafe();\n if (!setupOk) {\n this.stopHeartbeat();\n await this.setState(\"error\");\n this.connection.disconnect();\n return;\n }\n }\n\n this.initRtk();\n\n // --- Phase 2.5: Worktree isolation (local agents) ---\n if (this.config.mode === \"pm\" || process.env.CONVEYOR_USE_WORKTREE === \"true\") {\n try {\n const worktreePath = ensureWorktree(this.config.workspaceDir, this.config.taskId);\n this.config = { ...this.config, workspaceDir: worktreePath };\n this.worktreeActive = true;\n this.setupLog.push(`[conveyor] Using worktree: ${worktreePath}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n this.setupLog.push(`[conveyor] Worktree creation failed, using shared workspace: ${msg}`);\n }\n }\n\n // --- Phase 3: Fetch context ---\n await this.setState(\"fetching_context\");\n try {\n this.taskContext = await this.connection.fetchTaskContext();\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Failed to fetch task context\";\n this.connection.sendEvent({ type: \"error\", message });\n await this.callbacks.onEvent({ type: \"error\", message });\n this.stopHeartbeat();\n await this.setState(\"error\");\n this.connection.disconnect();\n return;\n }\n\n if (process.env.CODESPACES === \"true\" && this.taskContext.baseBranch) {\n const result = cleanDevcontainerFromGit(\n this.config.workspaceDir,\n this.taskContext.githubBranch,\n this.taskContext.baseBranch,\n );\n if (result.cleaned) {\n this.setupLog.push(`[conveyor] ${result.message}`);\n }\n }\n\n if (!this.worktreeActive && this.taskContext.useWorktree) {\n try {\n const worktreePath = ensureWorktree(this.config.workspaceDir, this.config.taskId);\n this.config = { ...this.config, workspaceDir: worktreePath };\n this.worktreeActive = true;\n this.setupLog.push(`[conveyor] Using worktree (from task config): ${worktreePath}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n this.setupLog.push(`[conveyor] Worktree creation failed, using shared workspace: ${msg}`);\n }\n }\n\n if (this.worktreeActive && this.taskContext.githubBranch) {\n try {\n const branch = this.taskContext.githubBranch;\n execSync(`git fetch origin ${branch} && git checkout ${branch}`, {\n cwd: this.config.workspaceDir,\n stdio: \"ignore\",\n });\n } catch {\n /* branch may not exist remotely yet or already checked out */\n }\n }\n\n // --- Phase 4: Initial action ---\n const isPm = this.config.mode === \"pm\";\n if (isPm) {\n await this.setState(\"idle\");\n } else {\n await this.setState(\"running\");\n await this.runSdkQuery(this.taskContext);\n if (!this.stopped) {\n await this.setState(\"idle\");\n }\n }\n\n // --- Phase 5: Core loop — stay alive for follow-up messages ---\n while (!this.stopped) {\n if (this._state === \"idle\") {\n const msg = await this.waitForUserContent();\n if (!msg) break;\n\n await this.setState(\"running\");\n await this.runSdkQuery(this.taskContext, msg);\n\n if (!this.stopped) {\n await this.setState(\"idle\");\n }\n } else if (this._state === \"error\") {\n await this.setState(\"idle\");\n } else {\n break;\n }\n }\n\n // --- Cleanup ---\n this.stopHeartbeat();\n await this.setState(\"finished\");\n this.connection.disconnect();\n }\n\n /**\n * Wraps project setup in try/catch. On failure, posts error to chat\n * directly (no SDK needed) and streams to CLI. Returns false if setup failed.\n */\n private async runSetupSafe(): Promise<boolean> {\n await this.setState(\"setup\");\n\n const ports = await loadForwardPorts(this.config.workspaceDir);\n if (ports.length > 0 && process.env.CODESPACE_NAME) {\n const visibility = ports.map((p) => `${p}:public`).join(\" \");\n runStartCommand(\n `gh codespace ports visibility ${visibility} -c \"${process.env.CODESPACE_NAME}\" 2>/dev/null`,\n this.config.workspaceDir,\n () => undefined,\n );\n }\n\n const config = await loadConveyorConfig(this.config.workspaceDir);\n if (!config) {\n this.connection.sendEvent({ type: \"setup_complete\" });\n await this.callbacks.onEvent({ type: \"setup_complete\" });\n return true;\n }\n\n try {\n await this.executeSetupConfig(config);\n const setupEvent: AgentEvent = {\n type: \"setup_complete\",\n previewPort: config.previewPort ?? undefined,\n };\n this.connection.sendEvent(setupEvent);\n await this.callbacks.onEvent(setupEvent);\n return true;\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Setup failed\";\n this.connection.sendEvent({ type: \"setup_error\", message });\n await this.callbacks.onEvent({ type: \"setup_error\", message });\n this.connection.postChatMessage(\n `Environment setup failed: ${message}\\nThe agent cannot start until this is resolved.`,\n );\n return false;\n }\n }\n\n private pushSetupLog(line: string): void {\n this.setupLog.push(line);\n if (this.setupLog.length > AgentRunner.MAX_SETUP_LOG_LINES) {\n this.setupLog.splice(0, this.setupLog.length - AgentRunner.MAX_SETUP_LOG_LINES);\n }\n }\n\n private async executeSetupConfig(config: ConveyorConfig): Promise<void> {\n if (config.setupCommand) {\n this.pushSetupLog(`$ ${config.setupCommand}`);\n await runSetupCommand(config.setupCommand, this.config.workspaceDir, (stream, data) => {\n this.connection.sendEvent({ type: \"setup_output\", stream, data });\n for (const line of data.split(\"\\n\").filter(Boolean)) {\n this.pushSetupLog(`[${stream}] ${line}`);\n }\n });\n this.pushSetupLog(\"(exit 0)\");\n }\n\n if (config.startCommand) {\n this.pushSetupLog(`$ ${config.startCommand} & (background)`);\n runStartCommand(config.startCommand, this.config.workspaceDir, (stream, data) => {\n this.connection.sendEvent({ type: \"start_command_output\", stream, data });\n });\n }\n }\n\n private initRtk(): void {\n try {\n execSync(\"rtk --version\", { stdio: \"ignore\" });\n execSync(\"rtk init --global --auto-patch\", { stdio: \"ignore\" });\n } catch {\n // RTK not installed — skip silently\n }\n }\n\n private injectHumanMessage(content: string): void {\n const msg: SDKUserMessage = {\n type: \"user\" as const,\n session_id: \"\",\n message: { role: \"user\" as const, content },\n parent_tool_use_id: null,\n };\n\n if (this.inputResolver) {\n const resolve = this.inputResolver;\n this.inputResolver = null;\n resolve(msg);\n } else {\n this.pendingMessages.push(msg);\n }\n }\n\n private waitForMessage(): Promise<SDKUserMessage | null> {\n return new Promise<SDKUserMessage | null>((resolve) => {\n const checkStopped = setInterval(() => {\n if (this.stopped) {\n clearInterval(checkStopped);\n this.inputResolver = null;\n resolve(null);\n }\n }, 1000);\n\n this.inputResolver = (msg: SDKUserMessage) => {\n clearInterval(checkStopped);\n resolve(msg);\n };\n });\n }\n\n /**\n * Wait for the next user message content string. Drains pendingMessages first.\n * Returns null if stopped.\n */\n private async waitForUserContent(): Promise<string | null> {\n if (this.pendingMessages.length > 0) {\n const next = this.pendingMessages.shift()!;\n return (next.message as { content: string }).content;\n }\n\n const msg = await this.waitForMessage();\n if (!msg) return null;\n return (msg.message as { content: string }).content;\n }\n\n private async *createInputStream(\n initialPrompt: string,\n ): AsyncGenerator<SDKUserMessage, void, unknown> {\n const makeUserMessage = (content: string): SDKUserMessage => ({\n type: \"user\" as const,\n session_id: \"\",\n message: { role: \"user\" as const, content },\n parent_tool_use_id: null,\n });\n\n yield makeUserMessage(initialPrompt);\n\n while (!this.stopped) {\n if (this.pendingMessages.length > 0) {\n const next = this.pendingMessages.shift();\n if (next) {\n yield next;\n }\n continue;\n }\n\n this.connection.emitStatus(\"waiting_for_input\");\n await this.callbacks.onStatusChange(\"waiting_for_input\");\n const msg = await this.waitForMessage();\n\n if (!msg) break;\n this.connection.emitStatus(\"running\");\n await this.callbacks.onStatusChange(\"running\");\n yield msg;\n }\n }\n\n private findLastAgentMessageIndex(history: TaskContext[\"chatHistory\"]): number {\n for (let i = history.length - 1; i >= 0; i--) {\n if (history[i].role === \"assistant\") return i;\n }\n return -1;\n }\n\n private detectRelaunchScenario(\n context: TaskContext,\n ): \"fresh\" | \"idle_relaunch\" | \"feedback_relaunch\" {\n const lastAgentIdx = this.findLastAgentMessageIndex(context.chatHistory);\n if (lastAgentIdx === -1) return \"fresh\";\n\n const hasPriorWork = !!context.githubPRUrl || !!context.claudeSessionId;\n if (!hasPriorWork) return \"fresh\";\n\n const messagesAfterAgent = context.chatHistory.slice(lastAgentIdx + 1);\n const hasNewUserMessages = messagesAfterAgent.some((m) => m.role === \"user\");\n return hasNewUserMessages ? \"feedback_relaunch\" : \"idle_relaunch\";\n }\n\n // eslint-disable-next-line max-lines-per-function\n private buildInitialPrompt(context: TaskContext): string {\n const parts: string[] = [];\n const scenario = this.detectRelaunchScenario(context);\n\n if (context.claudeSessionId && scenario !== \"fresh\") {\n if (this.config.mode === \"pm\") {\n const lastAgentIdx = this.findLastAgentMessageIndex(context.chatHistory);\n const newMessages = context.chatHistory\n .slice(lastAgentIdx + 1)\n .filter((m) => m.role === \"user\");\n if (newMessages.length > 0) {\n parts.push(\n `You have been relaunched. Here are new messages since your last session:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n );\n } else {\n parts.push(`You have been relaunched. No new messages since your last session.`);\n }\n parts.push(\n `\\nYou are the project manager for this task.`,\n `Review the context above and wait for the team to provide instructions before taking action.`,\n );\n } else if (scenario === \"feedback_relaunch\") {\n const lastAgentIdx = this.findLastAgentMessageIndex(context.chatHistory);\n const newMessages = context.chatHistory\n .slice(lastAgentIdx + 1)\n .filter((m) => m.role === \"user\");\n parts.push(\n `You have been relaunched with new feedback.`,\n `Work on the git branch \"${context.githubBranch}\".`,\n `\\nNew messages since your last run:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n `\\nAddress the requested changes. Commit and push your updates.`,\n );\n if (context.githubPRUrl) {\n parts.push(\n `An existing PR is open at ${context.githubPRUrl} — push to the same branch. Do NOT create a new PR.`,\n );\n } else {\n parts.push(\n `When finished, use the create_pull_request tool to open a PR. Do NOT use gh CLI.`,\n );\n }\n } else {\n parts.push(\n `You were relaunched but no new instructions have been given since your last run.`,\n `Work on the git branch \"${context.githubBranch}\".`,\n `Review the current state of the codebase and verify everything is working correctly.`,\n `Post a brief status update to the chat, then wait for further instructions.`,\n );\n if (context.githubPRUrl) {\n parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);\n }\n }\n return parts.join(\"\\n\");\n }\n\n parts.push(`# Task: ${context.title}`);\n if (context.description) {\n parts.push(`\\n## Description\\n${context.description}`);\n }\n if (context.plan) {\n parts.push(`\\n## Plan\\n${context.plan}`);\n }\n\n if (context.files && context.files.length > 0) {\n parts.push(`\\n## Attached Files`);\n for (const file of context.files) {\n parts.push(`- **${file.fileName}** (${file.mimeType}): ${file.downloadUrl}`);\n }\n }\n\n if (context.repoRefs && context.repoRefs.length > 0) {\n parts.push(`\\n## Repository References`);\n for (const ref of context.repoRefs) {\n const icon = ref.refType === \"folder\" ? \"folder\" : \"file\";\n parts.push(`- [${icon}] \\`${ref.path}\\``);\n }\n }\n\n if (context.chatHistory.length > 0) {\n const relevant = context.chatHistory.slice(-20);\n parts.push(`\\n## Recent Chat Context`);\n for (const msg of relevant) {\n const sender = msg.userName ?? msg.role;\n parts.push(`[${sender}]: ${msg.content}`);\n }\n }\n\n parts.push(`\\n## Instructions`);\n\n if (scenario === \"fresh\") {\n if (this.config.mode === \"pm\") {\n parts.push(\n `You are the project manager for this task.`,\n `The task details are provided above. Wait for the team to ask questions or provide additional requirements before starting to plan.`,\n );\n } else {\n parts.push(\n `Begin executing the task plan above immediately.`,\n `Your FIRST action should be reading the relevant source files mentioned in the plan, then writing code. Do NOT run install, build, lint, test, or dev server commands first — the environment is already set up.`,\n `Work on the git branch \"${context.githubBranch}\".`,\n `Post a brief message to chat when you begin meaningful implementation, and again when the PR is ready.`,\n `When finished, commit your changes, push the branch, and use the create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`,\n );\n }\n } else if (scenario === \"idle_relaunch\") {\n if (this.config.mode === \"pm\") {\n parts.push(\n `You were relaunched but no new instructions have been given since your last run.`,\n `You are the project manager for this task.`,\n `Wait for the team to provide instructions before taking action.`,\n );\n } else {\n parts.push(\n `You were relaunched but no new instructions have been given since your last run.`,\n `Work on the git branch \"${context.githubBranch}\".`,\n `Review the current state of the codebase and verify everything is working correctly (e.g. tests pass, the web server starts on port 3000).`,\n `Post a brief status update to the chat summarizing the current state.`,\n `Then wait for further instructions — do NOT redo work that was already completed.`,\n );\n if (context.githubPRUrl) {\n parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);\n }\n }\n } else {\n const lastAgentIdx = this.findLastAgentMessageIndex(context.chatHistory);\n const newMessages = context.chatHistory\n .slice(lastAgentIdx + 1)\n .filter((m) => m.role === \"user\");\n if (this.config.mode === \"pm\") {\n parts.push(\n `You were relaunched with new feedback since your last run.`,\n `You are the project manager for this task.`,\n `\\nNew messages since your last run:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n `\\nReview these messages and wait for the team to provide instructions before taking action.`,\n );\n } else {\n parts.push(\n `You were relaunched with new feedback since your last run.`,\n `Work on the git branch \"${context.githubBranch}\".`,\n `\\nNew messages since your last run:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n `\\nAddress the requested changes. Commit and push your updates.`,\n );\n if (context.githubPRUrl) {\n parts.push(\n `An existing PR is open at ${context.githubPRUrl} — push to the same branch to update it. Do NOT create a new PR.`,\n );\n } else {\n parts.push(\n `When finished, use the create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`,\n );\n }\n }\n }\n\n return parts.join(\"\\n\");\n }\n\n private buildSystemPrompt(context: TaskContext): string {\n const parts =\n this.config.mode === \"pm\"\n ? [\n `You are an AI project manager helping to plan tasks for the \"${context.title}\" project.`,\n `You are running locally with full access to the repository.`,\n `\\nEnvironment (ready, no setup required):`,\n `- Repository is cloned at your current working directory.`,\n `- You can read files to understand the codebase before writing task plans.`,\n `- Check the dev branch (e.g. run: git fetch && git checkout dev || git checkout main) to understand the current state of the codebase that agents will branch off of.`,\n ]\n : [\n `You are an AI agent working on a task for the \"${context.title}\" project.`,\n `You are running inside a GitHub Codespace with full access to the repository.`,\n `\\nEnvironment (fully ready — do NOT verify or set up):`,\n `- Repository is cloned at your current working directory.`,\n `- Branch \\`${context.githubBranch}\\` is already checked out.`,\n `- All dependencies are installed, database is migrated, and the dev server is running.`,\n `- Git is configured. Commit and push directly to this branch.`,\n `\\nIMPORTANT — Skip all environment verification. Do NOT run any of the following:`,\n `- bun/npm install, pip install, or any dependency installation`,\n `- bun build, bun lint, bun test, bun typecheck, or any build/check commands as a \"first step\"`,\n `- bun db:generate, bun db:push, prisma migrate, or any database setup`,\n `- bun dev, npm start, or any dev server startup commands`,\n `- pwd, ls, echo, or exploratory shell commands to \"check\" the environment`,\n `Only run these if you encounter a specific error that requires it.`,\n `Start reading the task plan and writing code immediately.`,\n ];\n\n if (this.setupLog.length > 0) {\n parts.push(\n `\\nEnvironment setup log (already executed before you started — proof that setup succeeded):`,\n \"```\",\n ...this.setupLog,\n \"```\",\n );\n }\n\n if (context.agentInstructions) {\n parts.push(`\\nAgent Instructions:\\n${context.agentInstructions}`);\n }\n if (this.config.instructions) {\n parts.push(`\\nAdditional Instructions:\\n${this.config.instructions}`);\n }\n parts.push(\n `\\nYou have access to Conveyor MCP tools to interact with the task management system.`,\n `Use the post_to_chat tool to communicate progress or ask questions.`,\n `Use the read_task_chat tool to check for new messages from the team.`,\n );\n if (this.config.mode !== \"pm\") {\n parts.push(\n `Use the create_pull_request tool to open PRs — do NOT use gh CLI or shell commands for PR creation.`,\n );\n }\n return parts.join(\"\\n\");\n }\n\n // oxlint-disable-next-line typescript/explicit-function-return-type, max-lines-per-function\n private createConveyorMcpServer(context: TaskContext) {\n const connection = this.connection;\n const config = this.config;\n\n const textResult = (text: string): { content: { type: \"text\"; text: string }[] } => ({\n content: [{ type: \"text\" as const, text }],\n });\n\n const commonTools = [\n tool(\n \"read_task_chat\",\n \"Read recent messages from the task chat to see team feedback or instructions\",\n {\n limit: z.number().optional().describe(\"Number of recent messages to fetch (default 20)\"),\n },\n async ({ limit }) => {\n try {\n const messages = await connection.fetchChatMessages(limit);\n return textResult(JSON.stringify(messages, null, 2));\n } catch {\n return textResult(\n JSON.stringify({\n note: \"Could not fetch live chat. Chat history was provided in the initial context.\",\n }),\n );\n }\n },\n { annotations: { readOnly: true } },\n ),\n tool(\n \"post_to_chat\",\n \"Post a message to the task chat visible to all team members\",\n { message: z.string().describe(\"The message to post to the team\") },\n ({ message }) => {\n connection.postChatMessage(message);\n return Promise.resolve(textResult(\"Message posted to task chat.\"));\n },\n ),\n tool(\n \"update_task_status\",\n \"Update the task status on the Kanban board\",\n {\n status: z\n .enum([\"InProgress\", \"ReviewPR\", \"Complete\"])\n .describe(\"The new status for the task\"),\n },\n ({ status }) => {\n connection.updateStatus(status);\n return Promise.resolve(textResult(`Task status updated to ${status}.`));\n },\n ),\n tool(\n \"get_task_plan\",\n \"Re-read the latest task plan in case it was updated\",\n {},\n async () => {\n try {\n const ctx = await connection.fetchTaskContext();\n return textResult(ctx.plan ?? \"No plan available.\");\n } catch {\n return textResult(`Task ID: ${config.taskId} - could not fetch updated plan.`);\n }\n },\n { annotations: { readOnly: true } },\n ),\n ];\n\n const modeTools =\n config.mode === \"pm\"\n ? [\n tool(\n \"update_task\",\n \"Save the finalized task plan and/or description\",\n {\n plan: z.string().optional().describe(\"The task plan in markdown\"),\n description: z.string().optional().describe(\"Updated task description\"),\n },\n async ({ plan, description }) => {\n try {\n connection.updateTaskFields({ plan, description });\n return textResult(\"Task updated successfully.\");\n } catch {\n return textResult(\"Failed to update task.\");\n }\n },\n ),\n ]\n : [\n tool(\n \"create_pull_request\",\n \"Create a GitHub pull request for this task. Use this instead of gh CLI or git commands to create PRs.\",\n {\n title: z.string().describe(\"The PR title\"),\n body: z.string().describe(\"The PR description/body in markdown\"),\n },\n async ({ title, body }) => {\n try {\n const result = await connection.createPR({ title, body });\n connection.sendEvent({\n type: \"pr_created\",\n url: result.url,\n number: result.number,\n });\n return textResult(`Pull request #${result.number} created: ${result.url}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n return textResult(`Failed to create pull request: ${msg}`);\n }\n },\n ),\n ];\n\n return createSdkMcpServer({\n name: \"conveyor\",\n tools: [...commonTools, ...modeTools],\n });\n\n void context;\n }\n\n // oxlint-disable-next-line max-lines-per-function, complexity\n private async processEvents(\n events: AsyncGenerator<SDKMessage, void>,\n context: TaskContext,\n ): Promise<{ retriable: boolean }> {\n const startTime = Date.now();\n let totalCostUsd = 0;\n let sessionIdStored = false;\n let isTyping = false;\n let retriable = false;\n\n for await (const event of events) {\n if (this.stopped) break;\n\n switch (event.type) {\n case \"system\": {\n if (event.subtype === \"init\") {\n const sessionId = (event as unknown as Record<string, unknown>).session_id as\n | string\n | undefined;\n if (sessionId && !sessionIdStored) {\n sessionIdStored = true;\n this.connection.storeSessionId(sessionId);\n }\n await this.callbacks.onEvent({\n type: \"thinking\",\n message: `Agent initialized (model: ${event.model})`,\n });\n }\n break;\n }\n\n case \"assistant\": {\n if (!isTyping) {\n setTimeout(() => {\n this.connection.sendTypingStart();\n }, 200);\n isTyping = true;\n }\n\n const msg = event.message as unknown as Record<string, unknown>;\n const content = msg.content as Record<string, unknown>[];\n const turnTextParts: string[] = [];\n for (const block of content) {\n const blockType = block.type as string;\n if (blockType === \"text\") {\n const text = block.text as string;\n turnTextParts.push(text);\n this.connection.sendEvent({ type: \"message\", content: text });\n await this.callbacks.onEvent({ type: \"message\", content: text });\n } else if (blockType === \"tool_use\") {\n const name = block.name as string;\n const inputStr =\n typeof block.input === \"string\" ? block.input : JSON.stringify(block.input);\n const isContentTool = [\"edit\", \"write\"].includes(name.toLowerCase());\n const inputLimit = isContentTool ? 10_000 : 500;\n const summary: ActivityEventSummary = {\n tool: name,\n input: inputStr.slice(0, inputLimit),\n timestamp: new Date().toISOString(),\n };\n this.currentTurnToolCalls.push(summary);\n this.connection.sendEvent({\n type: \"tool_use\",\n tool: name,\n input: inputStr,\n });\n await this.callbacks.onEvent({\n type: \"tool_use\",\n tool: name,\n input: inputStr,\n });\n }\n }\n\n if (turnTextParts.length > 0) {\n this.connection.postChatMessage(turnTextParts.join(\"\\n\\n\"));\n }\n\n if (this.currentTurnToolCalls.length > 0) {\n this.connection.sendEvent({\n type: \"turn_end\",\n toolCalls: [...this.currentTurnToolCalls],\n });\n this.currentTurnToolCalls = [];\n }\n\n if (this.config.mode === \"pm\") {\n this.syncPlanFile();\n }\n break;\n }\n\n case \"result\": {\n if (isTyping) {\n this.connection.sendTypingStop();\n isTyping = false;\n }\n\n const resultEvent = event as SDKMessage & { type: \"result\"; subtype: string };\n if (resultEvent.subtype === \"success\") {\n totalCostUsd =\n \"total_cost_usd\" in resultEvent\n ? ((resultEvent as Record<string, unknown>).total_cost_usd as number)\n : 0;\n const durationMs = Date.now() - startTime;\n const summary =\n \"result\" in resultEvent\n ? String((resultEvent as Record<string, unknown>).result)\n : \"Task completed.\";\n\n if (API_ERROR_PATTERN.test(summary) && durationMs < 30_000) {\n retriable = true;\n }\n\n this.connection.sendEvent({\n type: \"completed\",\n summary,\n costUsd: totalCostUsd,\n durationMs,\n });\n\n if (totalCostUsd > 0 && context.agentId) {\n const estimatedTotalTokens = Math.round(totalCostUsd * 100000);\n const estimatedInputTokens = Math.round(estimatedTotalTokens * 0.7);\n const estimatedOutputTokens = Math.round(estimatedTotalTokens * 0.3);\n\n this.connection.trackSpending({\n agentId: context.agentId,\n inputTokens: estimatedInputTokens,\n outputTokens: estimatedOutputTokens,\n totalTokens: estimatedTotalTokens,\n totalCostUsd,\n onSubscription: this.config.mode === \"pm\" || !!process.env.CLAUDE_CODE_OAUTH_TOKEN,\n });\n }\n\n await this.callbacks.onEvent({\n type: \"completed\",\n summary,\n costUsd: totalCostUsd,\n durationMs,\n });\n } else {\n const errors =\n \"errors\" in resultEvent\n ? ((resultEvent as Record<string, unknown>).errors as string[])\n : [];\n const errorMsg =\n errors.length > 0 ? errors.join(\", \") : `Agent stopped: ${resultEvent.subtype}`;\n\n if (API_ERROR_PATTERN.test(errorMsg)) {\n retriable = true;\n }\n\n this.connection.sendEvent({ type: \"error\", message: errorMsg });\n await this.callbacks.onEvent({ type: \"error\", message: errorMsg });\n }\n break;\n }\n }\n }\n\n if (isTyping) {\n this.connection.sendTypingStop();\n }\n\n return { retriable };\n }\n\n /**\n * Snapshot current plan files so syncPlanFile can distinguish files created\n * by THIS session from ones created by a concurrent agent.\n */\n private snapshotPlanFiles(): void {\n const plansDir = join(homedir(), \".claude\", \"plans\");\n this.planFileSnapshot.clear();\n try {\n for (const file of readdirSync(plansDir).filter((f) => f.endsWith(\".md\"))) {\n try {\n const stat = statSync(join(plansDir, file));\n this.planFileSnapshot.set(file, stat.mtimeMs);\n } catch {\n continue;\n }\n }\n } catch {\n /* plans dir doesn't exist yet */\n }\n }\n\n /**\n * After a PM-mode query, scan ~/.claude/plans/ for plan files that were\n * created or modified by THIS session (not present in the pre-query snapshot)\n * and push the newest one to the task.\n */\n private syncPlanFile(): void {\n const plansDir = join(homedir(), \".claude\", \"plans\");\n\n let files: string[];\n try {\n files = readdirSync(plansDir).filter((f) => f.endsWith(\".md\"));\n } catch {\n return;\n }\n\n let newest: { path: string; mtime: number } | null = null;\n for (const file of files) {\n const fullPath = join(plansDir, file);\n try {\n const stat = statSync(fullPath);\n const prevMtime = this.planFileSnapshot.get(file);\n const isNew = prevMtime === undefined || stat.mtimeMs > prevMtime;\n if (isNew && (!newest || stat.mtimeMs > newest.mtime)) {\n newest = { path: fullPath, mtime: stat.mtimeMs };\n }\n } catch {\n continue;\n }\n }\n\n if (newest) {\n const content = readFileSync(newest.path, \"utf-8\").trim();\n if (content) {\n this.connection.updateTaskFields({ plan: content });\n }\n }\n }\n\n /**\n * Runs one SDK query cycle. For PM mode this is a single-turn query per\n * user message. For task mode this uses the long-running input stream\n * (initial execution) or a single follow-up prompt.\n */\n // oxlint-disable-next-line max-lines-per-function\n private async runSdkQuery(context: TaskContext, followUpContent?: string): Promise<void> {\n if (this.stopped) return;\n\n const settings = context.agentSettings ?? this.config.agentSettings ?? {};\n const systemPromptText = this.buildSystemPrompt(context);\n const conveyorMcp = this.createConveyorMcpServer(context);\n\n const systemPrompt: { type: \"preset\"; preset: \"claude_code\"; append?: string } = {\n type: \"preset\",\n preset: \"claude_code\",\n append: systemPromptText || undefined,\n };\n const settingSources = (settings.settingSources ?? [\"user\", \"project\"]) as (\n | \"user\"\n | \"project\"\n | \"local\"\n )[];\n\n const model = context.model || this.config.model;\n const pmDisallowedTools = this.config.mode === \"pm\" ? [\"TodoWrite\", \"TodoRead\"] : [];\n const disallowedTools = [...(settings.disallowedTools ?? []), ...pmDisallowedTools];\n\n const isPm = this.config.mode === \"pm\";\n if (isPm) {\n this.snapshotPlanFiles();\n }\n\n const QUESTION_TIMEOUT_MS = 5 * 60 * 1000;\n\n const canUseTool = async (\n toolName: string,\n input: Record<string, unknown>,\n ): Promise<\n | { behavior: \"allow\"; updatedInput?: Record<string, unknown> }\n | { behavior: \"deny\"; message: string }\n > => {\n if (toolName === \"AskUserQuestion\") {\n const questions = input.questions as {\n question: string;\n header: string;\n options: { label: string; description: string; preview?: string }[];\n multiSelect?: boolean;\n }[];\n\n const requestId = randomUUID();\n\n this.connection.emitStatus(\"waiting_for_input\");\n this.connection.sendEvent({\n type: \"tool_use\",\n tool: \"AskUserQuestion\",\n input: JSON.stringify(input),\n });\n\n const answerPromise = this.connection.askUserQuestion(requestId, questions);\n const timeoutPromise = new Promise<null>((resolve) =>\n setTimeout(() => resolve(null), QUESTION_TIMEOUT_MS),\n );\n\n const answers = await Promise.race([answerPromise, timeoutPromise]);\n\n this.connection.emitStatus(\"running\");\n\n if (!answers) {\n return {\n behavior: \"deny\",\n message:\n \"User did not respond to clarifying questions in time. Proceed with your best judgment.\",\n };\n }\n\n return {\n behavior: \"allow\",\n updatedInput: { questions: input.questions, answers },\n };\n }\n\n if (isPm && PM_DENIED_TOOLS.has(toolName)) {\n return {\n behavior: \"deny\",\n message: \"PM mode is plan-only. Use the update_task tool to save your plan.\",\n };\n }\n\n return { behavior: \"allow\", updatedInput: input };\n };\n\n const commonOptions = {\n model,\n systemPrompt,\n settingSources,\n cwd: this.config.workspaceDir,\n permissionMode: (isPm ? \"plan\" : \"bypassPermissions\") as \"plan\" | \"bypassPermissions\",\n allowDangerouslySkipPermissions: !isPm,\n canUseTool,\n tools: { type: \"preset\" as const, preset: \"claude_code\" as const },\n mcpServers: { conveyor: conveyorMcp },\n maxTurns: settings.maxTurns,\n effort: settings.effort,\n thinking: settings.thinking,\n betas: settings.betas,\n maxBudgetUsd: settings.maxBudgetUsd ?? 50,\n disallowedTools: disallowedTools.length > 0 ? disallowedTools : undefined,\n enableFileCheckpointing: settings.enableFileCheckpointing,\n };\n\n const resume = context.claudeSessionId ?? undefined;\n\n if (followUpContent) {\n // Follow-up message: single prompt, resume session\n const prompt = isPm\n ? `${this.buildInitialPrompt(context)}\\n\\n---\\n\\nThe team says:\\n${followUpContent}`\n : followUpContent;\n\n const agentQuery = query({\n prompt,\n options: { ...commonOptions, resume },\n });\n await this.runWithRetry(agentQuery, context, commonOptions);\n } else if (isPm) {\n // PM initial: no-op, we go straight to idle and wait for messages\n return;\n } else {\n // Task initial: long-running query with input stream\n const initialPrompt = this.buildInitialPrompt(context);\n const agentQuery = query({\n prompt: this.createInputStream(initialPrompt),\n options: { ...commonOptions, resume },\n });\n await this.runWithRetry(agentQuery, context, commonOptions);\n }\n\n if (isPm) {\n this.syncPlanFile();\n }\n }\n\n /**\n * Run a query with retry logic for transient API errors.\n */\n private async runWithRetry(\n initialQuery: AsyncGenerator<SDKMessage, void>,\n context: TaskContext,\n // oxlint-disable-next-line typescript/no-explicit-any\n options: Record<string, any>,\n ): Promise<void> {\n for (let attempt = 0; attempt <= RETRY_DELAYS_MS.length; attempt++) {\n if (this.stopped) return;\n\n const agentQuery =\n attempt === 0\n ? initialQuery\n : query({\n prompt: this.createInputStream(this.buildInitialPrompt(context)),\n options: { ...options, resume: undefined },\n });\n\n try {\n const { retriable } = await this.processEvents(agentQuery, context);\n if (!retriable || this.stopped) return;\n } catch (error) {\n const isStaleSession =\n error instanceof Error && error.message.includes(\"No conversation found with session ID\");\n\n if (isStaleSession && context.claudeSessionId) {\n this.connection.storeSessionId(\"\");\n const freshCtx = { ...context, claudeSessionId: null };\n const freshQuery = query({\n prompt: this.createInputStream(this.buildInitialPrompt(freshCtx)),\n options: { ...options, resume: undefined },\n });\n return this.runWithRetry(freshQuery, freshCtx, options);\n }\n\n const isApiError = error instanceof Error && API_ERROR_PATTERN.test(error.message);\n if (!isApiError) throw error;\n }\n\n if (attempt >= RETRY_DELAYS_MS.length) {\n this.connection.postChatMessage(\n `Agent shutting down after ${RETRY_DELAYS_MS.length} failed retry attempts due to API errors. ` +\n `The task will resume automatically when the codespace restarts.`,\n );\n return;\n }\n\n const delayMs = RETRY_DELAYS_MS[attempt];\n const delayMin = Math.round(delayMs / 60_000);\n this.connection.postChatMessage(\n `API error encountered. Retrying in ${delayMin} minute${delayMin > 1 ? \"s\" : \"\"}... (attempt ${attempt + 1}/${RETRY_DELAYS_MS.length})`,\n );\n this.connection.sendEvent({\n type: \"error\",\n message: `API error, retrying in ${delayMin}m (${attempt + 1}/${RETRY_DELAYS_MS.length})`,\n });\n this.connection.emitStatus(\"waiting_for_input\");\n await this.callbacks.onStatusChange(\"waiting_for_input\");\n\n await new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, delayMs);\n const checkStopped = setInterval(() => {\n if (this.stopped) {\n clearTimeout(timer);\n clearInterval(checkStopped);\n resolve();\n }\n }, 1000);\n setTimeout(() => clearInterval(checkStopped), delayMs + 100);\n });\n\n this.connection.emitStatus(\"running\");\n await this.callbacks.onStatusChange(\"running\");\n }\n }\n\n stop(): void {\n this.stopped = true;\n if (this.inputResolver) {\n this.inputResolver(null as unknown as SDKUserMessage);\n this.inputResolver = null;\n }\n }\n}\n"],"mappings":"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","names":["execSync","join","execSync","join","execSync","join"]}
|
package/dist/cli.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -54,6 +54,7 @@ interface TaskContext {
|
|
|
54
54
|
baseBranch: string;
|
|
55
55
|
githubPRUrl?: string | null;
|
|
56
56
|
claudeSessionId?: string | null;
|
|
57
|
+
useWorktree?: boolean;
|
|
57
58
|
agentSettings?: AgentSettings | null;
|
|
58
59
|
files?: TaskFileContext[];
|
|
59
60
|
repoRefs?: TaskRepoRefContext[];
|
|
@@ -146,7 +147,8 @@ declare class AgentRunner {
|
|
|
146
147
|
private setupLog;
|
|
147
148
|
private heartbeatTimer;
|
|
148
149
|
private taskContext;
|
|
149
|
-
private
|
|
150
|
+
private planFileSnapshot;
|
|
151
|
+
private worktreeActive;
|
|
150
152
|
private static readonly MAX_SETUP_LOG_LINES;
|
|
151
153
|
constructor(config: AgentRunnerConfig, callbacks: AgentRunnerCallbacks);
|
|
152
154
|
get state(): AgentRunnerStatus;
|
|
@@ -177,8 +179,14 @@ declare class AgentRunner {
|
|
|
177
179
|
private createConveyorMcpServer;
|
|
178
180
|
private processEvents;
|
|
179
181
|
/**
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
+
* Snapshot current plan files so syncPlanFile can distinguish files created
|
|
183
|
+
* by THIS session from ones created by a concurrent agent.
|
|
184
|
+
*/
|
|
185
|
+
private snapshotPlanFiles;
|
|
186
|
+
/**
|
|
187
|
+
* After a PM-mode query, scan ~/.claude/plans/ for plan files that were
|
|
188
|
+
* created or modified by THIS session (not present in the pre-query snapshot)
|
|
189
|
+
* and push the newest one to the task.
|
|
182
190
|
*/
|
|
183
191
|
private syncPlanFile;
|
|
184
192
|
/**
|
|
@@ -283,4 +291,14 @@ declare function runSetupCommand(cmd: string, cwd: string, onOutput: (stream: "s
|
|
|
283
291
|
*/
|
|
284
292
|
declare function runStartCommand(cmd: string, cwd: string, onOutput: (stream: "stdout" | "stderr", data: string) => void): ChildProcess;
|
|
285
293
|
|
|
286
|
-
|
|
294
|
+
/**
|
|
295
|
+
* Ensure a git worktree exists for the given task. Creates one if it doesn't
|
|
296
|
+
* exist, reuses the existing one otherwise. Returns the absolute worktree path.
|
|
297
|
+
*/
|
|
298
|
+
declare function ensureWorktree(projectDir: string, taskId: string, branch?: string): string;
|
|
299
|
+
/**
|
|
300
|
+
* Remove a task's git worktree. Best-effort — silently ignores failures.
|
|
301
|
+
*/
|
|
302
|
+
declare function removeWorktree(projectDir: string, taskId: string): void;
|
|
303
|
+
|
|
304
|
+
export { type AgentEvent, AgentRunner, type AgentRunnerCallbacks, type AgentRunnerConfig, type ChatMessage, type ConveyorConfig, ConveyorConnection, type TaskContext, ensureWorktree, loadConveyorConfig, removeWorktree, runSetupCommand, runStartCommand };
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentRunner,
|
|
3
3
|
ConveyorConnection,
|
|
4
|
+
ensureWorktree,
|
|
4
5
|
loadConveyorConfig,
|
|
6
|
+
removeWorktree,
|
|
5
7
|
runSetupCommand,
|
|
6
8
|
runStartCommand
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JWIGEYRD.js";
|
|
8
10
|
export {
|
|
9
11
|
AgentRunner,
|
|
10
12
|
ConveyorConnection,
|
|
13
|
+
ensureWorktree,
|
|
11
14
|
loadConveyorConfig,
|
|
15
|
+
removeWorktree,
|
|
12
16
|
runSetupCommand,
|
|
13
17
|
runStartCommand
|
|
14
18
|
};
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/connection.ts","../src/setup.ts","../src/runner.ts"],"sourcesContent":["import { io, type Socket } from \"socket.io-client\";\nimport type { AgentRunnerConfig, TaskContext, AgentEvent } from \"./types.js\";\n\ninterface AgentQuestionOption {\n label: string;\n description: string;\n preview?: string;\n}\n\ninterface AgentQuestion {\n question: string;\n header: string;\n options: AgentQuestionOption[];\n multiSelect?: boolean;\n}\n\nexport class ConveyorConnection {\n private socket: Socket | null = null;\n private config: AgentRunnerConfig;\n private eventBuffer: { taskId: string; event: AgentEvent }[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private static readonly EVENT_BATCH_MS = 500;\n\n private earlyMessages: { content: string; userId: string }[] = [];\n private earlyStop = false;\n private chatMessageCallback: ((msg: { content: string; userId: string }) => void) | null = null;\n private stopCallback: (() => void) | null = null;\n private pendingQuestionResolvers = new Map<string, (answers: Record<string, string>) => void>();\n\n constructor(config: AgentRunnerConfig) {\n this.config = config;\n }\n\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n let settled = false;\n let attempts = 0;\n const maxInitialAttempts = 30;\n\n this.socket = io(this.config.conveyorApiUrl, {\n auth: { taskToken: this.config.taskToken, runnerMode: this.config.mode ?? \"task\" },\n transports: [\"websocket\"],\n reconnection: true,\n reconnectionAttempts: Infinity,\n reconnectionDelay: 2000,\n reconnectionDelayMax: 30000,\n randomizationFactor: 0.3,\n extraHeaders: {\n \"ngrok-skip-browser-warning\": \"true\",\n },\n });\n\n // Register listeners immediately so we capture messages the server\n // flushes during registerHandlers (before connect() resolves).\n this.socket.on(\"agentRunner:incomingMessage\", (msg: { content: string; userId: string }) => {\n if (this.chatMessageCallback) {\n this.chatMessageCallback(msg);\n } else {\n this.earlyMessages.push(msg);\n }\n });\n\n this.socket.on(\"agentRunner:stop\", () => {\n if (this.stopCallback) {\n this.stopCallback();\n } else {\n this.earlyStop = true;\n }\n });\n\n this.socket.on(\n \"agentRunner:questionAnswer\",\n (data: { requestId: string; answers: Record<string, string> }) => {\n const resolver = this.pendingQuestionResolvers.get(data.requestId);\n if (resolver) {\n this.pendingQuestionResolvers.delete(data.requestId);\n resolver(data.answers);\n }\n },\n );\n\n this.socket.on(\"connect\", () => {\n if (!settled) {\n settled = true;\n resolve();\n }\n });\n\n this.socket.io.on(\"reconnect_attempt\", () => {\n attempts++;\n if (!settled && attempts >= maxInitialAttempts) {\n settled = true;\n reject(new Error(`Failed to connect after ${maxInitialAttempts} attempts`));\n }\n });\n });\n }\n\n fetchChatMessages(\n limit?: number,\n ): Promise<\n { role: string; content: string; userId: string | null; userName?: string; createdAt: string }[]\n > {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getChatMessages\",\n { taskId: this.config.taskId, limit },\n (response: {\n success: boolean;\n data?: {\n role: string;\n content: string;\n userId: string | null;\n userName?: string;\n createdAt: string;\n }[];\n error?: string;\n }): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch chat messages\"));\n }\n },\n );\n });\n }\n\n fetchTaskContext(): Promise<TaskContext> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getTaskContext\",\n { taskId: this.config.taskId },\n (response: { success: boolean; data?: TaskContext; error?: string }): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch task context\"));\n }\n },\n );\n });\n }\n\n sendEvent(event: AgentEvent): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.eventBuffer.push({ taskId: this.config.taskId, event });\n if (!this.flushTimer) {\n this.flushTimer = setTimeout(() => this.flushEvents(), ConveyorConnection.EVENT_BATCH_MS);\n }\n }\n\n flushEvents(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n if (!this.socket || this.eventBuffer.length === 0) return;\n for (const entry of this.eventBuffer) {\n this.socket.emit(\"agentRunner:event\", entry);\n }\n this.eventBuffer = [];\n }\n\n updateStatus(status: string): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:statusUpdate\", {\n taskId: this.config.taskId,\n status,\n });\n }\n\n postChatMessage(content: string): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:chatMessage\", {\n taskId: this.config.taskId,\n content,\n });\n }\n\n createPR(params: {\n title: string;\n body: string;\n baseBranch?: string;\n }): Promise<{ url: string; number: number }> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:createPR\",\n { taskId: this.config.taskId, ...params },\n (response: {\n success: boolean;\n data?: { url: string; number: number };\n error?: string;\n }): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to create pull request\"));\n }\n },\n );\n });\n }\n\n askUserQuestion(requestId: string, questions: AgentQuestion[]): Promise<Record<string, string>> {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:askUserQuestion\", {\n taskId: this.config.taskId,\n requestId,\n questions,\n });\n\n return new Promise((resolve) => {\n this.pendingQuestionResolvers.set(requestId, resolve);\n });\n }\n\n cancelPendingQuestions(): void {\n this.pendingQuestionResolvers.clear();\n }\n\n storeSessionId(sessionId: string): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:storeSessionId\", {\n taskId: this.config.taskId,\n sessionId,\n });\n }\n\n updateTaskFields(fields: { plan?: string; description?: string }): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"agentRunner:updateTaskFields\", {\n taskId: this.config.taskId,\n fields,\n });\n }\n\n onChatMessage(callback: (message: { content: string; userId: string }) => void): void {\n this.chatMessageCallback = callback;\n for (const msg of this.earlyMessages) {\n callback(msg);\n }\n this.earlyMessages = [];\n }\n\n onStopRequested(callback: () => void): void {\n this.stopCallback = callback;\n if (this.earlyStop) {\n callback();\n this.earlyStop = false;\n }\n }\n\n trackSpending(params: {\n agentId: string;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n totalCostUsd: number;\n onSubscription: boolean;\n }): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:trackSpending\", {\n taskId: this.config.taskId,\n ...params,\n });\n }\n\n emitStatus(status: string): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:statusUpdate\", {\n taskId: this.config.taskId,\n status,\n });\n }\n\n sendHeartbeat(): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:heartbeat\", {\n taskId: this.config.taskId,\n });\n }\n\n sendTypingStart(): void {\n this.sendEvent({ type: \"agent_typing_start\" });\n }\n\n sendTypingStop(): void {\n this.sendEvent({ type: \"agent_typing_stop\" });\n }\n\n disconnect(): void {\n this.flushEvents();\n this.socket?.disconnect();\n this.socket = null;\n }\n}\n","import { execSync } from \"node:child_process\";\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport interface ConveyorConfig {\n setupCommand?: string;\n startCommand?: string;\n previewPort?: number;\n}\n\nconst CONVEYOR_CONFIG_PATH = \".conveyor/config.json\";\nconst DEVCONTAINER_PATH = \".devcontainer/conveyor/devcontainer.json\";\n\nexport async function loadForwardPorts(workspaceDir: string): Promise<number[]> {\n try {\n const raw = await readFile(join(workspaceDir, DEVCONTAINER_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as { forwardPorts?: number[] };\n return parsed.forwardPorts ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function loadConveyorConfig(workspaceDir: string): Promise<ConveyorConfig | null> {\n // Primary: .conveyor/config.json\n try {\n const raw = await readFile(join(workspaceDir, CONVEYOR_CONFIG_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as ConveyorConfig;\n if (parsed.setupCommand || parsed.startCommand) return parsed;\n } catch {\n // Not found or invalid — try fallback\n }\n\n // Fallback: devcontainer.json \"conveyor\" section\n try {\n const raw = await readFile(join(workspaceDir, DEVCONTAINER_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as { conveyor?: ConveyorConfig };\n if (parsed.conveyor && (parsed.conveyor.startCommand || parsed.conveyor.setupCommand)) {\n return parsed.conveyor;\n }\n } catch {\n // Not found or invalid\n }\n\n return null;\n}\n\n/**\n * Runs a command synchronously (waits for exit). Streams stdout/stderr\n * line-by-line via the onOutput callback.\n */\nexport function runSetupCommand(\n cmd: string,\n cwd: string,\n onOutput: (stream: \"stdout\" | \"stderr\", data: string) => void,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"sh\", [\"-c\", cmd], {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env },\n });\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n onOutput(\"stdout\", chunk.toString());\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n onOutput(\"stderr\", chunk.toString());\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`Setup command exited with code ${code}`));\n }\n });\n\n child.on(\"error\", (err) => {\n reject(err);\n });\n });\n}\n\n/**\n * Runs a command in the background (does not wait for exit). Returns the\n * ChildProcess so it can be cleaned up on agent shutdown. Streams\n * stdout/stderr via the onOutput callback.\n */\nexport function runStartCommand(\n cmd: string,\n cwd: string,\n onOutput: (stream: \"stdout\" | \"stderr\", data: string) => void,\n): ChildProcess {\n const child = spawn(\"sh\", [\"-c\", cmd], {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: true,\n env: { ...process.env },\n });\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n onOutput(\"stdout\", chunk.toString());\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n onOutput(\"stderr\", chunk.toString());\n });\n\n child.unref();\n return child;\n}\n\n/**\n * Reset `.devcontainer/conveyor/devcontainer.json` to match the base branch\n * and remove the cloud-build \"configure\" commit from git history. This runs\n * AFTER the codespace has started (env vars are already in process memory)\n * so the agent sees a branch identical to base — no spurious diffs, no\n * rebase conflicts on devcontainer.json.\n */\nexport function cleanDevcontainerFromGit(\n workspaceDir: string,\n taskBranch: string,\n baseBranch: string,\n): { cleaned: boolean; message: string } {\n const git = (cmd: string): string =>\n execSync(cmd, { cwd: workspaceDir, encoding: \"utf-8\", timeout: 30_000 }).trim();\n\n try {\n git(`git fetch origin ${baseBranch}`);\n } catch {\n return { cleaned: false, message: `Failed to fetch origin/${baseBranch}` };\n }\n\n // Check if devcontainer.json differs from base\n try {\n git(`git diff --quiet origin/${baseBranch} -- ${DEVCONTAINER_PATH}`);\n return { cleaned: false, message: \"devcontainer.json already matches base\" };\n } catch {\n // diff --quiet exits non-zero when there IS a diff — expected path\n }\n\n try {\n const ahead = parseInt(git(`git rev-list --count origin/${baseBranch}..HEAD`), 10);\n\n if (ahead <= 1) {\n // Fresh start: only the devcontainer commit exists — hard reset to base\n git(`git reset --hard origin/${baseBranch}`);\n } else {\n // Relaunch: agent has prior commits — restore file and add fixup commit\n git(`git checkout origin/${baseBranch} -- ${DEVCONTAINER_PATH}`);\n git(`git add ${DEVCONTAINER_PATH}`);\n\n try {\n git(`git diff --cached --quiet -- ${DEVCONTAINER_PATH}`);\n return { cleaned: false, message: \"devcontainer.json already clean in working tree\" };\n } catch {\n git(`git commit -m \"chore: reset devcontainer config\"`);\n }\n }\n\n git(`git push --force-with-lease origin ${taskBranch}`);\n return { cleaned: true, message: \"devcontainer.json cleaned from git history\" };\n } catch (err) {\n const msg = err instanceof Error ? err.message : \"Unknown error\";\n return { cleaned: false, message: `Git cleanup failed: ${msg}` };\n }\n}\n","// oxlint-disable max-lines\nimport { randomUUID } from \"node:crypto\";\nimport { execSync } from \"node:child_process\";\nimport { readdirSync, statSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n query,\n tool,\n createSdkMcpServer,\n type SDKMessage,\n type SDKUserMessage,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod\";\nimport type {\n AgentRunnerConfig,\n AgentRunnerCallbacks,\n AgentRunnerStatus,\n AgentEvent,\n TaskContext,\n ActivityEventSummary,\n} from \"./types.js\";\nimport { ConveyorConnection } from \"./connection.js\";\nimport {\n cleanDevcontainerFromGit,\n loadConveyorConfig,\n loadForwardPorts,\n runSetupCommand,\n runStartCommand,\n type ConveyorConfig,\n} from \"./setup.js\";\n\nconst API_ERROR_PATTERN = /API Error: [45]\\d\\d/;\nconst RETRY_DELAYS_MS = [60_000, 120_000, 180_000, 300_000]; // 1, 2, 3, 5 minutes\nconst HEARTBEAT_INTERVAL_MS = 30_000;\n\nexport class AgentRunner {\n private config: AgentRunnerConfig;\n private connection: ConveyorConnection;\n private callbacks: AgentRunnerCallbacks;\n private _state: AgentRunnerStatus = \"connecting\";\n private stopped = false;\n private inputResolver: ((msg: SDKUserMessage) => void) | null = null;\n private pendingMessages: SDKUserMessage[] = [];\n private currentTurnToolCalls: ActivityEventSummary[] = [];\n private setupLog: string[] = [];\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private taskContext: TaskContext | null = null;\n private planSyncBaseMs = 0;\n private static readonly MAX_SETUP_LOG_LINES = 50;\n\n constructor(config: AgentRunnerConfig, callbacks: AgentRunnerCallbacks) {\n this.config = config;\n this.connection = new ConveyorConnection(config);\n this.callbacks = callbacks;\n }\n\n get state(): AgentRunnerStatus {\n return this._state;\n }\n\n private async setState(status: AgentRunnerStatus): Promise<void> {\n this._state = status;\n this.connection.emitStatus(status);\n await this.callbacks.onStatusChange(status);\n }\n\n private startHeartbeat(): void {\n this.heartbeatTimer = setInterval(() => {\n if (!this.stopped) {\n this.connection.sendHeartbeat();\n }\n }, HEARTBEAT_INTERVAL_MS);\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n // oxlint-disable-next-line max-lines-per-function\n async start(): Promise<void> {\n // --- Phase 1: Connect ---\n await this.setState(\"connecting\");\n await this.connection.connect();\n\n this.connection.onStopRequested(() => {\n this.stop();\n });\n\n this.connection.onChatMessage((message) => {\n this.injectHumanMessage(message.content);\n });\n\n await this.setState(\"connected\");\n this.connection.sendEvent({\n type: \"connected\",\n taskId: this.config.taskId,\n });\n this.startHeartbeat();\n\n // --- Phase 2: Setup (task mode + codespace only) ---\n if (this.config.mode !== \"pm\" && process.env.CODESPACES === \"true\") {\n const setupOk = await this.runSetupSafe();\n if (!setupOk) {\n this.stopHeartbeat();\n await this.setState(\"error\");\n this.connection.disconnect();\n return;\n }\n }\n\n this.initRtk();\n\n // --- Phase 3: Fetch context ---\n await this.setState(\"fetching_context\");\n try {\n this.taskContext = await this.connection.fetchTaskContext();\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Failed to fetch task context\";\n this.connection.sendEvent({ type: \"error\", message });\n await this.callbacks.onEvent({ type: \"error\", message });\n this.stopHeartbeat();\n await this.setState(\"error\");\n this.connection.disconnect();\n return;\n }\n\n if (process.env.CODESPACES === \"true\" && this.taskContext.baseBranch) {\n const result = cleanDevcontainerFromGit(\n this.config.workspaceDir,\n this.taskContext.githubBranch,\n this.taskContext.baseBranch,\n );\n if (result.cleaned) {\n this.setupLog.push(`[conveyor] ${result.message}`);\n }\n }\n\n // --- Phase 4: Initial action ---\n const isPm = this.config.mode === \"pm\";\n if (isPm) {\n await this.setState(\"idle\");\n } else {\n await this.setState(\"running\");\n await this.runSdkQuery(this.taskContext);\n if (!this.stopped) {\n await this.setState(\"idle\");\n }\n }\n\n // --- Phase 5: Core loop — stay alive for follow-up messages ---\n while (!this.stopped) {\n if (this._state === \"idle\") {\n const msg = await this.waitForUserContent();\n if (!msg) break;\n\n await this.setState(\"running\");\n await this.runSdkQuery(this.taskContext, msg);\n\n if (!this.stopped) {\n await this.setState(\"idle\");\n }\n } else if (this._state === \"error\") {\n await this.setState(\"idle\");\n } else {\n break;\n }\n }\n\n // --- Cleanup ---\n this.stopHeartbeat();\n await this.setState(\"finished\");\n this.connection.disconnect();\n }\n\n /**\n * Wraps project setup in try/catch. On failure, posts error to chat\n * directly (no SDK needed) and streams to CLI. Returns false if setup failed.\n */\n private async runSetupSafe(): Promise<boolean> {\n await this.setState(\"setup\");\n\n const ports = await loadForwardPorts(this.config.workspaceDir);\n if (ports.length > 0 && process.env.CODESPACE_NAME) {\n const visibility = ports.map((p) => `${p}:public`).join(\" \");\n runStartCommand(\n `gh codespace ports visibility ${visibility} -c \"${process.env.CODESPACE_NAME}\" 2>/dev/null`,\n this.config.workspaceDir,\n () => undefined,\n );\n }\n\n const config = await loadConveyorConfig(this.config.workspaceDir);\n if (!config) {\n this.connection.sendEvent({ type: \"setup_complete\" });\n await this.callbacks.onEvent({ type: \"setup_complete\" });\n return true;\n }\n\n try {\n await this.executeSetupConfig(config);\n const setupEvent: AgentEvent = {\n type: \"setup_complete\",\n previewPort: config.previewPort ?? undefined,\n };\n this.connection.sendEvent(setupEvent);\n await this.callbacks.onEvent(setupEvent);\n return true;\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Setup failed\";\n this.connection.sendEvent({ type: \"setup_error\", message });\n await this.callbacks.onEvent({ type: \"setup_error\", message });\n this.connection.postChatMessage(\n `Environment setup failed: ${message}\\nThe agent cannot start until this is resolved.`,\n );\n return false;\n }\n }\n\n private pushSetupLog(line: string): void {\n this.setupLog.push(line);\n if (this.setupLog.length > AgentRunner.MAX_SETUP_LOG_LINES) {\n this.setupLog.splice(0, this.setupLog.length - AgentRunner.MAX_SETUP_LOG_LINES);\n }\n }\n\n private async executeSetupConfig(config: ConveyorConfig): Promise<void> {\n if (config.setupCommand) {\n this.pushSetupLog(`$ ${config.setupCommand}`);\n await runSetupCommand(config.setupCommand, this.config.workspaceDir, (stream, data) => {\n this.connection.sendEvent({ type: \"setup_output\", stream, data });\n for (const line of data.split(\"\\n\").filter(Boolean)) {\n this.pushSetupLog(`[${stream}] ${line}`);\n }\n });\n this.pushSetupLog(\"(exit 0)\");\n }\n\n if (config.startCommand) {\n this.pushSetupLog(`$ ${config.startCommand} & (background)`);\n runStartCommand(config.startCommand, this.config.workspaceDir, (stream, data) => {\n this.connection.sendEvent({ type: \"start_command_output\", stream, data });\n });\n }\n }\n\n private initRtk(): void {\n try {\n execSync(\"rtk --version\", { stdio: \"ignore\" });\n execSync(\"rtk init --global --auto-patch\", { stdio: \"ignore\" });\n } catch {\n // RTK not installed — skip silently\n }\n }\n\n private injectHumanMessage(content: string): void {\n const msg: SDKUserMessage = {\n type: \"user\" as const,\n session_id: \"\",\n message: { role: \"user\" as const, content },\n parent_tool_use_id: null,\n };\n\n if (this.inputResolver) {\n const resolve = this.inputResolver;\n this.inputResolver = null;\n resolve(msg);\n } else {\n this.pendingMessages.push(msg);\n }\n }\n\n private waitForMessage(): Promise<SDKUserMessage | null> {\n return new Promise<SDKUserMessage | null>((resolve) => {\n const checkStopped = setInterval(() => {\n if (this.stopped) {\n clearInterval(checkStopped);\n this.inputResolver = null;\n resolve(null);\n }\n }, 1000);\n\n this.inputResolver = (msg: SDKUserMessage) => {\n clearInterval(checkStopped);\n resolve(msg);\n };\n });\n }\n\n /**\n * Wait for the next user message content string. Drains pendingMessages first.\n * Returns null if stopped.\n */\n private async waitForUserContent(): Promise<string | null> {\n if (this.pendingMessages.length > 0) {\n const next = this.pendingMessages.shift()!;\n return (next.message as { content: string }).content;\n }\n\n const msg = await this.waitForMessage();\n if (!msg) return null;\n return (msg.message as { content: string }).content;\n }\n\n private async *createInputStream(\n initialPrompt: string,\n ): AsyncGenerator<SDKUserMessage, void, unknown> {\n const makeUserMessage = (content: string): SDKUserMessage => ({\n type: \"user\" as const,\n session_id: \"\",\n message: { role: \"user\" as const, content },\n parent_tool_use_id: null,\n });\n\n yield makeUserMessage(initialPrompt);\n\n while (!this.stopped) {\n if (this.pendingMessages.length > 0) {\n const next = this.pendingMessages.shift();\n if (next) {\n yield next;\n }\n continue;\n }\n\n this.connection.emitStatus(\"waiting_for_input\");\n await this.callbacks.onStatusChange(\"waiting_for_input\");\n const msg = await this.waitForMessage();\n\n if (!msg) break;\n this.connection.emitStatus(\"running\");\n await this.callbacks.onStatusChange(\"running\");\n yield msg;\n }\n }\n\n private findLastAgentMessageIndex(history: TaskContext[\"chatHistory\"]): number {\n for (let i = history.length - 1; i >= 0; i--) {\n if (history[i].role === \"assistant\") return i;\n }\n return -1;\n }\n\n private detectRelaunchScenario(\n context: TaskContext,\n ): \"fresh\" | \"idle_relaunch\" | \"feedback_relaunch\" {\n const lastAgentIdx = this.findLastAgentMessageIndex(context.chatHistory);\n if (lastAgentIdx === -1) return \"fresh\";\n\n const hasPriorWork = !!context.githubPRUrl || !!context.claudeSessionId;\n if (!hasPriorWork) return \"fresh\";\n\n const messagesAfterAgent = context.chatHistory.slice(lastAgentIdx + 1);\n const hasNewUserMessages = messagesAfterAgent.some((m) => m.role === \"user\");\n return hasNewUserMessages ? \"feedback_relaunch\" : \"idle_relaunch\";\n }\n\n // eslint-disable-next-line max-lines-per-function\n private buildInitialPrompt(context: TaskContext): string {\n const parts: string[] = [];\n const scenario = this.detectRelaunchScenario(context);\n\n if (context.claudeSessionId && scenario !== \"fresh\") {\n if (this.config.mode === \"pm\") {\n const lastAgentIdx = this.findLastAgentMessageIndex(context.chatHistory);\n const newMessages = context.chatHistory\n .slice(lastAgentIdx + 1)\n .filter((m) => m.role === \"user\");\n if (newMessages.length > 0) {\n parts.push(\n `You have been relaunched. Here are new messages since your last session:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n );\n } else {\n parts.push(`You have been relaunched. No new messages since your last session.`);\n }\n parts.push(\n `\\nYou are the project manager for this task.`,\n `Review the context above and wait for the team to provide instructions before taking action.`,\n );\n } else if (scenario === \"feedback_relaunch\") {\n const lastAgentIdx = this.findLastAgentMessageIndex(context.chatHistory);\n const newMessages = context.chatHistory\n .slice(lastAgentIdx + 1)\n .filter((m) => m.role === \"user\");\n parts.push(\n `You have been relaunched with new feedback.`,\n `Work on the git branch \"${context.githubBranch}\".`,\n `\\nNew messages since your last run:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n `\\nAddress the requested changes. Commit and push your updates.`,\n );\n if (context.githubPRUrl) {\n parts.push(\n `An existing PR is open at ${context.githubPRUrl} — push to the same branch. Do NOT create a new PR.`,\n );\n } else {\n parts.push(\n `When finished, use the create_pull_request tool to open a PR. Do NOT use gh CLI.`,\n );\n }\n } else {\n parts.push(\n `You were relaunched but no new instructions have been given since your last run.`,\n `Work on the git branch \"${context.githubBranch}\".`,\n `Review the current state of the codebase and verify everything is working correctly.`,\n `Post a brief status update to the chat, then wait for further instructions.`,\n );\n if (context.githubPRUrl) {\n parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);\n }\n }\n return parts.join(\"\\n\");\n }\n\n parts.push(`# Task: ${context.title}`);\n if (context.description) {\n parts.push(`\\n## Description\\n${context.description}`);\n }\n if (context.plan) {\n parts.push(`\\n## Plan\\n${context.plan}`);\n }\n\n if (context.files && context.files.length > 0) {\n parts.push(`\\n## Attached Files`);\n for (const file of context.files) {\n parts.push(`- **${file.fileName}** (${file.mimeType}): ${file.downloadUrl}`);\n }\n }\n\n if (context.repoRefs && context.repoRefs.length > 0) {\n parts.push(`\\n## Repository References`);\n for (const ref of context.repoRefs) {\n const icon = ref.refType === \"folder\" ? \"folder\" : \"file\";\n parts.push(`- [${icon}] \\`${ref.path}\\``);\n }\n }\n\n if (context.chatHistory.length > 0) {\n const relevant = context.chatHistory.slice(-20);\n parts.push(`\\n## Recent Chat Context`);\n for (const msg of relevant) {\n const sender = msg.userName ?? msg.role;\n parts.push(`[${sender}]: ${msg.content}`);\n }\n }\n\n parts.push(`\\n## Instructions`);\n\n if (scenario === \"fresh\") {\n if (this.config.mode === \"pm\") {\n parts.push(\n `You are the project manager for this task.`,\n `The task details are provided above. Wait for the team to ask questions or provide additional requirements before starting to plan.`,\n );\n } else {\n parts.push(\n `Begin executing the task plan above immediately.`,\n `Your FIRST action should be reading the relevant source files mentioned in the plan, then writing code. Do NOT run install, build, lint, test, or dev server commands first — the environment is already set up.`,\n `Work on the git branch \"${context.githubBranch}\".`,\n `Post a brief message to chat when you begin meaningful implementation, and again when the PR is ready.`,\n `When finished, commit your changes, push the branch, and use the create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`,\n );\n }\n } else if (scenario === \"idle_relaunch\") {\n if (this.config.mode === \"pm\") {\n parts.push(\n `You were relaunched but no new instructions have been given since your last run.`,\n `You are the project manager for this task.`,\n `Wait for the team to provide instructions before taking action.`,\n );\n } else {\n parts.push(\n `You were relaunched but no new instructions have been given since your last run.`,\n `Work on the git branch \"${context.githubBranch}\".`,\n `Review the current state of the codebase and verify everything is working correctly (e.g. tests pass, the web server starts on port 3000).`,\n `Post a brief status update to the chat summarizing the current state.`,\n `Then wait for further instructions — do NOT redo work that was already completed.`,\n );\n if (context.githubPRUrl) {\n parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);\n }\n }\n } else {\n const lastAgentIdx = this.findLastAgentMessageIndex(context.chatHistory);\n const newMessages = context.chatHistory\n .slice(lastAgentIdx + 1)\n .filter((m) => m.role === \"user\");\n if (this.config.mode === \"pm\") {\n parts.push(\n `You were relaunched with new feedback since your last run.`,\n `You are the project manager for this task.`,\n `\\nNew messages since your last run:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n `\\nReview these messages and wait for the team to provide instructions before taking action.`,\n );\n } else {\n parts.push(\n `You were relaunched with new feedback since your last run.`,\n `Work on the git branch \"${context.githubBranch}\".`,\n `\\nNew messages since your last run:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n `\\nAddress the requested changes. Commit and push your updates.`,\n );\n if (context.githubPRUrl) {\n parts.push(\n `An existing PR is open at ${context.githubPRUrl} — push to the same branch to update it. Do NOT create a new PR.`,\n );\n } else {\n parts.push(\n `When finished, use the create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`,\n );\n }\n }\n }\n\n return parts.join(\"\\n\");\n }\n\n private buildSystemPrompt(context: TaskContext): string {\n const parts =\n this.config.mode === \"pm\"\n ? [\n `You are an AI project manager helping to plan tasks for the \"${context.title}\" project.`,\n `You are running locally with full access to the repository.`,\n `\\nEnvironment (ready, no setup required):`,\n `- Repository is cloned at your current working directory.`,\n `- You can read files to understand the codebase before writing task plans.`,\n `- Check the dev branch (e.g. run: git fetch && git checkout dev || git checkout main) to understand the current state of the codebase that agents will branch off of.`,\n ]\n : [\n `You are an AI agent working on a task for the \"${context.title}\" project.`,\n `You are running inside a GitHub Codespace with full access to the repository.`,\n `\\nEnvironment (fully ready — do NOT verify or set up):`,\n `- Repository is cloned at your current working directory.`,\n `- Branch \\`${context.githubBranch}\\` is already checked out.`,\n `- All dependencies are installed, database is migrated, and the dev server is running.`,\n `- Git is configured. Commit and push directly to this branch.`,\n `\\nIMPORTANT — Skip all environment verification. Do NOT run any of the following:`,\n `- bun/npm install, pip install, or any dependency installation`,\n `- bun build, bun lint, bun test, bun typecheck, or any build/check commands as a \"first step\"`,\n `- bun db:generate, bun db:push, prisma migrate, or any database setup`,\n `- bun dev, npm start, or any dev server startup commands`,\n `- pwd, ls, echo, or exploratory shell commands to \"check\" the environment`,\n `Only run these if you encounter a specific error that requires it.`,\n `Start reading the task plan and writing code immediately.`,\n ];\n\n if (this.setupLog.length > 0) {\n parts.push(\n `\\nEnvironment setup log (already executed before you started — proof that setup succeeded):`,\n \"```\",\n ...this.setupLog,\n \"```\",\n );\n }\n\n if (context.agentInstructions) {\n parts.push(`\\nAgent Instructions:\\n${context.agentInstructions}`);\n }\n if (this.config.instructions) {\n parts.push(`\\nAdditional Instructions:\\n${this.config.instructions}`);\n }\n parts.push(\n `\\nYou have access to Conveyor MCP tools to interact with the task management system.`,\n `Use the post_to_chat tool to communicate progress or ask questions.`,\n `Use the read_task_chat tool to check for new messages from the team.`,\n );\n if (this.config.mode !== \"pm\") {\n parts.push(\n `Use the create_pull_request tool to open PRs — do NOT use gh CLI or shell commands for PR creation.`,\n );\n }\n return parts.join(\"\\n\");\n }\n\n // oxlint-disable-next-line typescript/explicit-function-return-type, max-lines-per-function\n private createConveyorMcpServer(context: TaskContext) {\n const connection = this.connection;\n const config = this.config;\n\n const textResult = (text: string): { content: { type: \"text\"; text: string }[] } => ({\n content: [{ type: \"text\" as const, text }],\n });\n\n const commonTools = [\n tool(\n \"read_task_chat\",\n \"Read recent messages from the task chat to see team feedback or instructions\",\n {\n limit: z.number().optional().describe(\"Number of recent messages to fetch (default 20)\"),\n },\n async ({ limit }) => {\n try {\n const messages = await connection.fetchChatMessages(limit);\n return textResult(JSON.stringify(messages, null, 2));\n } catch {\n return textResult(\n JSON.stringify({\n note: \"Could not fetch live chat. Chat history was provided in the initial context.\",\n }),\n );\n }\n },\n { annotations: { readOnly: true } },\n ),\n tool(\n \"post_to_chat\",\n \"Post a message to the task chat visible to all team members\",\n { message: z.string().describe(\"The message to post to the team\") },\n ({ message }) => {\n connection.postChatMessage(message);\n return Promise.resolve(textResult(\"Message posted to task chat.\"));\n },\n ),\n tool(\n \"update_task_status\",\n \"Update the task status on the Kanban board\",\n {\n status: z\n .enum([\"InProgress\", \"ReviewPR\", \"Complete\"])\n .describe(\"The new status for the task\"),\n },\n ({ status }) => {\n connection.updateStatus(status);\n return Promise.resolve(textResult(`Task status updated to ${status}.`));\n },\n ),\n tool(\n \"get_task_plan\",\n \"Re-read the latest task plan in case it was updated\",\n {},\n async () => {\n try {\n const ctx = await connection.fetchTaskContext();\n return textResult(ctx.plan ?? \"No plan available.\");\n } catch {\n return textResult(`Task ID: ${config.taskId} - could not fetch updated plan.`);\n }\n },\n { annotations: { readOnly: true } },\n ),\n ];\n\n const modeTools =\n config.mode === \"pm\"\n ? [\n tool(\n \"update_task\",\n \"Save the finalized task plan and/or description\",\n {\n plan: z.string().optional().describe(\"The task plan in markdown\"),\n description: z.string().optional().describe(\"Updated task description\"),\n },\n async ({ plan, description }) => {\n try {\n connection.updateTaskFields({ plan, description });\n return textResult(\"Task updated successfully.\");\n } catch {\n return textResult(\"Failed to update task.\");\n }\n },\n ),\n ]\n : [\n tool(\n \"create_pull_request\",\n \"Create a GitHub pull request for this task. Use this instead of gh CLI or git commands to create PRs.\",\n {\n title: z.string().describe(\"The PR title\"),\n body: z.string().describe(\"The PR description/body in markdown\"),\n },\n async ({ title, body }) => {\n try {\n const result = await connection.createPR({ title, body });\n connection.sendEvent({\n type: \"pr_created\",\n url: result.url,\n number: result.number,\n });\n return textResult(`Pull request #${result.number} created: ${result.url}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n return textResult(`Failed to create pull request: ${msg}`);\n }\n },\n ),\n ];\n\n return createSdkMcpServer({\n name: \"conveyor\",\n tools: [...commonTools, ...modeTools],\n });\n\n void context;\n }\n\n // oxlint-disable-next-line max-lines-per-function, complexity\n private async processEvents(\n events: AsyncGenerator<SDKMessage, void>,\n context: TaskContext,\n ): Promise<{ retriable: boolean }> {\n const startTime = Date.now();\n let totalCostUsd = 0;\n let sessionIdStored = false;\n let isTyping = false;\n let retriable = false;\n\n for await (const event of events) {\n if (this.stopped) break;\n\n switch (event.type) {\n case \"system\": {\n if (event.subtype === \"init\") {\n const sessionId = (event as unknown as Record<string, unknown>).session_id as\n | string\n | undefined;\n if (sessionId && !sessionIdStored) {\n sessionIdStored = true;\n this.connection.storeSessionId(sessionId);\n }\n await this.callbacks.onEvent({\n type: \"thinking\",\n message: `Agent initialized (model: ${event.model})`,\n });\n }\n break;\n }\n\n case \"assistant\": {\n if (!isTyping) {\n setTimeout(() => {\n this.connection.sendTypingStart();\n }, 200);\n isTyping = true;\n }\n\n const msg = event.message as unknown as Record<string, unknown>;\n const content = msg.content as Record<string, unknown>[];\n const turnTextParts: string[] = [];\n for (const block of content) {\n const blockType = block.type as string;\n if (blockType === \"text\") {\n const text = block.text as string;\n turnTextParts.push(text);\n this.connection.sendEvent({ type: \"message\", content: text });\n await this.callbacks.onEvent({ type: \"message\", content: text });\n } else if (blockType === \"tool_use\") {\n const name = block.name as string;\n const inputStr =\n typeof block.input === \"string\" ? block.input : JSON.stringify(block.input);\n const isContentTool = [\"edit\", \"write\"].includes(name.toLowerCase());\n const inputLimit = isContentTool ? 10_000 : 500;\n const summary: ActivityEventSummary = {\n tool: name,\n input: inputStr.slice(0, inputLimit),\n timestamp: new Date().toISOString(),\n };\n this.currentTurnToolCalls.push(summary);\n this.connection.sendEvent({\n type: \"tool_use\",\n tool: name,\n input: inputStr,\n });\n await this.callbacks.onEvent({\n type: \"tool_use\",\n tool: name,\n input: inputStr,\n });\n }\n }\n\n if (turnTextParts.length > 0) {\n this.connection.postChatMessage(turnTextParts.join(\"\\n\\n\"));\n }\n\n if (this.currentTurnToolCalls.length > 0) {\n this.connection.sendEvent({\n type: \"turn_end\",\n toolCalls: [...this.currentTurnToolCalls],\n });\n this.currentTurnToolCalls = [];\n }\n\n if (this.config.mode === \"pm\" && this.planSyncBaseMs > 0) {\n this.syncPlanFile(this.planSyncBaseMs);\n }\n break;\n }\n\n case \"result\": {\n if (isTyping) {\n this.connection.sendTypingStop();\n isTyping = false;\n }\n\n const resultEvent = event as SDKMessage & { type: \"result\"; subtype: string };\n if (resultEvent.subtype === \"success\") {\n totalCostUsd =\n \"total_cost_usd\" in resultEvent\n ? ((resultEvent as Record<string, unknown>).total_cost_usd as number)\n : 0;\n const durationMs = Date.now() - startTime;\n const summary =\n \"result\" in resultEvent\n ? String((resultEvent as Record<string, unknown>).result)\n : \"Task completed.\";\n\n if (API_ERROR_PATTERN.test(summary) && durationMs < 30_000) {\n retriable = true;\n }\n\n this.connection.sendEvent({\n type: \"completed\",\n summary,\n costUsd: totalCostUsd,\n durationMs,\n });\n\n if (totalCostUsd > 0 && context.agentId) {\n const estimatedTotalTokens = Math.round(totalCostUsd * 100000);\n const estimatedInputTokens = Math.round(estimatedTotalTokens * 0.7);\n const estimatedOutputTokens = Math.round(estimatedTotalTokens * 0.3);\n\n this.connection.trackSpending({\n agentId: context.agentId,\n inputTokens: estimatedInputTokens,\n outputTokens: estimatedOutputTokens,\n totalTokens: estimatedTotalTokens,\n totalCostUsd,\n onSubscription: this.config.mode === \"pm\" || !!process.env.CLAUDE_CODE_OAUTH_TOKEN,\n });\n }\n\n await this.callbacks.onEvent({\n type: \"completed\",\n summary,\n costUsd: totalCostUsd,\n durationMs,\n });\n } else {\n const errors =\n \"errors\" in resultEvent\n ? ((resultEvent as Record<string, unknown>).errors as string[])\n : [];\n const errorMsg =\n errors.length > 0 ? errors.join(\", \") : `Agent stopped: ${resultEvent.subtype}`;\n\n if (API_ERROR_PATTERN.test(errorMsg)) {\n retriable = true;\n }\n\n this.connection.sendEvent({ type: \"error\", message: errorMsg });\n await this.callbacks.onEvent({ type: \"error\", message: errorMsg });\n }\n break;\n }\n }\n }\n\n if (isTyping) {\n this.connection.sendTypingStop();\n }\n\n return { retriable };\n }\n\n /**\n * After a PM-mode query, scan ~/.claude/plans/ for plan files created or\n * modified during the query window and push the newest one to the task.\n */\n private syncPlanFile(sinceMs: number): void {\n const plansDir = join(homedir(), \".claude\", \"plans\");\n\n let files: string[];\n try {\n files = readdirSync(plansDir).filter((f) => f.endsWith(\".md\"));\n } catch {\n return;\n }\n\n let newest: { path: string; mtime: number } | null = null;\n for (const file of files) {\n const fullPath = join(plansDir, file);\n try {\n const stat = statSync(fullPath);\n if (stat.mtimeMs >= sinceMs && (!newest || stat.mtimeMs > newest.mtime)) {\n newest = { path: fullPath, mtime: stat.mtimeMs };\n }\n } catch {\n continue;\n }\n }\n\n if (newest) {\n const content = readFileSync(newest.path, \"utf-8\").trim();\n if (content) {\n this.connection.updateTaskFields({ plan: content });\n }\n }\n }\n\n /**\n * Runs one SDK query cycle. For PM mode this is a single-turn query per\n * user message. For task mode this uses the long-running input stream\n * (initial execution) or a single follow-up prompt.\n */\n // oxlint-disable-next-line max-lines-per-function\n private async runSdkQuery(context: TaskContext, followUpContent?: string): Promise<void> {\n if (this.stopped) return;\n\n const settings = context.agentSettings ?? this.config.agentSettings ?? {};\n const systemPromptText = this.buildSystemPrompt(context);\n const conveyorMcp = this.createConveyorMcpServer(context);\n\n const systemPrompt: { type: \"preset\"; preset: \"claude_code\"; append?: string } = {\n type: \"preset\",\n preset: \"claude_code\",\n append: systemPromptText || undefined,\n };\n const settingSources = (settings.settingSources ?? [\"user\", \"project\"]) as (\n | \"user\"\n | \"project\"\n | \"local\"\n )[];\n\n const model = context.model || this.config.model;\n const pmDisallowedTools = this.config.mode === \"pm\" ? [\"TodoWrite\", \"TodoRead\"] : [];\n const disallowedTools = [...(settings.disallowedTools ?? []), ...pmDisallowedTools];\n\n const isPm = this.config.mode === \"pm\";\n const queryStartMs = Date.now();\n this.planSyncBaseMs = queryStartMs;\n\n const QUESTION_TIMEOUT_MS = 5 * 60 * 1000;\n\n const canUseTool = async (\n toolName: string,\n input: Record<string, unknown>,\n ): Promise<\n | { behavior: \"allow\"; updatedInput?: Record<string, unknown> }\n | { behavior: \"deny\"; message: string }\n > => {\n if (toolName === \"AskUserQuestion\") {\n const questions = input.questions as {\n question: string;\n header: string;\n options: { label: string; description: string; preview?: string }[];\n multiSelect?: boolean;\n }[];\n\n const requestId = randomUUID();\n\n this.connection.emitStatus(\"waiting_for_input\");\n this.connection.sendEvent({\n type: \"tool_use\",\n tool: \"AskUserQuestion\",\n input: JSON.stringify(input),\n });\n\n const answerPromise = this.connection.askUserQuestion(requestId, questions);\n const timeoutPromise = new Promise<null>((resolve) =>\n setTimeout(() => resolve(null), QUESTION_TIMEOUT_MS),\n );\n\n const answers = await Promise.race([answerPromise, timeoutPromise]);\n\n this.connection.emitStatus(\"running\");\n\n if (!answers) {\n return {\n behavior: \"deny\",\n message:\n \"User did not respond to clarifying questions in time. Proceed with your best judgment.\",\n };\n }\n\n return {\n behavior: \"allow\",\n updatedInput: { questions: input.questions, answers },\n };\n }\n\n return { behavior: \"allow\", updatedInput: input };\n };\n\n const commonOptions = {\n model,\n systemPrompt,\n settingSources,\n cwd: this.config.workspaceDir,\n permissionMode: (isPm ? \"plan\" : \"bypassPermissions\") as \"plan\" | \"bypassPermissions\",\n allowDangerouslySkipPermissions: !isPm,\n canUseTool,\n tools: { type: \"preset\" as const, preset: \"claude_code\" as const },\n mcpServers: { conveyor: conveyorMcp },\n maxTurns: settings.maxTurns,\n effort: settings.effort,\n thinking: settings.thinking,\n betas: settings.betas,\n maxBudgetUsd: settings.maxBudgetUsd ?? 50,\n disallowedTools: disallowedTools.length > 0 ? disallowedTools : undefined,\n enableFileCheckpointing: settings.enableFileCheckpointing,\n };\n\n const resume = context.claudeSessionId ?? undefined;\n\n if (followUpContent) {\n // Follow-up message: single prompt, resume session\n const prompt = isPm\n ? `${this.buildInitialPrompt(context)}\\n\\n---\\n\\nThe team says:\\n${followUpContent}`\n : followUpContent;\n\n const agentQuery = query({\n prompt,\n options: { ...commonOptions, resume },\n });\n await this.runWithRetry(agentQuery, context, commonOptions);\n } else if (isPm) {\n // PM initial: no-op, we go straight to idle and wait for messages\n return;\n } else {\n // Task initial: long-running query with input stream\n const initialPrompt = this.buildInitialPrompt(context);\n const agentQuery = query({\n prompt: this.createInputStream(initialPrompt),\n options: { ...commonOptions, resume },\n });\n await this.runWithRetry(agentQuery, context, commonOptions);\n }\n\n if (isPm) {\n this.syncPlanFile(queryStartMs);\n }\n }\n\n /**\n * Run a query with retry logic for transient API errors.\n */\n private async runWithRetry(\n initialQuery: AsyncGenerator<SDKMessage, void>,\n context: TaskContext,\n // oxlint-disable-next-line typescript/no-explicit-any\n options: Record<string, any>,\n ): Promise<void> {\n for (let attempt = 0; attempt <= RETRY_DELAYS_MS.length; attempt++) {\n if (this.stopped) return;\n\n const agentQuery =\n attempt === 0\n ? initialQuery\n : query({\n prompt: this.createInputStream(this.buildInitialPrompt(context)),\n options: { ...options, resume: undefined },\n });\n\n try {\n const { retriable } = await this.processEvents(agentQuery, context);\n if (!retriable || this.stopped) return;\n } catch (error) {\n const isStaleSession =\n error instanceof Error && error.message.includes(\"No conversation found with session ID\");\n\n if (isStaleSession && context.claudeSessionId) {\n this.connection.storeSessionId(\"\");\n const freshCtx = { ...context, claudeSessionId: null };\n const freshQuery = query({\n prompt: this.createInputStream(this.buildInitialPrompt(freshCtx)),\n options: { ...options, resume: undefined },\n });\n return this.runWithRetry(freshQuery, freshCtx, options);\n }\n\n const isApiError = error instanceof Error && API_ERROR_PATTERN.test(error.message);\n if (!isApiError) throw error;\n }\n\n if (attempt >= RETRY_DELAYS_MS.length) {\n this.connection.postChatMessage(\n `Agent shutting down after ${RETRY_DELAYS_MS.length} failed retry attempts due to API errors. ` +\n `The task will resume automatically when the codespace restarts.`,\n );\n return;\n }\n\n const delayMs = RETRY_DELAYS_MS[attempt];\n const delayMin = Math.round(delayMs / 60_000);\n this.connection.postChatMessage(\n `API error encountered. Retrying in ${delayMin} minute${delayMin > 1 ? \"s\" : \"\"}... (attempt ${attempt + 1}/${RETRY_DELAYS_MS.length})`,\n );\n this.connection.sendEvent({\n type: \"error\",\n message: `API error, retrying in ${delayMin}m (${attempt + 1}/${RETRY_DELAYS_MS.length})`,\n });\n this.connection.emitStatus(\"waiting_for_input\");\n await this.callbacks.onStatusChange(\"waiting_for_input\");\n\n await new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, delayMs);\n const checkStopped = setInterval(() => {\n if (this.stopped) {\n clearTimeout(timer);\n clearInterval(checkStopped);\n resolve();\n }\n }, 1000);\n setTimeout(() => clearInterval(checkStopped), delayMs + 100);\n });\n\n this.connection.emitStatus(\"running\");\n await this.callbacks.onStatusChange(\"running\");\n }\n }\n\n stop(): void {\n this.stopped = true;\n if (this.inputResolver) {\n this.inputResolver(null as unknown as SDKUserMessage);\n this.inputResolver = null;\n }\n }\n}\n"],"mappings":"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","names":["execSync","join","execSync","join"]}
|