@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.
- package/dist/chunk-CYZPFJGN.js +26 -0
- package/dist/chunk-CYZPFJGN.js.map +1 -0
- package/dist/chunk-KNBG2634.js +51 -0
- package/dist/chunk-KNBG2634.js.map +1 -0
- package/dist/{chunk-X7YUWDZ2.js → chunk-NZ3IPMLO.js} +105 -112
- package/dist/chunk-NZ3IPMLO.js.map +1 -0
- package/dist/cli.js +5 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/tag-audit-handler-4RRGIHVB.js +184 -0
- package/dist/tag-audit-handler-4RRGIHVB.js.map +1 -0
- package/dist/tunnel-client.d.ts +1 -0
- package/dist/tunnel-client.js +212 -0
- package/dist/tunnel-client.js.map +1 -0
- package/package.json +5 -2
- package/dist/chunk-X7YUWDZ2.js.map +0 -1
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
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
|
-
|
|
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-
|
|
7030
|
+
//# sourceMappingURL=chunk-NZ3IPMLO.js.map
|