@rallycry/conveyor-agent 7.0.1 → 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-HAU4E7IA.js → chunk-NZ3IPMLO.js} +99 -105
- 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-HAU4E7IA.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", {
|
|
@@ -543,28 +561,6 @@ var Lifecycle = class {
|
|
|
543
561
|
}
|
|
544
562
|
};
|
|
545
563
|
|
|
546
|
-
// src/utils/logger.ts
|
|
547
|
-
function createServiceLogger(service) {
|
|
548
|
-
const prefix = `[conveyor-agent:${service}]`;
|
|
549
|
-
return {
|
|
550
|
-
info(message, data) {
|
|
551
|
-
const extra = data ? ` ${JSON.stringify(data)}` : "";
|
|
552
|
-
process.stderr.write(`${prefix} ${message}${extra}
|
|
553
|
-
`);
|
|
554
|
-
},
|
|
555
|
-
warn(message, data) {
|
|
556
|
-
const extra = data ? ` ${JSON.stringify(data)}` : "";
|
|
557
|
-
process.stderr.write(`${prefix} WARN ${message}${extra}
|
|
558
|
-
`);
|
|
559
|
-
},
|
|
560
|
-
error(message, data) {
|
|
561
|
-
const extra = data ? ` ${JSON.stringify(data)}` : "";
|
|
562
|
-
process.stderr.write(`${prefix} ERROR ${message}${extra}
|
|
563
|
-
`);
|
|
564
|
-
}
|
|
565
|
-
};
|
|
566
|
-
}
|
|
567
|
-
|
|
568
564
|
// src/runner/git-utils.ts
|
|
569
565
|
import { execSync } from "child_process";
|
|
570
566
|
function hasUncommittedChanges(cwd) {
|
|
@@ -772,52 +768,6 @@ var PlanSync = class {
|
|
|
772
768
|
}
|
|
773
769
|
};
|
|
774
770
|
|
|
775
|
-
// src/harness/types.ts
|
|
776
|
-
function defineTool(name, description, schema, handler, options) {
|
|
777
|
-
return {
|
|
778
|
-
name,
|
|
779
|
-
description,
|
|
780
|
-
schema,
|
|
781
|
-
handler,
|
|
782
|
-
annotations: options?.annotations
|
|
783
|
-
};
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
// src/harness/claude-code/index.ts
|
|
787
|
-
import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
|
|
788
|
-
var ClaudeCodeHarness = class {
|
|
789
|
-
async *executeQuery(opts) {
|
|
790
|
-
const sdkEvents = query({
|
|
791
|
-
prompt: opts.prompt,
|
|
792
|
-
options: {
|
|
793
|
-
...opts.options,
|
|
794
|
-
...opts.resume ? { resume: opts.resume } : {},
|
|
795
|
-
...opts.options.abortController ? { abortController: opts.options.abortController } : {}
|
|
796
|
-
}
|
|
797
|
-
});
|
|
798
|
-
for await (const event of sdkEvents) {
|
|
799
|
-
yield event;
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
createMcpServer(config) {
|
|
803
|
-
const sdkTools = config.tools.map(
|
|
804
|
-
(t) => tool(
|
|
805
|
-
t.name,
|
|
806
|
-
t.description,
|
|
807
|
-
t.schema,
|
|
808
|
-
t.handler,
|
|
809
|
-
t.annotations ? { annotations: t.annotations } : void 0
|
|
810
|
-
)
|
|
811
|
-
);
|
|
812
|
-
return createSdkMcpServer({ name: config.name, tools: sdkTools });
|
|
813
|
-
}
|
|
814
|
-
};
|
|
815
|
-
|
|
816
|
-
// src/harness/index.ts
|
|
817
|
-
function createHarness() {
|
|
818
|
-
return new ClaudeCodeHarness();
|
|
819
|
-
}
|
|
820
|
-
|
|
821
771
|
// src/execution/pack-runner-prompt.ts
|
|
822
772
|
function findLastAgentMessageIndex(history) {
|
|
823
773
|
for (let i = history.length - 1; i >= 0; i--) {
|
|
@@ -1209,8 +1159,7 @@ function buildAutoPrompt(context) {
|
|
|
1209
1159
|
`You are in Auto mode \u2014 operating autonomously through planning \u2192 building \u2192 PR.`,
|
|
1210
1160
|
``,
|
|
1211
1161
|
`### Phase 1: Discovery & Planning (current)`,
|
|
1212
|
-
`- You
|
|
1213
|
-
`- 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`,
|
|
1214
1163
|
`- You have MCP tools for task properties: update_task, update_task_properties`,
|
|
1215
1164
|
``,
|
|
1216
1165
|
`### Required before transitioning:`,
|
|
@@ -2334,7 +2283,16 @@ Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>`;
|
|
|
2334
2283
|
}
|
|
2335
2284
|
}
|
|
2336
2285
|
if (hasUnpushedCommits(cwd)) {
|
|
2337
|
-
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
|
+
});
|
|
2338
2296
|
if (pushSuccess) {
|
|
2339
2297
|
connection.sendEvent({
|
|
2340
2298
|
type: "message",
|
|
@@ -4696,15 +4654,6 @@ function handleAutoToolAccess(toolName, input, hasExitedPlanMode, isParentTask)
|
|
|
4696
4654
|
if (hasExitedPlanMode) {
|
|
4697
4655
|
return isParentTask ? handleReviewToolAccess(toolName, input, true) : handleBuildingToolAccess(toolName, input);
|
|
4698
4656
|
}
|
|
4699
|
-
if (PM_PLAN_FILE_TOOLS.has(toolName)) {
|
|
4700
|
-
if (isPlanFile(input)) {
|
|
4701
|
-
return { behavior: "allow", updatedInput: input };
|
|
4702
|
-
}
|
|
4703
|
-
return {
|
|
4704
|
-
behavior: "deny",
|
|
4705
|
-
message: "You are in auto plan mode. File writes are restricted to plan files. Call ExitPlanMode when your plan is ready to start building."
|
|
4706
|
-
};
|
|
4707
|
-
}
|
|
4708
4657
|
return { behavior: "allow", updatedInput: input };
|
|
4709
4658
|
}
|
|
4710
4659
|
async function handleExitPlanMode(host, input) {
|
|
@@ -5343,6 +5292,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
5343
5292
|
callbacks;
|
|
5344
5293
|
_state = "connecting";
|
|
5345
5294
|
stopped = false;
|
|
5295
|
+
hasCompleted = false;
|
|
5346
5296
|
interrupted = false;
|
|
5347
5297
|
taskContext = null;
|
|
5348
5298
|
fullContext = null;
|
|
@@ -5354,7 +5304,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
5354
5304
|
this.config = config;
|
|
5355
5305
|
this.callbacks = callbacks;
|
|
5356
5306
|
this.connection = new AgentConnection(config.connection);
|
|
5357
|
-
const initialMode = config.agentMode ?? (config.runnerMode === "pm" ? "discovery" : "building");
|
|
5307
|
+
const initialMode = config.agentMode ?? (config.runnerMode === "pm" ? config.isAuto ? "auto" : "discovery" : "building");
|
|
5358
5308
|
this.mode = new ModeController(initialMode, config.runnerMode, config.isAuto);
|
|
5359
5309
|
const lifecycleConfig = { ...DEFAULT_LIFECYCLE_CONFIG, ...config.lifecycle };
|
|
5360
5310
|
this.lifecycle = new Lifecycle(lifecycleConfig, {
|
|
@@ -5430,6 +5380,9 @@ var SessionRunner = class _SessionRunner {
|
|
|
5430
5380
|
this.queryBridge = this.createQueryBridge();
|
|
5431
5381
|
this.logInitialization();
|
|
5432
5382
|
await this.executeInitialMode();
|
|
5383
|
+
if (!this.stopped && this._state !== "error") {
|
|
5384
|
+
this.hasCompleted = true;
|
|
5385
|
+
}
|
|
5433
5386
|
if (!this.stopped && this.pendingMessages.length === 0) {
|
|
5434
5387
|
await this.maybeSendPRNudge();
|
|
5435
5388
|
}
|
|
@@ -5459,6 +5412,12 @@ var SessionRunner = class _SessionRunner {
|
|
|
5459
5412
|
}
|
|
5460
5413
|
break;
|
|
5461
5414
|
}
|
|
5415
|
+
if (this.hasCompleted && msg.userId === "system") {
|
|
5416
|
+
continue;
|
|
5417
|
+
}
|
|
5418
|
+
if (msg.userId !== "system") {
|
|
5419
|
+
this.hasCompleted = false;
|
|
5420
|
+
}
|
|
5462
5421
|
await this.setState("running");
|
|
5463
5422
|
this.interrupted = false;
|
|
5464
5423
|
await this.callbacks.onEvent({
|
|
@@ -5634,7 +5593,12 @@ var SessionRunner = class _SessionRunner {
|
|
|
5634
5593
|
baseBranch: ctx.baseBranch ?? "",
|
|
5635
5594
|
githubPRUrl: ctx.githubPRUrl,
|
|
5636
5595
|
claudeSessionId: ctx.claudeSessionId ?? null,
|
|
5637
|
-
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
|
|
5638
5602
|
};
|
|
5639
5603
|
}
|
|
5640
5604
|
createQueryBridge() {
|
|
@@ -5833,6 +5797,9 @@ var ProjectConnection = class {
|
|
|
5833
5797
|
onRestartStartCommand(callback) {
|
|
5834
5798
|
this.requireSocket().on("projectRunner:restartStartCommand", callback);
|
|
5835
5799
|
}
|
|
5800
|
+
onAuditTags(callback) {
|
|
5801
|
+
this.requireSocket().on("projectRunner:auditTags", callback);
|
|
5802
|
+
}
|
|
5836
5803
|
// ── Outgoing helpers ───────────────────────────────────────────────────
|
|
5837
5804
|
sendHeartbeat() {
|
|
5838
5805
|
void this.call("projectRunnerHeartbeat", { projectId: this.config.projectId }).catch(() => {
|
|
@@ -6342,21 +6309,24 @@ function buildChatQueryOptions(agentCtx, projectDir, connection) {
|
|
|
6342
6309
|
tools: buildProjectTools(connection)
|
|
6343
6310
|
});
|
|
6344
6311
|
return {
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
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
|
|
6350
6328
|
},
|
|
6351
|
-
|
|
6352
|
-
permissionMode: "bypassPermissions",
|
|
6353
|
-
allowDangerouslySkipPermissions: true,
|
|
6354
|
-
tools: { type: "preset", preset: "claude_code" },
|
|
6355
|
-
mcpServers: { conveyor: mcpServer },
|
|
6356
|
-
maxTurns: settings.maxTurns ?? 30,
|
|
6357
|
-
maxBudgetUsd: settings.maxBudgetUsd ?? 50,
|
|
6358
|
-
effort: settings.effort,
|
|
6359
|
-
thinking: settings.thinking
|
|
6329
|
+
harness
|
|
6360
6330
|
};
|
|
6361
6331
|
}
|
|
6362
6332
|
function processContentBlock(block, responseParts, turnToolCalls) {
|
|
@@ -6405,10 +6375,9 @@ function emitResultCost(event, connection) {
|
|
|
6405
6375
|
}
|
|
6406
6376
|
async function runChatQuery(message, connection, projectDir, sessionId) {
|
|
6407
6377
|
const { agentCtx, chatHistory } = await fetchContext(connection, message.chatId);
|
|
6408
|
-
const options = buildChatQueryOptions(agentCtx, projectDir, connection);
|
|
6378
|
+
const { options, harness } = buildChatQueryOptions(agentCtx, projectDir, connection);
|
|
6409
6379
|
const prompt = buildPrompt(message, chatHistory);
|
|
6410
6380
|
connection.emitStatus("busy");
|
|
6411
|
-
const harness = createHarness();
|
|
6412
6381
|
const events = harness.executeQuery({
|
|
6413
6382
|
prompt,
|
|
6414
6383
|
options,
|
|
@@ -6433,7 +6402,8 @@ async function runChatQuery(message, connection, projectDir, sessionId) {
|
|
|
6433
6402
|
if (responseText) {
|
|
6434
6403
|
await connection.call("postProjectAgentMessage", {
|
|
6435
6404
|
projectId: connection.projectId,
|
|
6436
|
-
content: responseText
|
|
6405
|
+
content: responseText,
|
|
6406
|
+
chatId: message.chatId
|
|
6437
6407
|
});
|
|
6438
6408
|
}
|
|
6439
6409
|
return resultSessionId;
|
|
@@ -6448,7 +6418,8 @@ async function handleProjectChatMessage(message, connection, projectDir, session
|
|
|
6448
6418
|
try {
|
|
6449
6419
|
await connection.call("postProjectAgentMessage", {
|
|
6450
6420
|
projectId: connection.projectId,
|
|
6451
|
-
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
|
|
6452
6423
|
});
|
|
6453
6424
|
} catch {
|
|
6454
6425
|
}
|
|
@@ -6580,7 +6551,7 @@ var ProjectRunner = class {
|
|
|
6580
6551
|
await this.connection.connect();
|
|
6581
6552
|
const registration = await this.connection.call("registerProjectAgent", {
|
|
6582
6553
|
projectId: this.connection.projectId,
|
|
6583
|
-
capabilities: ["task", "pm", "code-review"]
|
|
6554
|
+
capabilities: ["task", "pm", "code-review", "audit"]
|
|
6584
6555
|
});
|
|
6585
6556
|
this.branchSwitchCommand = registration.branchSwitchCommand ?? process.env.CONVEYOR_BRANCH_SWITCH_COMMAND;
|
|
6586
6557
|
logger6.info("Registered as project agent", { agentName: registration.agentName });
|
|
@@ -6665,6 +6636,7 @@ var ProjectRunner = class {
|
|
|
6665
6636
|
}
|
|
6666
6637
|
);
|
|
6667
6638
|
});
|
|
6639
|
+
this.connection.onAuditTags((request) => void this.handleAuditTags(request));
|
|
6668
6640
|
this.connection.onSwitchBranch((data, cb) => void this.handleSwitchBranch(data, cb));
|
|
6669
6641
|
this.connection.onSyncEnvironment((cb) => void this.handleSyncEnvironment(cb));
|
|
6670
6642
|
this.connection.onRestartStartCommand((cb) => {
|
|
@@ -6677,7 +6649,7 @@ var ProjectRunner = class {
|
|
|
6677
6649
|
try {
|
|
6678
6650
|
await this.connection.call("registerProjectAgent", {
|
|
6679
6651
|
projectId: this.connection.projectId,
|
|
6680
|
-
capabilities: ["task", "pm", "code-review"]
|
|
6652
|
+
capabilities: ["task", "pm", "code-review", "audit"]
|
|
6681
6653
|
});
|
|
6682
6654
|
this.connection.emitStatus(this.activeAgents.size > 0 ? "busy" : "idle");
|
|
6683
6655
|
logger6.info("Re-registered after reconnect");
|
|
@@ -6686,6 +6658,29 @@ var ProjectRunner = class {
|
|
|
6686
6658
|
logger6.error("Failed to re-register after reconnect", { error: msg });
|
|
6687
6659
|
}
|
|
6688
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
|
+
}
|
|
6689
6684
|
// ── Task management ────────────────────────────────────────────────────
|
|
6690
6685
|
handleAssignment(assignment) {
|
|
6691
6686
|
const { taskId, mode } = assignment;
|
|
@@ -7013,7 +7008,6 @@ export {
|
|
|
7013
7008
|
ModeController,
|
|
7014
7009
|
DEFAULT_LIFECYCLE_CONFIG,
|
|
7015
7010
|
Lifecycle,
|
|
7016
|
-
createServiceLogger,
|
|
7017
7011
|
hasUncommittedChanges,
|
|
7018
7012
|
getCurrentBranch,
|
|
7019
7013
|
hasUnpushedCommits,
|
|
@@ -7033,4 +7027,4 @@ export {
|
|
|
7033
7027
|
removeWorktree,
|
|
7034
7028
|
ProjectRunner
|
|
7035
7029
|
};
|
|
7036
|
-
//# sourceMappingURL=chunk-
|
|
7030
|
+
//# sourceMappingURL=chunk-NZ3IPMLO.js.map
|