@rallycry/conveyor-agent 1.0.0 → 1.1.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.
@@ -134,6 +134,12 @@ var ConveyorConnection = class _ConveyorConnection {
134
134
  ...params
135
135
  });
136
136
  }
137
+ sendTypingStart() {
138
+ this.sendEvent({ type: "agent_typing_start" });
139
+ }
140
+ sendTypingStop() {
141
+ this.sendEvent({ type: "agent_typing_stop" });
142
+ }
137
143
  disconnect() {
138
144
  this.flushEvents();
139
145
  this.socket?.disconnect();
@@ -453,9 +459,8 @@ ${context.plan}`);
453
459
  if (scenario === "fresh") {
454
460
  if (this.config.mode === "pm") {
455
461
  parts.push(
456
- `You are the project manager for this task. Help the team plan and refine it.`,
457
- `You have access to the repository \u2014 read files to understand the codebase before writing the plan.`,
458
- `When the plan is complete and ready, use the update_task tool to save it and update_task_status to move the task to "Open".`
462
+ `You are the project manager for this task.`,
463
+ `The task details are provided above. Wait for the team to ask questions or provide additional requirements before starting to plan.`
459
464
  );
460
465
  } else {
461
466
  parts.push(
@@ -673,6 +678,7 @@ You have access to Conveyor MCP tools to interact with the task management syste
673
678
  const startTime = Date.now();
674
679
  let totalCostUsd = 0;
675
680
  let sessionIdStored = false;
681
+ let isTyping = false;
676
682
  for await (const event of events) {
677
683
  if (this.stopped) break;
678
684
  switch (event.type) {
@@ -691,6 +697,12 @@ You have access to Conveyor MCP tools to interact with the task management syste
691
697
  break;
692
698
  }
693
699
  case "assistant": {
700
+ if (!isTyping) {
701
+ setTimeout(() => {
702
+ this.connection.sendTypingStart();
703
+ }, 200);
704
+ isTyping = true;
705
+ }
694
706
  const msg = event.message;
695
707
  const content = msg.content;
696
708
  const turnTextParts = [];
@@ -704,9 +716,11 @@ You have access to Conveyor MCP tools to interact with the task management syste
704
716
  } else if (blockType === "tool_use") {
705
717
  const name = block.name;
706
718
  const inputStr = typeof block.input === "string" ? block.input : JSON.stringify(block.input);
719
+ const isContentTool = ["edit", "write"].includes(name.toLowerCase());
720
+ const inputLimit = isContentTool ? 1e4 : 500;
707
721
  const summary = {
708
722
  tool: name,
709
- input: inputStr.slice(0, 500),
723
+ input: inputStr.slice(0, inputLimit),
710
724
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
711
725
  };
712
726
  this.currentTurnToolCalls.push(summary);
@@ -735,6 +749,10 @@ You have access to Conveyor MCP tools to interact with the task management syste
735
749
  break;
736
750
  }
737
751
  case "result": {
752
+ if (isTyping) {
753
+ this.connection.sendTypingStop();
754
+ isTyping = false;
755
+ }
738
756
  const resultEvent = event;
739
757
  if (resultEvent.subtype === "success") {
740
758
  totalCostUsd = "total_cost_usd" in resultEvent ? resultEvent.total_cost_usd : 0;
@@ -774,6 +792,9 @@ You have access to Conveyor MCP tools to interact with the task management syste
774
792
  }
775
793
  }
776
794
  }
795
+ if (isTyping) {
796
+ this.connection.sendTypingStop();
797
+ }
777
798
  }
778
799
  // oxlint-disable-next-line max-lines-per-function
779
800
  async executeTask(context) {
@@ -848,4 +869,4 @@ export {
848
869
  runStartCommand,
849
870
  AgentRunner
850
871
  };
851
- //# sourceMappingURL=chunk-ZLMVQCVF.js.map
872
+ //# sourceMappingURL=chunk-LMPNKQJE.js.map
@@ -0,0 +1 @@
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\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 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.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 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.socket?.on(\"agentRunner:incomingMessage\", callback);\n }\n\n onStopRequested(callback: () => void): void {\n this.socket?.on(\"agentRunner:stop\", callback);\n }\n\n trackSpending(params: {\n agentId: string;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n totalCostUsd: number;\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 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 { 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","// oxlint-disable max-lines\nimport { execSync } from \"node:child_process\";\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\";\nimport {\n loadConveyorConfig,\n loadForwardPorts,\n runSetupCommand,\n runStartCommand,\n type ConveyorConfig,\n} from \"./setup.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 private setupLog: string[] = [];\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 async start(): Promise<void> {\n await this.callbacks.onStatusChange(\"connecting\");\n await this.connection.connect();\n\n this.connection.onStopRequested(() => {\n this.stopped = true;\n });\n\n this.connection.onChatMessage((message) => {\n this.injectHumanMessage(message.content);\n });\n\n this.connection.sendEvent({\n type: \"connected\",\n taskId: this.config.taskId,\n });\n\n if (process.env.CODESPACES === \"true\") {\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 await this.runProjectSetup();\n }\n\n this.initRtk();\n\n await this.callbacks.onStatusChange(\"fetching_context\");\n const context = await this.connection.fetchTaskContext();\n\n await this.callbacks.onStatusChange(\"running\");\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 async runProjectSetup(): Promise<void> {\n await this.callbacks.onStatusChange(\"setup\");\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;\n }\n\n try {\n await this.executeSetupConfig(config);\n this.connection.sendEvent({ type: \"setup_complete\" });\n await this.callbacks.onEvent({ type: \"setup_complete\" });\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 throw error;\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 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 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 private buildInitialPrompt(context: TaskContext): string {\n const parts: string[] = [];\n const scenario = this.detectRelaunchScenario(context);\n\n // When resuming a session, the context is already in the session history —\n // just inject a brief orientation message.\n if (context.claudeSessionId && scenario !== \"fresh\") {\n 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.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 // For fresh PM scenarios, provide minimal context and explicitly wait for user input\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 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 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 (_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 \"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 // PM mode gets update_task tool; task mode gets create_pull_request\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 // Suppress unused warning — context used by callers for session ID\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<void> {\n const startTime = Date.now();\n let totalCostUsd = 0;\n let sessionIdStored = false;\n let isTyping = 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 // Send typing start event with 200ms delay (like Cloud PM Agent)\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 break;\n }\n\n case \"result\": {\n // Send typing stop event when processing completes\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 this.connection.sendEvent({\n type: \"completed\",\n summary,\n costUsd: totalCostUsd,\n durationMs,\n });\n\n // Track spending if cost information is available and we have an agent ID\n if (totalCostUsd > 0 && context.agentId) {\n // For now, estimate token usage from cost since SDK doesn't provide detailed breakdown\n // We'll use the agent's default model to reverse-calculate approximate tokens\n // Rough estimation: assume average token cost and split evenly between input/output\n // This is a temporary solution until we can get actual token counts from SDK\n const estimatedTotalTokens = Math.round(totalCostUsd * 100000); // Very rough estimate\n const estimatedInputTokens = Math.round(estimatedTotalTokens * 0.7); // 70% input\n const estimatedOutputTokens = Math.round(estimatedTotalTokens * 0.3); // 30% output\n\n this.connection.trackSpending({\n agentId: context.agentId,\n inputTokens: estimatedInputTokens,\n outputTokens: estimatedOutputTokens,\n totalTokens: estimatedTotalTokens,\n totalCostUsd,\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 this.connection.sendEvent({ type: \"error\", message: errorMsg });\n await this.callbacks.onEvent({ type: \"error\", message: errorMsg });\n }\n break;\n }\n }\n }\n\n // Ensure typing stops when processing ends\n if (isTyping) {\n this.connection.sendTypingStop();\n }\n }\n\n // oxlint-disable-next-line max-lines-per-function\n private async executeTask(context: TaskContext): 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 commonOptions = {\n model,\n systemPrompt,\n settingSources,\n cwd: this.config.workspaceDir,\n permissionMode: \"bypassPermissions\" as const,\n allowDangerouslySkipPermissions: true,\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 ?? 25,\n disallowedTools: disallowedTools.length > 0 ? disallowedTools : undefined,\n enableFileCheckpointing: settings.enableFileCheckpointing,\n };\n\n const initialPrompt = this.buildInitialPrompt(context);\n const agentQuery = query({\n prompt: this.createInputStream(initialPrompt),\n options: {\n ...commonOptions,\n resume: context.claudeSessionId ?? undefined,\n },\n });\n\n try {\n await this.processEvents(agentQuery, context);\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 freshPrompt = this.buildInitialPrompt({ ...context, claudeSessionId: null });\n const freshQuery = query({\n prompt: this.createInputStream(freshPrompt),\n options: { ...commonOptions, resume: undefined },\n });\n await this.processEvents(freshQuery, context);\n } else {\n throw error;\n }\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":[]}
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  AgentRunner
4
- } from "./chunk-ZLMVQCVF.js";
4
+ } from "./chunk-LMPNKQJE.js";
5
5
 
6
6
  // src/cli.ts
7
7
  var CONVEYOR_API_URL = process.env.CONVEYOR_API_URL;
package/dist/index.d.ts CHANGED
@@ -100,6 +100,10 @@ type AgentEvent = {
100
100
  type: "start_command_output";
101
101
  stream: "stdout" | "stderr";
102
102
  data: string;
103
+ } | {
104
+ type: "agent_typing_start";
105
+ } | {
106
+ type: "agent_typing_stop";
103
107
  };
104
108
  interface ActivityEventSummary {
105
109
  tool: string;
@@ -179,6 +183,8 @@ declare class ConveyorConnection {
179
183
  totalTokens: number;
180
184
  totalCostUsd: number;
181
185
  }): void;
186
+ sendTypingStart(): void;
187
+ sendTypingStop(): void;
182
188
  disconnect(): void;
183
189
  }
184
190
 
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  loadConveyorConfig,
5
5
  runSetupCommand,
6
6
  runStartCommand
7
- } from "./chunk-ZLMVQCVF.js";
7
+ } from "./chunk-LMPNKQJE.js";
8
8
  export {
9
9
  AgentRunner,
10
10
  ConveyorConnection,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rallycry/conveyor-agent",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Conveyor cloud build agent runner - executes task plans inside GitHub Codespaces",
5
5
  "keywords": [
6
6
  "agent",
@@ -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\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 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.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 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.socket?.on(\"agentRunner:incomingMessage\", callback);\n }\n\n onStopRequested(callback: () => void): void {\n this.socket?.on(\"agentRunner:stop\", callback);\n }\n\n trackSpending(params: {\n agentId: string;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n totalCostUsd: number;\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 disconnect(): void {\n this.flushEvents();\n this.socket?.disconnect();\n this.socket = null;\n }\n}\n","import { 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","// oxlint-disable max-lines\nimport { execSync } from \"node:child_process\";\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\";\nimport {\n loadConveyorConfig,\n loadForwardPorts,\n runSetupCommand,\n runStartCommand,\n type ConveyorConfig,\n} from \"./setup.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 private setupLog: string[] = [];\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 async start(): Promise<void> {\n await this.callbacks.onStatusChange(\"connecting\");\n await this.connection.connect();\n\n this.connection.onStopRequested(() => {\n this.stopped = true;\n });\n\n this.connection.onChatMessage((message) => {\n this.injectHumanMessage(message.content);\n });\n\n this.connection.sendEvent({\n type: \"connected\",\n taskId: this.config.taskId,\n });\n\n if (process.env.CODESPACES === \"true\") {\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 await this.runProjectSetup();\n }\n\n this.initRtk();\n\n await this.callbacks.onStatusChange(\"fetching_context\");\n const context = await this.connection.fetchTaskContext();\n\n await this.callbacks.onStatusChange(\"running\");\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 async runProjectSetup(): Promise<void> {\n await this.callbacks.onStatusChange(\"setup\");\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;\n }\n\n try {\n await this.executeSetupConfig(config);\n this.connection.sendEvent({ type: \"setup_complete\" });\n await this.callbacks.onEvent({ type: \"setup_complete\" });\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 throw error;\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 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 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 private buildInitialPrompt(context: TaskContext): string {\n const parts: string[] = [];\n const scenario = this.detectRelaunchScenario(context);\n\n // When resuming a session, the context is already in the session history —\n // just inject a brief orientation message.\n if (context.claudeSessionId && scenario !== \"fresh\") {\n 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.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. Help the team plan and refine it.`,\n `You have access to the repository — read files to understand the codebase before writing the plan.`,\n `When the plan is complete and ready, use the update_task tool to save it and update_task_status to move the task to \"Open\".`,\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 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 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 (_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 \"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 // PM mode gets update_task tool; task mode gets create_pull_request\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 // Suppress unused warning — context used by callers for session ID\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<void> {\n const startTime = Date.now();\n let totalCostUsd = 0;\n let sessionIdStored = 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 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 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 (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 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 // Track spending if cost information is available and we have an agent ID\n if (totalCostUsd > 0 && context.agentId) {\n // For now, estimate token usage from cost since SDK doesn't provide detailed breakdown\n // We'll use the agent's default model to reverse-calculate approximate tokens\n // Rough estimation: assume average token cost and split evenly between input/output\n // This is a temporary solution until we can get actual token counts from SDK\n const estimatedTotalTokens = Math.round(totalCostUsd * 100000); // Very rough estimate\n const estimatedInputTokens = Math.round(estimatedTotalTokens * 0.7); // 70% input\n const estimatedOutputTokens = Math.round(estimatedTotalTokens * 0.3); // 30% output\n\n this.connection.trackSpending({\n agentId: context.agentId,\n inputTokens: estimatedInputTokens,\n outputTokens: estimatedOutputTokens,\n totalTokens: estimatedTotalTokens,\n totalCostUsd,\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 this.connection.sendEvent({ type: \"error\", message: errorMsg });\n await this.callbacks.onEvent({ type: \"error\", message: errorMsg });\n }\n break;\n }\n }\n }\n }\n\n // oxlint-disable-next-line max-lines-per-function\n private async executeTask(context: TaskContext): 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 commonOptions = {\n model,\n systemPrompt,\n settingSources,\n cwd: this.config.workspaceDir,\n permissionMode: \"bypassPermissions\" as const,\n allowDangerouslySkipPermissions: true,\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 ?? 25,\n disallowedTools: disallowedTools.length > 0 ? disallowedTools : undefined,\n enableFileCheckpointing: settings.enableFileCheckpointing,\n };\n\n const initialPrompt = this.buildInitialPrompt(context);\n const agentQuery = query({\n prompt: this.createInputStream(initialPrompt),\n options: {\n ...commonOptions,\n resume: context.claudeSessionId ?? undefined,\n },\n });\n\n try {\n await this.processEvents(agentQuery, context);\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 freshPrompt = this.buildInitialPrompt({ ...context, claudeSessionId: null });\n const freshQuery = query({\n prompt: this.createInputStream(freshPrompt),\n options: { ...commonOptions, resume: undefined },\n });\n await this.processEvents(freshQuery, context);\n } else {\n throw error;\n }\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":[]}