@rallycry/conveyor-agent 7.0.0 → 7.0.2

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.
@@ -0,0 +1,26 @@
1
+ // src/utils/logger.ts
2
+ function createServiceLogger(service) {
3
+ const prefix = `[conveyor-agent:${service}]`;
4
+ return {
5
+ info(message, data) {
6
+ const extra = data ? ` ${JSON.stringify(data)}` : "";
7
+ process.stderr.write(`${prefix} ${message}${extra}
8
+ `);
9
+ },
10
+ warn(message, data) {
11
+ const extra = data ? ` ${JSON.stringify(data)}` : "";
12
+ process.stderr.write(`${prefix} WARN ${message}${extra}
13
+ `);
14
+ },
15
+ error(message, data) {
16
+ const extra = data ? ` ${JSON.stringify(data)}` : "";
17
+ process.stderr.write(`${prefix} ERROR ${message}${extra}
18
+ `);
19
+ }
20
+ };
21
+ }
22
+
23
+ export {
24
+ createServiceLogger
25
+ };
26
+ //# sourceMappingURL=chunk-CYZPFJGN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/logger.ts"],"sourcesContent":["/** Minimal structured logger for conveyor-agent (writes to stderr). */\nexport function createServiceLogger(service: string) {\n const prefix = `[conveyor-agent:${service}]`;\n return {\n info(message: string, data?: Record<string, unknown>): void {\n const extra = data ? ` ${JSON.stringify(data)}` : \"\";\n process.stderr.write(`${prefix} ${message}${extra}\\n`);\n },\n warn(message: string, data?: Record<string, unknown>): void {\n const extra = data ? ` ${JSON.stringify(data)}` : \"\";\n process.stderr.write(`${prefix} WARN ${message}${extra}\\n`);\n },\n error(message: string, data?: Record<string, unknown>): void {\n const extra = data ? ` ${JSON.stringify(data)}` : \"\";\n process.stderr.write(`${prefix} ERROR ${message}${extra}\\n`);\n },\n };\n}\n"],"mappings":";AACO,SAAS,oBAAoB,SAAiB;AACnD,QAAM,SAAS,mBAAmB,OAAO;AACzC,SAAO;AAAA,IACL,KAAK,SAAiB,MAAsC;AAC1D,YAAM,QAAQ,OAAO,IAAI,KAAK,UAAU,IAAI,CAAC,KAAK;AAClD,cAAQ,OAAO,MAAM,GAAG,MAAM,IAAI,OAAO,GAAG,KAAK;AAAA,CAAI;AAAA,IACvD;AAAA,IACA,KAAK,SAAiB,MAAsC;AAC1D,YAAM,QAAQ,OAAO,IAAI,KAAK,UAAU,IAAI,CAAC,KAAK;AAClD,cAAQ,OAAO,MAAM,GAAG,MAAM,SAAS,OAAO,GAAG,KAAK;AAAA,CAAI;AAAA,IAC5D;AAAA,IACA,MAAM,SAAiB,MAAsC;AAC3D,YAAM,QAAQ,OAAO,IAAI,KAAK,UAAU,IAAI,CAAC,KAAK;AAClD,cAAQ,OAAO,MAAM,GAAG,MAAM,UAAU,OAAO,GAAG,KAAK;AAAA,CAAI;AAAA,IAC7D;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,51 @@
1
+ // src/harness/types.ts
2
+ function defineTool(name, description, schema, handler, options) {
3
+ return {
4
+ name,
5
+ description,
6
+ schema,
7
+ handler,
8
+ annotations: options?.annotations
9
+ };
10
+ }
11
+
12
+ // src/harness/claude-code/index.ts
13
+ import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
14
+ var ClaudeCodeHarness = class {
15
+ async *executeQuery(opts) {
16
+ const sdkEvents = query({
17
+ prompt: opts.prompt,
18
+ options: {
19
+ ...opts.options,
20
+ ...opts.resume ? { resume: opts.resume } : {},
21
+ ...opts.options.abortController ? { abortController: opts.options.abortController } : {}
22
+ }
23
+ });
24
+ for await (const event of sdkEvents) {
25
+ yield event;
26
+ }
27
+ }
28
+ createMcpServer(config) {
29
+ const sdkTools = config.tools.map(
30
+ (t) => tool(
31
+ t.name,
32
+ t.description,
33
+ t.schema,
34
+ t.handler,
35
+ t.annotations ? { annotations: t.annotations } : void 0
36
+ )
37
+ );
38
+ return createSdkMcpServer({ name: config.name, tools: sdkTools });
39
+ }
40
+ };
41
+
42
+ // src/harness/index.ts
43
+ function createHarness() {
44
+ return new ClaudeCodeHarness();
45
+ }
46
+
47
+ export {
48
+ defineTool,
49
+ createHarness
50
+ };
51
+ //# sourceMappingURL=chunk-KNBG2634.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/harness/types.ts","../src/harness/claude-code/index.ts","../src/harness/index.ts"],"sourcesContent":["/**\n * Harness-neutral types for agent query execution.\n *\n * These types abstract the underlying agent SDK so that the runner,\n * execution, and tool layers never reference SDK-specific imports\n * directly. The only place that should import from\n * `@anthropic-ai/claude-agent-sdk` is `harness/claude-code/`.\n */\n\nimport type { z } from \"zod\";\n\n// ── Events emitted by the harness during a query ────────────────────────\n\nexport interface HarnessSystemInitEvent {\n type: \"system\";\n subtype: \"init\";\n session_id?: string;\n model: string;\n}\n\nexport interface HarnessCompactBoundaryEvent {\n type: \"system\";\n subtype: \"compact_boundary\";\n compact_metadata: { trigger: \"manual\" | \"auto\"; pre_tokens: number };\n}\n\nexport interface HarnessTaskStartedEvent {\n type: \"system\";\n subtype: \"task_started\";\n task_id: string;\n description: string;\n}\n\nexport interface HarnessTaskProgressEvent {\n type: \"system\";\n subtype: \"task_progress\";\n task_id: string;\n description: string;\n usage?: { tool_uses: number; duration_ms: number };\n}\n\nexport type HarnessSystemEvent =\n | HarnessSystemInitEvent\n | HarnessCompactBoundaryEvent\n | HarnessTaskStartedEvent\n | HarnessTaskProgressEvent;\n\nexport interface HarnessContentBlock {\n type: string;\n text?: string;\n name?: string;\n input?: unknown;\n id?: string;\n}\n\nexport interface HarnessAssistantEvent {\n type: \"assistant\";\n message: {\n role: \"assistant\";\n content: HarnessContentBlock[];\n usage?: {\n input_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n };\n}\n\nexport interface HarnessResultSuccessEvent {\n type: \"result\";\n subtype: \"success\";\n result: string;\n total_cost_usd: number;\n modelUsage?: Record<string, unknown>;\n sessionId?: string;\n}\n\nexport interface HarnessResultErrorEvent {\n type: \"result\";\n subtype: \"error\";\n errors: string[];\n sessionId?: string;\n}\n\nexport type HarnessResultEvent = HarnessResultSuccessEvent | HarnessResultErrorEvent;\n\nexport interface HarnessRateLimitEvent {\n type: \"rate_limit_event\";\n rate_limit_info: {\n status: string;\n rateLimitType?: string;\n utilization?: number;\n resetsAt?: unknown;\n };\n}\n\nexport interface HarnessToolProgressEvent {\n type: \"tool_progress\";\n tool_name?: string;\n elapsed_time_seconds?: number;\n}\n\nexport type HarnessEvent =\n | HarnessSystemEvent\n | HarnessAssistantEvent\n | HarnessResultEvent\n | HarnessRateLimitEvent\n | HarnessToolProgressEvent;\n\n// ── User message fed into a query ───────────────────────────────────────\n\nexport interface HarnessUserMessage {\n type: \"user\";\n session_id: string;\n message: { role: \"user\"; content: string | unknown[] };\n parent_tool_use_id: null;\n}\n\n// ── Tool definition (harness-neutral) ───────────────────────────────────\n\nexport interface HarnessToolAnnotations {\n readOnlyHint?: boolean;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any -- generic tool handler */\nexport interface HarnessToolDefinition {\n name: string;\n description: string;\n schema: z.ZodRawShape;\n handler: (\n input: any,\n ) => Promise<{ content: { type: string; text?: string; data?: string; mimeType?: string }[] }>;\n annotations?: HarnessToolAnnotations;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n// ── Hook types ──────────────────────────────────────────────────────────\n\nexport interface HarnessHookInput {\n hook_event_name: string;\n tool_name: string;\n tool_response: unknown;\n}\n\nexport interface HarnessHookOutput {\n continue: boolean;\n}\n\nexport type HarnessPostToolUseHook = (input: HarnessHookInput) => Promise<HarnessHookOutput>;\n\n// ── MCP server handle (opaque to the runner) ────────────────────────────\n\n/** Opaque handle returned by `AgentHarness.createMcpServer()`. */\nexport type HarnessMcpServer = unknown;\n\n// ── Query options ───────────────────────────────────────────────────────\n\nexport interface HarnessQueryOptions {\n model: string;\n systemPrompt: unknown;\n cwd: string;\n permissionMode: \"plan\" | \"bypassPermissions\";\n allowDangerouslySkipPermissions: boolean;\n tools: { type: \"preset\"; preset: \"claude_code\" };\n mcpServers: Record<string, HarnessMcpServer>;\n settingSources?: (\"user\" | \"project\" | \"local\")[];\n sandbox?: { enabled: boolean };\n maxTurns?: number;\n maxBudgetUsd?: number;\n effort?: string;\n thinking?: unknown;\n betas?: unknown;\n disallowedTools?: string[];\n abortController?: AbortController;\n enableFileCheckpointing?: boolean;\n canUseTool?: (\n toolName: string,\n input: Record<string, unknown>,\n ) => Promise<\n | { behavior: \"allow\"; updatedInput?: Record<string, unknown> }\n | { behavior: \"deny\"; message: string }\n >;\n hooks?: Record<string, { hooks: HarnessPostToolUseHook[]; timeout: number }[]>;\n resume?: string;\n stderr?: (data: string) => void;\n}\n\n// ── Tool definition helper ──────────────────────────────────────────────\n\n/**\n * Construct a `HarnessToolDefinition` with the same signature as the SDK's\n * `tool()` helper, but without importing the SDK. The harness implementation\n * converts these into SDK-native tools when `createMcpServer()` is called.\n */\nexport function defineTool<T extends z.ZodRawShape>(\n name: string,\n description: string,\n schema: T,\n handler: (\n input: z.infer<z.ZodObject<T>>,\n ) => Promise<{ content: { type: string; text?: string; data?: string; mimeType?: string }[] }>,\n options?: { annotations?: HarnessToolAnnotations },\n): HarnessToolDefinition {\n return {\n name,\n description,\n schema,\n handler: handler as HarnessToolDefinition[\"handler\"],\n annotations: options?.annotations,\n };\n}\n\n// ── AgentHarness interface ──────────────────────────────────────────────\n\nexport interface AgentHarness {\n /** Start a streaming query and return an async generator of events. */\n executeQuery(options: {\n prompt: string | AsyncGenerator<HarnessUserMessage, void, unknown>;\n options: HarnessQueryOptions;\n resume?: string;\n }): AsyncGenerator<HarnessEvent, void>;\n\n /** Wrap an array of harness-neutral tool definitions into an MCP server. */\n createMcpServer(config: { name: string; tools: HarnessToolDefinition[] }): HarnessMcpServer;\n}\n","/**\n * ClaudeCodeHarness — wraps `@anthropic-ai/claude-agent-sdk` behind the\n * generic `AgentHarness` interface.\n *\n * This is the ONLY module that should import from the SDK.\n */\n\nimport { query, tool, createSdkMcpServer } from \"@anthropic-ai/claude-agent-sdk\";\nimport type {\n AgentHarness,\n HarnessEvent,\n HarnessQueryOptions,\n HarnessToolDefinition,\n HarnessMcpServer,\n HarnessUserMessage,\n} from \"../types.js\";\n\nexport class ClaudeCodeHarness implements AgentHarness {\n async *executeQuery(opts: {\n prompt: string | AsyncGenerator<HarnessUserMessage, void, unknown>;\n options: HarnessQueryOptions;\n resume?: string;\n }): AsyncGenerator<HarnessEvent, void> {\n const sdkEvents = query({\n prompt: opts.prompt as Parameters<typeof query>[0][\"prompt\"],\n options: {\n ...(opts.options as Parameters<typeof query>[0][\"options\"]),\n ...(opts.resume ? { resume: opts.resume } : {}),\n ...(opts.options.abortController ? { abortController: opts.options.abortController } : {}),\n },\n });\n\n for await (const event of sdkEvents) {\n yield event as unknown as HarnessEvent;\n }\n }\n\n createMcpServer(config: { name: string; tools: HarnessToolDefinition[] }): HarnessMcpServer {\n const sdkTools = config.tools.map((t) =>\n tool(\n t.name,\n t.description,\n t.schema,\n t.handler as Parameters<typeof tool>[3],\n t.annotations ? { annotations: t.annotations } : undefined,\n ),\n );\n return createSdkMcpServer({ name: config.name, tools: sdkTools });\n }\n}\n","export { defineTool } from \"./types.js\";\n\nexport type {\n AgentHarness,\n HarnessEvent,\n HarnessSystemEvent,\n HarnessSystemInitEvent,\n HarnessCompactBoundaryEvent,\n HarnessTaskStartedEvent,\n HarnessTaskProgressEvent,\n HarnessAssistantEvent,\n HarnessContentBlock,\n HarnessResultEvent,\n HarnessResultSuccessEvent,\n HarnessResultErrorEvent,\n HarnessRateLimitEvent,\n HarnessToolProgressEvent,\n HarnessUserMessage,\n HarnessToolDefinition,\n HarnessToolAnnotations,\n HarnessMcpServer,\n HarnessQueryOptions,\n HarnessHookInput,\n HarnessHookOutput,\n HarnessPostToolUseHook,\n} from \"./types.js\";\n\nexport { ClaudeCodeHarness } from \"./claude-code/index.js\";\n\nimport { ClaudeCodeHarness } from \"./claude-code/index.js\";\nimport type { AgentHarness } from \"./types.js\";\n\nexport function createHarness(): AgentHarness {\n return new ClaudeCodeHarness();\n}\n"],"mappings":";AAkMO,SAAS,WACd,MACA,aACA,QACA,SAGA,SACuB;AACvB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,SAAS;AAAA,EACxB;AACF;;;AC3MA,SAAS,OAAO,MAAM,0BAA0B;AAUzC,IAAM,oBAAN,MAAgD;AAAA,EACrD,OAAO,aAAa,MAImB;AACrC,UAAM,YAAY,MAAM;AAAA,MACtB,QAAQ,KAAK;AAAA,MACb,SAAS;AAAA,QACP,GAAI,KAAK;AAAA,QACT,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,QAC7C,GAAI,KAAK,QAAQ,kBAAkB,EAAE,iBAAiB,KAAK,QAAQ,gBAAgB,IAAI,CAAC;AAAA,MAC1F;AAAA,IACF,CAAC;AAED,qBAAiB,SAAS,WAAW;AACnC,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,gBAAgB,QAA4E;AAC1F,UAAM,WAAW,OAAO,MAAM;AAAA,MAAI,CAAC,MACjC;AAAA,QACE,EAAE;AAAA,QACF,EAAE;AAAA,QACF,EAAE;AAAA,QACF,EAAE;AAAA,QACF,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,IAAI;AAAA,MACnD;AAAA,IACF;AACA,WAAO,mBAAmB,EAAE,MAAM,OAAO,MAAM,OAAO,SAAS,CAAC;AAAA,EAClE;AACF;;;ACjBO,SAAS,gBAA8B;AAC5C,SAAO,IAAI,kBAAkB;AAC/B;","names":[]}
@@ -1,3 +1,11 @@
1
+ import {
2
+ createHarness,
3
+ defineTool
4
+ } from "./chunk-KNBG2634.js";
5
+ import {
6
+ createServiceLogger
7
+ } from "./chunk-CYZPFJGN.js";
8
+
1
9
  // src/connection/agent-connection.ts
2
10
  import { io } from "socket.io-client";
3
11
  var EVENT_BATCH_MS = 500;
@@ -133,7 +141,17 @@ var AgentConnection = class {
133
141
  });
134
142
  this.socket.io.on("reconnect", () => {
135
143
  process.stderr.write("[conveyor-agent] Reconnected\n");
136
- void this.call("connectAgent", { sessionId: this.config.sessionId }).catch(() => {
144
+ this.call("connectAgent", { sessionId: this.config.sessionId }).then(({ pendingMessages }) => {
145
+ for (const msg of pendingMessages) {
146
+ if (msg.content) {
147
+ if (this.messageCallback) {
148
+ this.messageCallback({ content: msg.content, userId: msg.userId });
149
+ } else {
150
+ this.earlyMessages.push({ content: msg.content, userId: msg.userId });
151
+ }
152
+ }
153
+ }
154
+ }).catch(() => {
137
155
  });
138
156
  if (this.lastEmittedStatus) {
139
157
  void this.call("reportAgentStatus", {
@@ -280,14 +298,13 @@ var AgentConnection = class {
280
298
  (q) => `**${q.header}**
281
299
  ${q.question}${q.options.length ? "\n" + q.options.map((o) => `- ${o.label}: ${o.description}`).join("\n") : ""}`
282
300
  ).join("\n\n");
283
- const { answer } = await this.call("askUserQuestion", {
301
+ const requestId = crypto.randomUUID();
302
+ const { answers } = await this.call("askUserQuestion", {
284
303
  sessionId: this.config.sessionId,
285
- question: questionText
304
+ question: questionText,
305
+ requestId,
306
+ questions
286
307
  });
287
- const answers = {};
288
- for (const q of questions) {
289
- answers[q.header] = answer;
290
- }
291
308
  return answers;
292
309
  }
293
310
  // ── Typed service method wrappers ───────────────────────────────────
@@ -544,28 +561,6 @@ var Lifecycle = class {
544
561
  }
545
562
  };
546
563
 
547
- // src/utils/logger.ts
548
- function createServiceLogger(service) {
549
- const prefix = `[conveyor-agent:${service}]`;
550
- return {
551
- info(message, data) {
552
- const extra = data ? ` ${JSON.stringify(data)}` : "";
553
- process.stderr.write(`${prefix} ${message}${extra}
554
- `);
555
- },
556
- warn(message, data) {
557
- const extra = data ? ` ${JSON.stringify(data)}` : "";
558
- process.stderr.write(`${prefix} WARN ${message}${extra}
559
- `);
560
- },
561
- error(message, data) {
562
- const extra = data ? ` ${JSON.stringify(data)}` : "";
563
- process.stderr.write(`${prefix} ERROR ${message}${extra}
564
- `);
565
- }
566
- };
567
- }
568
-
569
564
  // src/runner/git-utils.ts
570
565
  import { execSync } from "child_process";
571
566
  function hasUncommittedChanges(cwd) {
@@ -773,52 +768,6 @@ var PlanSync = class {
773
768
  }
774
769
  };
775
770
 
776
- // src/harness/types.ts
777
- function defineTool(name, description, schema, handler, options) {
778
- return {
779
- name,
780
- description,
781
- schema,
782
- handler,
783
- annotations: options?.annotations
784
- };
785
- }
786
-
787
- // src/harness/claude-code/index.ts
788
- import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
789
- var ClaudeCodeHarness = class {
790
- async *executeQuery(opts) {
791
- const sdkEvents = query({
792
- prompt: opts.prompt,
793
- options: {
794
- ...opts.options,
795
- ...opts.resume ? { resume: opts.resume } : {},
796
- ...opts.options.abortController ? { abortController: opts.options.abortController } : {}
797
- }
798
- });
799
- for await (const event of sdkEvents) {
800
- yield event;
801
- }
802
- }
803
- createMcpServer(config) {
804
- const sdkTools = config.tools.map(
805
- (t) => tool(
806
- t.name,
807
- t.description,
808
- t.schema,
809
- t.handler,
810
- t.annotations ? { annotations: t.annotations } : void 0
811
- )
812
- );
813
- return createSdkMcpServer({ name: config.name, tools: sdkTools });
814
- }
815
- };
816
-
817
- // src/harness/index.ts
818
- function createHarness() {
819
- return new ClaudeCodeHarness();
820
- }
821
-
822
771
  // src/execution/pack-runner-prompt.ts
823
772
  function findLastAgentMessageIndex(history) {
824
773
  for (let i = history.length - 1; i >= 0; i--) {
@@ -1210,8 +1159,7 @@ function buildAutoPrompt(context) {
1210
1159
  `You are in Auto mode \u2014 operating autonomously through planning \u2192 building \u2192 PR.`,
1211
1160
  ``,
1212
1161
  `### Phase 1: Discovery & Planning (current)`,
1213
- `- You have read-only codebase access (can read files, run git commands, search code)`,
1214
- `- You can write plan files in .claude/plans/ only \u2014 no other file writes`,
1162
+ `- You are in the SDK's plan mode \u2014 read-only access is enforced automatically`,
1215
1163
  `- You have MCP tools for task properties: update_task, update_task_properties`,
1216
1164
  ``,
1217
1165
  `### Required before transitioning:`,
@@ -2335,7 +2283,16 @@ Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>`;
2335
2283
  }
2336
2284
  }
2337
2285
  if (hasUnpushedCommits(cwd)) {
2338
- const pushSuccess = await pushToOrigin(cwd);
2286
+ const pushSuccess = await pushToOrigin(cwd, async () => {
2287
+ try {
2288
+ const result2 = await connection.call("refreshGithubToken", {
2289
+ sessionId: connection.sessionId
2290
+ });
2291
+ return result2.token;
2292
+ } catch {
2293
+ return void 0;
2294
+ }
2295
+ });
2339
2296
  if (pushSuccess) {
2340
2297
  connection.sendEvent({
2341
2298
  type: "message",
@@ -4697,15 +4654,6 @@ function handleAutoToolAccess(toolName, input, hasExitedPlanMode, isParentTask)
4697
4654
  if (hasExitedPlanMode) {
4698
4655
  return isParentTask ? handleReviewToolAccess(toolName, input, true) : handleBuildingToolAccess(toolName, input);
4699
4656
  }
4700
- if (PM_PLAN_FILE_TOOLS.has(toolName)) {
4701
- if (isPlanFile(input)) {
4702
- return { behavior: "allow", updatedInput: input };
4703
- }
4704
- return {
4705
- behavior: "deny",
4706
- message: "You are in auto plan mode. File writes are restricted to plan files. Call ExitPlanMode when your plan is ready to start building."
4707
- };
4708
- }
4709
4657
  return { behavior: "allow", updatedInput: input };
4710
4658
  }
4711
4659
  async function handleExitPlanMode(host, input) {
@@ -4766,7 +4714,7 @@ async function handleAskUserQuestion(host, input) {
4766
4714
  });
4767
4715
  const answers = await Promise.race([answerPromise, timeoutPromise]);
4768
4716
  host.connection.emitStatus("running");
4769
- if (!answers) {
4717
+ if (!answers || Object.keys(answers).length === 0) {
4770
4718
  return {
4771
4719
  behavior: "deny",
4772
4720
  message: "User did not respond to clarifying questions in time. Proceed with your best judgment."
@@ -5344,6 +5292,7 @@ var SessionRunner = class _SessionRunner {
5344
5292
  callbacks;
5345
5293
  _state = "connecting";
5346
5294
  stopped = false;
5295
+ hasCompleted = false;
5347
5296
  interrupted = false;
5348
5297
  taskContext = null;
5349
5298
  fullContext = null;
@@ -5355,7 +5304,7 @@ var SessionRunner = class _SessionRunner {
5355
5304
  this.config = config;
5356
5305
  this.callbacks = callbacks;
5357
5306
  this.connection = new AgentConnection(config.connection);
5358
- const initialMode = config.agentMode ?? (config.runnerMode === "pm" ? "discovery" : "building");
5307
+ const initialMode = config.agentMode ?? (config.runnerMode === "pm" ? config.isAuto ? "auto" : "discovery" : "building");
5359
5308
  this.mode = new ModeController(initialMode, config.runnerMode, config.isAuto);
5360
5309
  const lifecycleConfig = { ...DEFAULT_LIFECYCLE_CONFIG, ...config.lifecycle };
5361
5310
  this.lifecycle = new Lifecycle(lifecycleConfig, {
@@ -5431,6 +5380,9 @@ var SessionRunner = class _SessionRunner {
5431
5380
  this.queryBridge = this.createQueryBridge();
5432
5381
  this.logInitialization();
5433
5382
  await this.executeInitialMode();
5383
+ if (!this.stopped && this._state !== "error") {
5384
+ this.hasCompleted = true;
5385
+ }
5434
5386
  if (!this.stopped && this.pendingMessages.length === 0) {
5435
5387
  await this.maybeSendPRNudge();
5436
5388
  }
@@ -5460,6 +5412,12 @@ var SessionRunner = class _SessionRunner {
5460
5412
  }
5461
5413
  break;
5462
5414
  }
5415
+ if (this.hasCompleted && msg.userId === "system") {
5416
+ continue;
5417
+ }
5418
+ if (msg.userId !== "system") {
5419
+ this.hasCompleted = false;
5420
+ }
5463
5421
  await this.setState("running");
5464
5422
  this.interrupted = false;
5465
5423
  await this.callbacks.onEvent({
@@ -5635,7 +5593,12 @@ var SessionRunner = class _SessionRunner {
5635
5593
  baseBranch: ctx.baseBranch ?? "",
5636
5594
  githubPRUrl: ctx.githubPRUrl,
5637
5595
  claudeSessionId: ctx.claudeSessionId ?? null,
5638
- isParentTask: !!ctx.parentTaskId
5596
+ isParentTask: !!ctx.parentTaskId,
5597
+ storyPoints: ctx.storyPoints ?? void 0,
5598
+ projectAgents: ctx.projectAgents ?? void 0,
5599
+ projectTags: ctx.projectTags ?? void 0,
5600
+ taskTagIds: ctx.taskTagIds ?? void 0,
5601
+ projectObjectives: ctx.projectObjectives ?? void 0
5639
5602
  };
5640
5603
  }
5641
5604
  createQueryBridge() {
@@ -5834,6 +5797,9 @@ var ProjectConnection = class {
5834
5797
  onRestartStartCommand(callback) {
5835
5798
  this.requireSocket().on("projectRunner:restartStartCommand", callback);
5836
5799
  }
5800
+ onAuditTags(callback) {
5801
+ this.requireSocket().on("projectRunner:auditTags", callback);
5802
+ }
5837
5803
  // ── Outgoing helpers ───────────────────────────────────────────────────
5838
5804
  sendHeartbeat() {
5839
5805
  void this.call("projectRunnerHeartbeat", { projectId: this.config.projectId }).catch(() => {
@@ -6343,21 +6309,24 @@ function buildChatQueryOptions(agentCtx, projectDir, connection) {
6343
6309
  tools: buildProjectTools(connection)
6344
6310
  });
6345
6311
  return {
6346
- model,
6347
- systemPrompt: {
6348
- type: "preset",
6349
- preset: "claude_code",
6350
- append: buildSystemPrompt2(projectDir, agentCtx)
6312
+ options: {
6313
+ model,
6314
+ systemPrompt: {
6315
+ type: "preset",
6316
+ preset: "claude_code",
6317
+ append: buildSystemPrompt2(projectDir, agentCtx)
6318
+ },
6319
+ cwd: projectDir,
6320
+ permissionMode: "bypassPermissions",
6321
+ allowDangerouslySkipPermissions: true,
6322
+ tools: { type: "preset", preset: "claude_code" },
6323
+ mcpServers: { conveyor: mcpServer },
6324
+ maxTurns: settings.maxTurns ?? 30,
6325
+ maxBudgetUsd: settings.maxBudgetUsd ?? 50,
6326
+ effort: settings.effort,
6327
+ thinking: settings.thinking
6351
6328
  },
6352
- cwd: projectDir,
6353
- permissionMode: "bypassPermissions",
6354
- allowDangerouslySkipPermissions: true,
6355
- tools: { type: "preset", preset: "claude_code" },
6356
- mcpServers: { conveyor: mcpServer },
6357
- maxTurns: settings.maxTurns ?? 30,
6358
- maxBudgetUsd: settings.maxBudgetUsd ?? 50,
6359
- effort: settings.effort,
6360
- thinking: settings.thinking
6329
+ harness
6361
6330
  };
6362
6331
  }
6363
6332
  function processContentBlock(block, responseParts, turnToolCalls) {
@@ -6406,10 +6375,9 @@ function emitResultCost(event, connection) {
6406
6375
  }
6407
6376
  async function runChatQuery(message, connection, projectDir, sessionId) {
6408
6377
  const { agentCtx, chatHistory } = await fetchContext(connection, message.chatId);
6409
- const options = buildChatQueryOptions(agentCtx, projectDir, connection);
6378
+ const { options, harness } = buildChatQueryOptions(agentCtx, projectDir, connection);
6410
6379
  const prompt = buildPrompt(message, chatHistory);
6411
6380
  connection.emitStatus("busy");
6412
- const harness = createHarness();
6413
6381
  const events = harness.executeQuery({
6414
6382
  prompt,
6415
6383
  options,
@@ -6434,7 +6402,8 @@ async function runChatQuery(message, connection, projectDir, sessionId) {
6434
6402
  if (responseText) {
6435
6403
  await connection.call("postProjectAgentMessage", {
6436
6404
  projectId: connection.projectId,
6437
- content: responseText
6405
+ content: responseText,
6406
+ chatId: message.chatId
6438
6407
  });
6439
6408
  }
6440
6409
  return resultSessionId;
@@ -6449,7 +6418,8 @@ async function handleProjectChatMessage(message, connection, projectDir, session
6449
6418
  try {
6450
6419
  await connection.call("postProjectAgentMessage", {
6451
6420
  projectId: connection.projectId,
6452
- content: "I encountered an error processing your message. Please try again."
6421
+ content: "I encountered an error processing your message. Please try again.",
6422
+ chatId: message.chatId
6453
6423
  });
6454
6424
  } catch {
6455
6425
  }
@@ -6581,7 +6551,7 @@ var ProjectRunner = class {
6581
6551
  await this.connection.connect();
6582
6552
  const registration = await this.connection.call("registerProjectAgent", {
6583
6553
  projectId: this.connection.projectId,
6584
- capabilities: ["task", "pm", "code-review"]
6554
+ capabilities: ["task", "pm", "code-review", "audit"]
6585
6555
  });
6586
6556
  this.branchSwitchCommand = registration.branchSwitchCommand ?? process.env.CONVEYOR_BRANCH_SWITCH_COMMAND;
6587
6557
  logger6.info("Registered as project agent", { agentName: registration.agentName });
@@ -6666,6 +6636,7 @@ var ProjectRunner = class {
6666
6636
  }
6667
6637
  );
6668
6638
  });
6639
+ this.connection.onAuditTags((request) => void this.handleAuditTags(request));
6669
6640
  this.connection.onSwitchBranch((data, cb) => void this.handleSwitchBranch(data, cb));
6670
6641
  this.connection.onSyncEnvironment((cb) => void this.handleSyncEnvironment(cb));
6671
6642
  this.connection.onRestartStartCommand((cb) => {
@@ -6678,7 +6649,7 @@ var ProjectRunner = class {
6678
6649
  try {
6679
6650
  await this.connection.call("registerProjectAgent", {
6680
6651
  projectId: this.connection.projectId,
6681
- capabilities: ["task", "pm", "code-review"]
6652
+ capabilities: ["task", "pm", "code-review", "audit"]
6682
6653
  });
6683
6654
  this.connection.emitStatus(this.activeAgents.size > 0 ? "busy" : "idle");
6684
6655
  logger6.info("Re-registered after reconnect");
@@ -6687,6 +6658,29 @@ var ProjectRunner = class {
6687
6658
  logger6.error("Failed to re-register after reconnect", { error: msg });
6688
6659
  }
6689
6660
  }
6661
+ // ── Tag audit ──────────────────────────────────────────────────────────
6662
+ async handleAuditTags(request) {
6663
+ this.connection.emitStatus("busy");
6664
+ try {
6665
+ const { handleTagAudit } = await import("./tag-audit-handler-4RRGIHVB.js");
6666
+ await handleTagAudit(request, this.connection, this.projectDir);
6667
+ } catch (error) {
6668
+ const msg = error instanceof Error ? error.message : String(error);
6669
+ logger6.error("Tag audit failed", { error: msg, requestId: request.requestId });
6670
+ try {
6671
+ await this.connection.call("reportTagAuditResult", {
6672
+ projectId: this.connection.projectId,
6673
+ requestId: request.requestId,
6674
+ recommendations: [],
6675
+ summary: `Audit failed: ${msg}`,
6676
+ complete: true
6677
+ });
6678
+ } catch {
6679
+ }
6680
+ } finally {
6681
+ this.connection.emitStatus("idle");
6682
+ }
6683
+ }
6690
6684
  // ── Task management ────────────────────────────────────────────────────
6691
6685
  handleAssignment(assignment) {
6692
6686
  const { taskId, mode } = assignment;
@@ -7014,7 +7008,6 @@ export {
7014
7008
  ModeController,
7015
7009
  DEFAULT_LIFECYCLE_CONFIG,
7016
7010
  Lifecycle,
7017
- createServiceLogger,
7018
7011
  hasUncommittedChanges,
7019
7012
  getCurrentBranch,
7020
7013
  hasUnpushedCommits,
@@ -7034,4 +7027,4 @@ export {
7034
7027
  removeWorktree,
7035
7028
  ProjectRunner
7036
7029
  };
7037
- //# sourceMappingURL=chunk-X7YUWDZ2.js.map
7030
+ //# sourceMappingURL=chunk-NZ3IPMLO.js.map