@rallycry/conveyor-agent 0.2.0 → 0.3.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.
@@ -6,24 +6,39 @@ var ConveyorConnection = class {
6
6
  constructor(config) {
7
7
  this.config = config;
8
8
  }
9
- async connect() {
9
+ connect() {
10
10
  return new Promise((resolve, reject) => {
11
+ let settled = false;
12
+ let attempts = 0;
13
+ const maxInitialAttempts = 30;
11
14
  this.socket = io(this.config.conveyorApiUrl, {
12
15
  auth: { taskToken: this.config.taskToken },
13
16
  transports: ["websocket"],
14
17
  reconnection: true,
15
- reconnectionAttempts: 10,
16
- reconnectionDelay: 1e3
18
+ reconnectionAttempts: Infinity,
19
+ reconnectionDelay: 2e3,
20
+ reconnectionDelayMax: 3e4,
21
+ randomizationFactor: 0.3,
22
+ extraHeaders: {
23
+ "ngrok-skip-browser-warning": "true"
24
+ }
17
25
  });
18
26
  this.socket.on("connect", () => {
19
- resolve();
27
+ if (!settled) {
28
+ settled = true;
29
+ resolve();
30
+ }
20
31
  });
21
- this.socket.on("connect_error", (err) => {
22
- reject(err);
32
+ this.socket.io.on("reconnect_attempt", () => {
33
+ attempts++;
34
+ if (!settled && attempts >= maxInitialAttempts) {
35
+ settled = true;
36
+ reject(new Error(`Failed to connect after ${maxInitialAttempts} attempts`));
37
+ }
23
38
  });
24
39
  });
25
40
  }
26
- async fetchTaskContext() {
41
+ fetchTaskContext() {
27
42
  const socket = this.socket;
28
43
  if (!socket) throw new Error("Not connected");
29
44
  return new Promise((resolve, reject) => {
@@ -61,7 +76,7 @@ var ConveyorConnection = class {
61
76
  content
62
77
  });
63
78
  }
64
- async createPR(params) {
79
+ createPR(params) {
65
80
  const socket = this.socket;
66
81
  if (!socket) throw new Error("Not connected");
67
82
  return new Promise((resolve, reject) => {
@@ -91,7 +106,11 @@ var ConveyorConnection = class {
91
106
  };
92
107
 
93
108
  // src/runner.ts
94
- import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
109
+ import {
110
+ query,
111
+ tool,
112
+ createSdkMcpServer
113
+ } from "@anthropic-ai/claude-agent-sdk";
95
114
  import { z } from "zod";
96
115
  var AgentRunner = class {
97
116
  config;
@@ -180,8 +199,22 @@ var AgentRunner = class {
180
199
  yield msg;
181
200
  }
182
201
  }
202
+ findLastAgentMessageIndex(history) {
203
+ for (let i = history.length - 1; i >= 0; i--) {
204
+ if (history[i].role === "assistant") return i;
205
+ }
206
+ return -1;
207
+ }
208
+ detectRelaunchScenario(context) {
209
+ const lastAgentIdx = this.findLastAgentMessageIndex(context.chatHistory);
210
+ if (lastAgentIdx === -1) return "fresh";
211
+ const messagesAfterAgent = context.chatHistory.slice(lastAgentIdx + 1);
212
+ const hasNewUserMessages = messagesAfterAgent.some((m) => m.role === "user");
213
+ return hasNewUserMessages ? "feedback_relaunch" : "idle_relaunch";
214
+ }
183
215
  buildInitialPrompt(context) {
184
216
  const parts = [];
217
+ const scenario = this.detectRelaunchScenario(context);
185
218
  parts.push(`# Task: ${context.title}`);
186
219
  if (context.description) {
187
220
  parts.push(`
@@ -202,12 +235,46 @@ ${context.plan}`);
202
235
  parts.push(`[${sender}]: ${msg.content}`);
203
236
  }
204
237
  }
205
- parts.push(
206
- `
207
- ## Instructions`,
208
- `Execute the task plan above. Work on the git branch "${context.githubBranch}".`,
209
- `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.`
210
- );
238
+ parts.push(`
239
+ ## Instructions`);
240
+ if (scenario === "fresh") {
241
+ parts.push(
242
+ `Execute the task plan above. Work on the git branch "${context.githubBranch}".`,
243
+ `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.`
244
+ );
245
+ } else if (scenario === "idle_relaunch") {
246
+ parts.push(
247
+ `You were relaunched but no new instructions have been given since your last run.`,
248
+ `Work on the git branch "${context.githubBranch}".`,
249
+ `Review the current state of the codebase and verify everything is working correctly (e.g. tests pass, the web server starts on port 3000).`,
250
+ `Post a brief status update to the chat summarizing the current state.`,
251
+ `Then wait for further instructions \u2014 do NOT redo work that was already completed.`
252
+ );
253
+ if (context.githubPRUrl) {
254
+ parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);
255
+ }
256
+ } else {
257
+ const lastAgentIdx = this.findLastAgentMessageIndex(context.chatHistory);
258
+ const newMessages = context.chatHistory.slice(lastAgentIdx + 1).filter((m) => m.role === "user");
259
+ parts.push(
260
+ `You were relaunched with new feedback since your last run.`,
261
+ `Work on the git branch "${context.githubBranch}".`,
262
+ `
263
+ New messages since your last run:`,
264
+ ...newMessages.map((m) => `[${m.userName ?? "user"}]: ${m.content}`),
265
+ `
266
+ Address the requested changes. Commit and push your updates.`
267
+ );
268
+ if (context.githubPRUrl) {
269
+ parts.push(
270
+ `An existing PR is open at ${context.githubPRUrl} \u2014 push to the same branch to update it. Do NOT create a new PR.`
271
+ );
272
+ } else {
273
+ parts.push(
274
+ `When finished, use the create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`
275
+ );
276
+ }
277
+ }
211
278
  return parts.join("\n");
212
279
  }
213
280
  buildSystemPrompt(context) {
@@ -229,7 +296,7 @@ You have access to Conveyor MCP tools to interact with the task management syste
229
296
  );
230
297
  return parts.join("\n");
231
298
  }
232
- // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
299
+ // oxlint-disable-next-line typescript/explicit-function-return-type, max-lines-per-function
233
300
  createConveyorMcpServer() {
234
301
  const connection = this.connection;
235
302
  const config = this.config;
@@ -242,11 +309,17 @@ You have access to Conveyor MCP tools to interact with the task management syste
242
309
  tool(
243
310
  "read_task_chat",
244
311
  "Read recent messages from the task chat to see team feedback or instructions",
245
- { limit: z.number().optional().describe("Number of recent messages to fetch (default 20)") },
312
+ {
313
+ limit: z.number().optional().describe("Number of recent messages to fetch (default 20)")
314
+ },
246
315
  (_args) => {
247
- return Promise.resolve(textResult(
248
- JSON.stringify({ note: "Chat history was provided in the initial context. Use post_to_chat to ask the team questions." })
249
- ));
316
+ return Promise.resolve(
317
+ textResult(
318
+ JSON.stringify({
319
+ note: "Chat history was provided in the initial context. Use post_to_chat to ask the team questions."
320
+ })
321
+ )
322
+ );
250
323
  },
251
324
  { annotations: { readOnly: true } }
252
325
  ),
@@ -305,6 +378,7 @@ You have access to Conveyor MCP tools to interact with the task management syste
305
378
  ]
306
379
  });
307
380
  }
381
+ // oxlint-disable-next-line max-lines-per-function, complexity
308
382
  async processEvents(events) {
309
383
  const startTime = Date.now();
310
384
  let totalCostUsd = 0;
@@ -423,4 +497,4 @@ export {
423
497
  ConveyorConnection,
424
498
  AgentRunner
425
499
  };
426
- //# sourceMappingURL=chunk-I2DBDKGW.js.map
500
+ //# sourceMappingURL=chunk-XRNZVTJT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connection.ts","../src/runner.ts"],"sourcesContent":["import { io, type Socket } from \"socket.io-client\";\nimport type { AgentRunnerConfig, TaskContext, AgentEvent } from \"./types.js\";\n\nexport class ConveyorConnection {\n private socket: Socket | null = null;\n private config: AgentRunnerConfig;\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 },\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 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 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.socket.emit(\"agentRunner:event\", {\n taskId: this.config.taskId,\n event,\n });\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 onChatMessage(callback: (message: { content: string; userId: string }) => void): void {\n this.socket?.on(\"agentRunner:incomingMessage\", callback);\n }\n\n onStopRequested(callback: () => void): void {\n this.socket?.on(\"agentRunner:stop\", callback);\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n}\n","// oxlint-disable max-lines\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 TaskContext,\n ActivityEventSummary,\n} from \"./types.js\";\nimport { ConveyorConnection } from \"./connection.js\";\n\nexport class AgentRunner {\n private config: AgentRunnerConfig;\n private connection: ConveyorConnection;\n private callbacks: AgentRunnerCallbacks;\n private stopped = false;\n private inputResolver: ((msg: SDKUserMessage) => void) | null = null;\n private pendingMessages: SDKUserMessage[] = [];\n private currentTurnToolCalls: ActivityEventSummary[] = [];\n\n constructor(config: AgentRunnerConfig, callbacks: AgentRunnerCallbacks) {\n this.config = config;\n this.connection = new ConveyorConnection(config);\n this.callbacks = callbacks;\n }\n\n async start(): Promise<void> {\n await this.callbacks.onStatusChange(\"connecting\");\n await this.connection.connect();\n\n await this.callbacks.onStatusChange(\"fetching_context\");\n const context = await this.connection.fetchTaskContext();\n\n this.connection.onStopRequested(() => {\n this.stopped = true;\n });\n\n this.connection.onChatMessage((message) => {\n this.injectHumanMessage(message.content);\n });\n\n await this.callbacks.onStatusChange(\"running\");\n this.connection.sendEvent({\n type: \"connected\",\n taskId: this.config.taskId,\n });\n\n try {\n await this.executeTask(context);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n this.connection.sendEvent({ type: \"error\", message });\n await this.callbacks.onEvent({ type: \"error\", message });\n throw error;\n } finally {\n await this.callbacks.onStatusChange(\"finished\");\n this.connection.disconnect();\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 async *createInputStream(\n initialPrompt: string,\n ): AsyncGenerator<SDKUserMessage, void, unknown> {\n yield {\n type: \"user\" as const,\n session_id: \"\",\n message: { role: \"user\" as const, content: initialPrompt },\n parent_tool_use_id: null,\n };\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 await this.callbacks.onStatusChange(\"waiting_for_input\");\n const msg = await new Promise<SDKUserMessage | null>((resolve) => {\n this.inputResolver = resolve as (msg: SDKUserMessage) => void;\n\n const checkStopped = setInterval(() => {\n if (this.stopped) {\n clearInterval(checkStopped);\n this.inputResolver = null;\n resolve(null);\n }\n }, 1000);\n });\n\n if (!msg) break;\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 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 private buildInitialPrompt(context: TaskContext): string {\n const parts: string[] = [];\n const scenario = this.detectRelaunchScenario(context);\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.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 parts.push(\n `Execute the task plan above. Work on the git branch \"${context.githubBranch}\".`,\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 } else if (scenario === \"idle_relaunch\") {\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 } else {\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 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 return parts.join(\"\\n\");\n }\n\n private buildSystemPrompt(context: TaskContext): string {\n const parts = [\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 ];\n if (this.config.instructions) {\n parts.push(`\\nAgent 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 `Use the create_pull_request tool to open PRs — do NOT use gh CLI or shell commands for PR creation.`,\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() {\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 return createSdkMcpServer({\n name: \"conveyor\",\n tools: [\n tool(\n \"read_task_chat\",\n \"Read recent messages from the task chat to see team feedback or instructions\",\n {\n limit: z\n .number()\n .optional()\n .describe(\"Number of recent messages to fetch (default 20)\"),\n },\n (_args) => {\n return Promise.resolve(\n textResult(\n JSON.stringify({\n note: \"Chat history was provided in the initial context. Use post_to_chat to ask the team questions.\",\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 \"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({ type: \"pr_created\", url: result.url, number: result.number });\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 tool(\n \"get_task_plan\",\n \"Re-read the latest task plan in case it was updated\",\n {},\n async () => {\n try {\n const context = await connection.fetchTaskContext();\n return textResult(context.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 }\n\n // oxlint-disable-next-line max-lines-per-function, complexity\n private async processEvents(events: AsyncGenerator<SDKMessage, void>): Promise<void> {\n const startTime = Date.now();\n let totalCostUsd = 0;\n\n for await (const event of events) {\n if (this.stopped) break;\n\n switch (event.type) {\n case \"assistant\": {\n const msg = event.message as unknown as Record<string, unknown>;\n const content = msg.content as Record<string, unknown>[];\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 this.connection.sendEvent({ type: \"message\", content: text });\n this.connection.postChatMessage(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 summary: ActivityEventSummary = {\n tool: name,\n input: inputStr.slice(0, 500),\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 (this.currentTurnToolCalls.length > 0) {\n this.connection.sendEvent({\n type: \"turn_end\",\n toolCalls: [...this.currentTurnToolCalls],\n });\n this.currentTurnToolCalls = [];\n }\n break;\n }\n\n case \"result\": {\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 this.connection.sendEvent({\n type: \"completed\",\n summary,\n costUsd: totalCostUsd,\n durationMs,\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 this.connection.sendEvent({ type: \"error\", message: errorMsg });\n await this.callbacks.onEvent({ type: \"error\", message: errorMsg });\n }\n break;\n }\n\n case \"system\": {\n if (event.subtype === \"init\") {\n await this.callbacks.onEvent({\n type: \"thinking\",\n message: `Agent initialized (model: ${event.model})`,\n });\n }\n break;\n }\n }\n }\n }\n\n private async executeTask(context: TaskContext): Promise<void> {\n if (this.stopped) return;\n\n const initialPrompt = this.buildInitialPrompt(context);\n const systemPrompt = this.buildSystemPrompt(context);\n const conveyorMcp = this.createConveyorMcpServer();\n const inputStream = this.createInputStream(initialPrompt);\n\n const agentQuery = query({\n prompt: inputStream,\n options: {\n model: this.config.model,\n systemPrompt,\n cwd: this.config.workspaceDir,\n permissionMode: \"bypassPermissions\",\n allowDangerouslySkipPermissions: true,\n tools: { type: \"preset\", preset: \"claude_code\" },\n mcpServers: { conveyor: conveyorMcp },\n maxTurns: 100,\n },\n });\n\n await this.processEvents(agentQuery);\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":[]}
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  AgentRunner
4
- } from "./chunk-I2DBDKGW.js";
4
+ } from "./chunk-XRNZVTJT.js";
5
5
 
6
6
  // src/cli.ts
7
7
  var CONVEYOR_API_URL = process.env.CONVEYOR_API_URL;
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/* eslint-disable no-console */\n\nimport { AgentRunner } from \"./runner.js\";\nimport type { AgentEvent, AgentRunnerStatus } from \"./types.js\";\n\nconst CONVEYOR_API_URL = process.env.CONVEYOR_API_URL;\nconst CONVEYOR_TASK_TOKEN = process.env.CONVEYOR_TASK_TOKEN;\nconst CONVEYOR_TASK_ID = process.env.CONVEYOR_TASK_ID;\nconst CONVEYOR_MODEL = process.env.CONVEYOR_MODEL ?? \"claude-sonnet-4-20250514\";\nconst CONVEYOR_INSTRUCTIONS = process.env.CONVEYOR_INSTRUCTIONS ?? \"\";\nconst CONVEYOR_WORKSPACE = process.env.CONVEYOR_WORKSPACE ?? process.cwd();\n\nif (!CONVEYOR_API_URL || !CONVEYOR_TASK_TOKEN || !CONVEYOR_TASK_ID) {\n console.error(\"Missing required environment variables:\");\n console.error(\" CONVEYOR_API_URL - URL of the Conveyor API server\");\n console.error(\" CONVEYOR_TASK_TOKEN - JWT token for task authentication\");\n console.error(\" CONVEYOR_TASK_ID - ID of the task to execute\");\n process.exit(1);\n}\n\nconst runner = new AgentRunner(\n {\n conveyorApiUrl: CONVEYOR_API_URL,\n taskToken: CONVEYOR_TASK_TOKEN,\n taskId: CONVEYOR_TASK_ID,\n model: CONVEYOR_MODEL,\n instructions: CONVEYOR_INSTRUCTIONS,\n workspaceDir: CONVEYOR_WORKSPACE,\n },\n {\n onEvent: (event: AgentEvent) => {\n const detail =\n \"message\" in event\n ? event.message\n : \"content\" in event\n ? event.content\n : \"summary\" in event\n ? event.summary\n : \"\";\n console.log(`[${event.type}] ${detail}`);\n },\n onStatusChange: (status: AgentRunnerStatus) => {\n console.log(`[status] ${status}`);\n },\n }\n);\n\nprocess.on(\"SIGTERM\", () => {\n console.log(\"Received SIGTERM, stopping agent...\");\n runner.stop();\n});\n\nprocess.on(\"SIGINT\", () => {\n console.log(\"Received SIGINT, stopping agent...\");\n runner.stop();\n});\n\nrunner.start().catch((error: unknown) => {\n console.error(\"Agent runner failed:\", error);\n process.exit(1);\n});\n"],"mappings":";;;;;;AAMA,IAAM,mBAAmB,QAAQ,IAAI;AACrC,IAAM,sBAAsB,QAAQ,IAAI;AACxC,IAAM,mBAAmB,QAAQ,IAAI;AACrC,IAAM,iBAAiB,QAAQ,IAAI,kBAAkB;AACrD,IAAM,wBAAwB,QAAQ,IAAI,yBAAyB;AACnE,IAAM,qBAAqB,QAAQ,IAAI,sBAAsB,QAAQ,IAAI;AAEzE,IAAI,CAAC,oBAAoB,CAAC,uBAAuB,CAAC,kBAAkB;AAClE,UAAQ,MAAM,yCAAyC;AACvD,UAAQ,MAAM,qDAAqD;AACnE,UAAQ,MAAM,2DAA2D;AACzE,UAAQ,MAAM,gDAAgD;AAC9D,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,SAAS,IAAI;AAAA,EACjB;AAAA,IACE,gBAAgB;AAAA,IAChB,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,cAAc;AAAA,IACd,cAAc;AAAA,EAChB;AAAA,EACA;AAAA,IACE,SAAS,CAAC,UAAsB;AAC9B,YAAM,SACJ,aAAa,QACT,MAAM,UACN,aAAa,QACX,MAAM,UACN,aAAa,QACX,MAAM,UACN;AACV,cAAQ,IAAI,IAAI,MAAM,IAAI,KAAK,MAAM,EAAE;AAAA,IACzC;AAAA,IACA,gBAAgB,CAAC,WAA8B;AAC7C,cAAQ,IAAI,YAAY,MAAM,EAAE;AAAA,IAClC;AAAA,EACF;AACF;AAEA,QAAQ,GAAG,WAAW,MAAM;AAC1B,UAAQ,IAAI,qCAAqC;AACjD,SAAO,KAAK;AACd,CAAC;AAED,QAAQ,GAAG,UAAU,MAAM;AACzB,UAAQ,IAAI,oCAAoC;AAChD,SAAO,KAAK;AACd,CAAC;AAED,OAAO,MAAM,EAAE,MAAM,CAAC,UAAmB;AACvC,UAAQ,MAAM,wBAAwB,KAAK;AAC3C,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/* oxlint-disable no-console */\n\nimport { AgentRunner } from \"./runner.js\";\nimport type { AgentEvent, AgentRunnerStatus } from \"./types.js\";\n\nconst CONVEYOR_API_URL = process.env.CONVEYOR_API_URL;\nconst CONVEYOR_TASK_TOKEN = process.env.CONVEYOR_TASK_TOKEN;\nconst CONVEYOR_TASK_ID = process.env.CONVEYOR_TASK_ID;\nconst CONVEYOR_MODEL = process.env.CONVEYOR_MODEL ?? \"claude-sonnet-4-20250514\";\nconst CONVEYOR_INSTRUCTIONS = process.env.CONVEYOR_INSTRUCTIONS ?? \"\";\nconst CONVEYOR_WORKSPACE = process.env.CONVEYOR_WORKSPACE ?? process.cwd();\n\nif (!CONVEYOR_API_URL || !CONVEYOR_TASK_TOKEN || !CONVEYOR_TASK_ID) {\n console.error(\"Missing required environment variables:\");\n console.error(\" CONVEYOR_API_URL - URL of the Conveyor API server\");\n console.error(\" CONVEYOR_TASK_TOKEN - JWT token for task authentication\");\n console.error(\" CONVEYOR_TASK_ID - ID of the task to execute\");\n process.exit(1);\n}\n\nconst runner = new AgentRunner(\n {\n conveyorApiUrl: CONVEYOR_API_URL,\n taskToken: CONVEYOR_TASK_TOKEN,\n taskId: CONVEYOR_TASK_ID,\n model: CONVEYOR_MODEL,\n instructions: CONVEYOR_INSTRUCTIONS,\n workspaceDir: CONVEYOR_WORKSPACE,\n },\n {\n onEvent: (event: AgentEvent) => {\n const detail =\n \"message\" in event\n ? event.message\n : \"content\" in event\n ? event.content\n : \"summary\" in event\n ? event.summary\n : \"\";\n console.log(`[${event.type}] ${detail}`);\n },\n onStatusChange: (status: AgentRunnerStatus) => {\n console.log(`[status] ${status}`);\n },\n },\n);\n\nprocess.on(\"SIGTERM\", () => {\n console.log(\"Received SIGTERM, stopping agent...\");\n runner.stop();\n});\n\nprocess.on(\"SIGINT\", () => {\n console.log(\"Received SIGINT, stopping agent...\");\n runner.stop();\n});\n\nrunner.start().catch((error: unknown) => {\n console.error(\"Agent runner failed:\", error);\n process.exit(1);\n});\n"],"mappings":";;;;;;AAMA,IAAM,mBAAmB,QAAQ,IAAI;AACrC,IAAM,sBAAsB,QAAQ,IAAI;AACxC,IAAM,mBAAmB,QAAQ,IAAI;AACrC,IAAM,iBAAiB,QAAQ,IAAI,kBAAkB;AACrD,IAAM,wBAAwB,QAAQ,IAAI,yBAAyB;AACnE,IAAM,qBAAqB,QAAQ,IAAI,sBAAsB,QAAQ,IAAI;AAEzE,IAAI,CAAC,oBAAoB,CAAC,uBAAuB,CAAC,kBAAkB;AAClE,UAAQ,MAAM,yCAAyC;AACvD,UAAQ,MAAM,qDAAqD;AACnE,UAAQ,MAAM,2DAA2D;AACzE,UAAQ,MAAM,gDAAgD;AAC9D,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,SAAS,IAAI;AAAA,EACjB;AAAA,IACE,gBAAgB;AAAA,IAChB,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,cAAc;AAAA,IACd,cAAc;AAAA,EAChB;AAAA,EACA;AAAA,IACE,SAAS,CAAC,UAAsB;AAC9B,YAAM,SACJ,aAAa,QACT,MAAM,UACN,aAAa,QACX,MAAM,UACN,aAAa,QACX,MAAM,UACN;AACV,cAAQ,IAAI,IAAI,MAAM,IAAI,KAAK,MAAM,EAAE;AAAA,IACzC;AAAA,IACA,gBAAgB,CAAC,WAA8B;AAC7C,cAAQ,IAAI,YAAY,MAAM,EAAE;AAAA,IAClC;AAAA,EACF;AACF;AAEA,QAAQ,GAAG,WAAW,MAAM;AAC1B,UAAQ,IAAI,qCAAqC;AACjD,SAAO,KAAK;AACd,CAAC;AAED,QAAQ,GAAG,UAAU,MAAM;AACzB,UAAQ,IAAI,oCAAoC;AAChD,SAAO,KAAK;AACd,CAAC;AAED,OAAO,MAAM,EAAE,MAAM,CAAC,UAAmB;AACvC,UAAQ,MAAM,wBAAwB,KAAK;AAC3C,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
package/dist/index.d.ts CHANGED
@@ -16,6 +16,7 @@ interface TaskContext {
16
16
  agentInstructions: string;
17
17
  model: string;
18
18
  githubBranch: string;
19
+ githubPRUrl?: string | null;
19
20
  }
20
21
  interface ChatMessage {
21
22
  role: "user" | "assistant" | "system";
@@ -84,6 +85,8 @@ declare class AgentRunner {
84
85
  start(): Promise<void>;
85
86
  private injectHumanMessage;
86
87
  private createInputStream;
88
+ private findLastAgentMessageIndex;
89
+ private detectRelaunchScenario;
87
90
  private buildInitialPrompt;
88
91
  private buildSystemPrompt;
89
92
  private createConveyorMcpServer;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  AgentRunner,
3
3
  ConveyorConnection
4
- } from "./chunk-I2DBDKGW.js";
4
+ } from "./chunk-XRNZVTJT.js";
5
5
  export {
6
6
  AgentRunner,
7
7
  ConveyorConnection
package/package.json CHANGED
@@ -1,29 +1,33 @@
1
1
  {
2
2
  "name": "@rallycry/conveyor-agent",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Conveyor cloud build agent runner - executes task plans inside GitHub Codespaces",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
5
+ "keywords": [
6
+ "agent",
7
+ "claude",
8
+ "codespace",
9
+ "conveyor"
10
+ ],
11
+ "license": "MIT",
8
12
  "bin": {
9
13
  "conveyor-agent": "./dist/cli.js"
10
14
  },
11
15
  "files": [
12
16
  "dist"
13
17
  ],
18
+ "type": "module",
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
14
21
  "publishConfig": {
15
22
  "access": "public"
16
23
  },
17
24
  "scripts": {
18
25
  "build": "tsup",
19
26
  "dev": "tsup --watch",
20
- "lint": "eslint src",
21
- "lint:fix": "eslint src --fix",
22
- "typecheck": "tsc --noEmit",
23
- "prepublishOnly": "pnpm build"
27
+ "lint": "oxlint -c ../../.oxlintrc.json src",
28
+ "lint:fix": "oxlint -c ../../.oxlintrc.json --fix src",
29
+ "typecheck": "tsgo --noEmit"
24
30
  },
25
- "keywords": ["conveyor", "agent", "codespace", "claude"],
26
- "license": "MIT",
27
31
  "dependencies": {
28
32
  "@anthropic-ai/claude-agent-sdk": "^0.2.71",
29
33
  "socket.io-client": "^4.7.4",
@@ -31,8 +35,6 @@
31
35
  "zod": "^3.25.76"
32
36
  },
33
37
  "devDependencies": {
34
- "@project/eslint-config": "workspace:*",
35
- "eslint": "^9.0.0",
36
38
  "tsup": "^8.0.0",
37
39
  "typescript": "^5.3.0"
38
40
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/connection.ts","../src/runner.ts"],"sourcesContent":["import { io, type Socket } from \"socket.io-client\";\nimport type { AgentRunnerConfig, TaskContext, AgentEvent } from \"./types.js\";\n\nexport class ConveyorConnection {\n private socket: Socket | null = null;\n private config: AgentRunnerConfig;\n\n constructor(config: AgentRunnerConfig) {\n this.config = config;\n }\n\n async connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.socket = io(this.config.conveyorApiUrl, {\n auth: { taskToken: this.config.taskToken },\n transports: [\"websocket\"],\n reconnection: true,\n reconnectionAttempts: 10,\n reconnectionDelay: 1000,\n });\n\n this.socket.on(\"connect\", () => {\n resolve();\n });\n this.socket.on(\"connect_error\", (err: Error) => {\n reject(err);\n });\n });\n }\n\n async 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.socket.emit(\"agentRunner:event\", {\n taskId: this.config.taskId,\n event,\n });\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 async createPR(params: { title: string; body: string; baseBranch?: string }): 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: { success: boolean; data?: { url: string; number: number }; error?: string }): 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 onChatMessage(callback: (message: { content: string; userId: string }) => void): void {\n this.socket?.on(\"agentRunner:incomingMessage\", callback);\n }\n\n onStopRequested(callback: () => void): void {\n this.socket?.on(\"agentRunner:stop\", callback);\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n}\n","import { query, tool, createSdkMcpServer, type SDKMessage, type SDKUserMessage } from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod\";\nimport type {\n AgentRunnerConfig,\n AgentRunnerCallbacks,\n TaskContext,\n ActivityEventSummary,\n} from \"./types.js\";\nimport { ConveyorConnection } from \"./connection.js\";\n\nexport class AgentRunner {\n private config: AgentRunnerConfig;\n private connection: ConveyorConnection;\n private callbacks: AgentRunnerCallbacks;\n private stopped = false;\n private inputResolver: ((msg: SDKUserMessage) => void) | null = null;\n private pendingMessages: SDKUserMessage[] = [];\n private currentTurnToolCalls: ActivityEventSummary[] = [];\n\n constructor(config: AgentRunnerConfig, callbacks: AgentRunnerCallbacks) {\n this.config = config;\n this.connection = new ConveyorConnection(config);\n this.callbacks = callbacks;\n }\n\n async start(): Promise<void> {\n await this.callbacks.onStatusChange(\"connecting\");\n await this.connection.connect();\n\n await this.callbacks.onStatusChange(\"fetching_context\");\n const context = await this.connection.fetchTaskContext();\n\n this.connection.onStopRequested(() => {\n this.stopped = true;\n });\n\n this.connection.onChatMessage((message) => {\n this.injectHumanMessage(message.content);\n });\n\n await this.callbacks.onStatusChange(\"running\");\n this.connection.sendEvent({\n type: \"connected\",\n taskId: this.config.taskId,\n });\n\n try {\n await this.executeTask(context);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n this.connection.sendEvent({ type: \"error\", message });\n await this.callbacks.onEvent({ type: \"error\", message });\n throw error;\n } finally {\n await this.callbacks.onStatusChange(\"finished\");\n this.connection.disconnect();\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 async *createInputStream(\n initialPrompt: string\n ): AsyncGenerator<SDKUserMessage, void, unknown> {\n yield {\n type: \"user\" as const,\n session_id: \"\",\n message: { role: \"user\" as const, content: initialPrompt },\n parent_tool_use_id: null,\n };\n\n while (!this.stopped) {\n if (this.pendingMessages.length > 0) {\n const next = this.pendingMessages.shift();\n if (next) { yield next; }\n continue;\n }\n\n await this.callbacks.onStatusChange(\"waiting_for_input\");\n const msg = await new Promise<SDKUserMessage | null>((resolve) => {\n this.inputResolver = resolve as (msg: SDKUserMessage) => void;\n\n const checkStopped = setInterval(() => {\n if (this.stopped) {\n clearInterval(checkStopped);\n this.inputResolver = null;\n resolve(null);\n }\n }, 1000);\n });\n\n if (!msg) break;\n await this.callbacks.onStatusChange(\"running\");\n yield msg;\n }\n }\n\n private buildInitialPrompt(context: TaskContext): string {\n const parts: string[] = [];\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 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 parts.push(\n `\\n## Instructions`,\n `Execute the task plan above. Work on the git branch \"${context.githubBranch}\".`,\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 return parts.join(\"\\n\");\n }\n\n private buildSystemPrompt(context: TaskContext): string {\n const parts = [\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 ];\n if (this.config.instructions) {\n parts.push(`\\nAgent 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 `Use the create_pull_request tool to open PRs — do NOT use gh CLI or shell commands for PR creation.`\n );\n return parts.join(\"\\n\");\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n private createConveyorMcpServer() {\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 return createSdkMcpServer({\n name: \"conveyor\",\n tools: [\n tool(\n \"read_task_chat\",\n \"Read recent messages from the task chat to see team feedback or instructions\",\n { limit: z.number().optional().describe(\"Number of recent messages to fetch (default 20)\") },\n (_args) => {\n return Promise.resolve(textResult(\n JSON.stringify({ note: \"Chat history was provided in the initial context. Use post_to_chat to ask the team questions.\" })\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 \"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({ type: \"pr_created\", url: result.url, number: result.number });\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 tool(\n \"get_task_plan\",\n \"Re-read the latest task plan in case it was updated\",\n {},\n async () => {\n try {\n const context = await connection.fetchTaskContext();\n return textResult(context.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 }\n\n private async processEvents(events: AsyncGenerator<SDKMessage, void>): Promise<void> {\n const startTime = Date.now();\n let totalCostUsd = 0;\n\n for await (const event of events) {\n if (this.stopped) break;\n\n switch (event.type) {\n case \"assistant\": {\n const msg = event.message as unknown as Record<string, unknown>;\n const content = msg.content as Record<string, unknown>[];\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 this.connection.sendEvent({ type: \"message\", content: text });\n this.connection.postChatMessage(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\"\n ? block.input\n : JSON.stringify(block.input);\n const summary: ActivityEventSummary = {\n tool: name,\n input: inputStr.slice(0, 500),\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 (this.currentTurnToolCalls.length > 0) {\n this.connection.sendEvent({\n type: \"turn_end\",\n toolCalls: [...this.currentTurnToolCalls],\n });\n this.currentTurnToolCalls = [];\n }\n break;\n }\n\n case \"result\": {\n const resultEvent = event as SDKMessage & { type: \"result\"; subtype: string };\n if (resultEvent.subtype === \"success\") {\n totalCostUsd = \"total_cost_usd\" in resultEvent ? (resultEvent as Record<string, unknown>).total_cost_usd as number : 0;\n const durationMs = Date.now() - startTime;\n const summary = \"result\" in resultEvent ? String((resultEvent as Record<string, unknown>).result) : \"Task completed.\";\n\n this.connection.sendEvent({\n type: \"completed\",\n summary,\n costUsd: totalCostUsd,\n durationMs,\n });\n\n await this.callbacks.onEvent({\n type: \"completed\",\n summary,\n costUsd: totalCostUsd,\n durationMs,\n });\n } else {\n const errors = \"errors\" in resultEvent ? (resultEvent as Record<string, unknown>).errors as string[] : [];\n const errorMsg = errors.length > 0 ? errors.join(\", \") : `Agent stopped: ${resultEvent.subtype}`;\n this.connection.sendEvent({ type: \"error\", message: errorMsg });\n await this.callbacks.onEvent({ type: \"error\", message: errorMsg });\n }\n break;\n }\n\n case \"system\": {\n if (event.subtype === \"init\") {\n await this.callbacks.onEvent({\n type: \"thinking\",\n message: `Agent initialized (model: ${event.model})`,\n });\n }\n break;\n }\n }\n }\n }\n\n private async executeTask(context: TaskContext): Promise<void> {\n if (this.stopped) return;\n\n const initialPrompt = this.buildInitialPrompt(context);\n const systemPrompt = this.buildSystemPrompt(context);\n const conveyorMcp = this.createConveyorMcpServer();\n const inputStream = this.createInputStream(initialPrompt);\n\n const agentQuery = query({\n prompt: inputStream,\n options: {\n model: this.config.model,\n systemPrompt,\n cwd: this.config.workspaceDir,\n permissionMode: \"bypassPermissions\",\n allowDangerouslySkipPermissions: true,\n tools: { type: \"preset\", preset: \"claude_code\" },\n mcpServers: { conveyor: conveyorMcp },\n maxTurns: 100,\n },\n });\n\n await this.processEvents(agentQuery);\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":[]}