@rallycry/conveyor-agent 5.10.2 → 5.10.3
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-WPQXAPVA.js → chunk-ASK2L7IU.js} +141 -52
- package/dist/chunk-ASK2L7IU.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-WPQXAPVA.js.map +0 -1
|
@@ -459,6 +459,7 @@ var ProjectConnection = class {
|
|
|
459
459
|
onSwitchBranch = null;
|
|
460
460
|
onSyncEnvironment = null;
|
|
461
461
|
onGetEnvStatus = null;
|
|
462
|
+
onRestartStartCommand = null;
|
|
462
463
|
constructor(config) {
|
|
463
464
|
this.config = config;
|
|
464
465
|
}
|
|
@@ -522,6 +523,13 @@ var ProjectConnection = class {
|
|
|
522
523
|
if (this.onGetEnvStatus) this.onGetEnvStatus(cb);
|
|
523
524
|
else cb({ ok: false, data: void 0 });
|
|
524
525
|
});
|
|
526
|
+
this.socket.on(
|
|
527
|
+
"projectRunner:restartStartCommand",
|
|
528
|
+
(_data, cb) => {
|
|
529
|
+
if (this.onRestartStartCommand) this.onRestartStartCommand(cb);
|
|
530
|
+
else cb({ ok: false, error: "restartStartCommand handler not registered" });
|
|
531
|
+
}
|
|
532
|
+
);
|
|
525
533
|
this.socket.on(
|
|
526
534
|
"projectRunner:runAuthTokenCommand",
|
|
527
535
|
(data, cb) => this.handleRunAuthTokenCommand(data.userEmail, cb)
|
|
@@ -784,6 +792,14 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
784
792
|
import { execSync as execSync4 } from "child_process";
|
|
785
793
|
|
|
786
794
|
// src/execution/event-handlers.ts
|
|
795
|
+
function safeVoid(promise, context) {
|
|
796
|
+
if (promise && typeof promise.catch === "function") {
|
|
797
|
+
promise.catch((err) => {
|
|
798
|
+
process.stderr.write(`[safeVoid] ${context}: ${err}
|
|
799
|
+
`);
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
}
|
|
787
803
|
function epochSecondsToISO(value) {
|
|
788
804
|
if (typeof value === "string") return value;
|
|
789
805
|
if (typeof value !== "number" || value <= 0) return void 0;
|
|
@@ -960,13 +976,13 @@ function handleRateLimitEvent(event, host) {
|
|
|
960
976
|
const resetsAtDisplay = resetsAt ?? "unknown";
|
|
961
977
|
const message = `Rate limit rejected (type: ${rate_limit_info.rateLimitType ?? "unknown"}, resets at: ${resetsAtDisplay})`;
|
|
962
978
|
host.connection.sendEvent({ type: "error", message });
|
|
963
|
-
|
|
979
|
+
safeVoid(host.callbacks.onEvent({ type: "error", message }), "rateLimitRejected");
|
|
964
980
|
return resetsAt;
|
|
965
981
|
} else if (status === "allowed_warning") {
|
|
966
982
|
const utilization = rate_limit_info.utilization ? `${Math.round(rate_limit_info.utilization * 100)}%` : "high";
|
|
967
983
|
const message = `Rate limit warning: ${utilization} utilization (type: ${rate_limit_info.rateLimitType ?? "unknown"})`;
|
|
968
984
|
host.connection.sendEvent({ type: "thinking", message });
|
|
969
|
-
|
|
985
|
+
safeVoid(host.callbacks.onEvent({ type: "thinking", message }), "rateLimitWarning");
|
|
970
986
|
}
|
|
971
987
|
return void 0;
|
|
972
988
|
}
|
|
@@ -984,34 +1000,46 @@ async function handleSystemEvent(event, host, context, sessionIdStored) {
|
|
|
984
1000
|
}
|
|
985
1001
|
function handleSystemSubevents(systemEvent, host) {
|
|
986
1002
|
if (systemEvent.subtype === "compact_boundary") {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1003
|
+
safeVoid(
|
|
1004
|
+
host.callbacks.onEvent({
|
|
1005
|
+
type: "context_compacted",
|
|
1006
|
+
trigger: systemEvent.compact_metadata.trigger,
|
|
1007
|
+
preTokens: systemEvent.compact_metadata.pre_tokens
|
|
1008
|
+
}),
|
|
1009
|
+
"compactBoundary"
|
|
1010
|
+
);
|
|
992
1011
|
} else if (systemEvent.subtype === "task_started") {
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1012
|
+
safeVoid(
|
|
1013
|
+
host.callbacks.onEvent({
|
|
1014
|
+
type: "subagent_started",
|
|
1015
|
+
sdkTaskId: systemEvent.task_id,
|
|
1016
|
+
description: systemEvent.description
|
|
1017
|
+
}),
|
|
1018
|
+
"taskStarted"
|
|
1019
|
+
);
|
|
998
1020
|
} else if (systemEvent.subtype === "task_progress") {
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1021
|
+
safeVoid(
|
|
1022
|
+
host.callbacks.onEvent({
|
|
1023
|
+
type: "subagent_progress",
|
|
1024
|
+
sdkTaskId: systemEvent.task_id,
|
|
1025
|
+
description: systemEvent.description,
|
|
1026
|
+
toolUses: systemEvent.usage?.tool_uses ?? 0,
|
|
1027
|
+
durationMs: systemEvent.usage?.duration_ms ?? 0
|
|
1028
|
+
}),
|
|
1029
|
+
"taskProgress"
|
|
1030
|
+
);
|
|
1006
1031
|
}
|
|
1007
1032
|
}
|
|
1008
1033
|
function handleToolProgressEvent(event, host) {
|
|
1009
1034
|
const msg = event;
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1035
|
+
safeVoid(
|
|
1036
|
+
host.callbacks.onEvent({
|
|
1037
|
+
type: "tool_progress",
|
|
1038
|
+
toolName: msg.tool_name ?? "",
|
|
1039
|
+
elapsedSeconds: msg.elapsed_time_seconds ?? 0
|
|
1040
|
+
}),
|
|
1041
|
+
"toolProgress"
|
|
1042
|
+
);
|
|
1015
1043
|
}
|
|
1016
1044
|
async function handleAssistantCase(event, host, turnToolCalls) {
|
|
1017
1045
|
await processAssistantEvent(event, host, turnToolCalls);
|
|
@@ -1034,6 +1062,7 @@ async function handleResultCase(event, host, context, startTime, isTyping, lastA
|
|
|
1034
1062
|
}
|
|
1035
1063
|
|
|
1036
1064
|
// src/execution/event-processor.ts
|
|
1065
|
+
var API_ERROR_PATTERN2 = /API Error: [45]\d\d/;
|
|
1037
1066
|
function stopTypingIfNeeded(host, isTyping) {
|
|
1038
1067
|
if (isTyping) host.connection.sendTypingStop();
|
|
1039
1068
|
}
|
|
@@ -1055,6 +1084,12 @@ async function processAssistantCase(event, host, state) {
|
|
|
1055
1084
|
}
|
|
1056
1085
|
const usage = await handleAssistantCase(event, host, state.turnToolCalls);
|
|
1057
1086
|
if (usage) state.lastAssistantUsage = usage;
|
|
1087
|
+
if (!state.sawApiError) {
|
|
1088
|
+
const fullText = event.message.content.filter((b) => b.type === "text").map((b) => b.text).join(" ");
|
|
1089
|
+
if (API_ERROR_PATTERN2.test(fullText)) {
|
|
1090
|
+
state.sawApiError = true;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1058
1093
|
}
|
|
1059
1094
|
async function processResultCase(event, host, context, startTime, state) {
|
|
1060
1095
|
const info = await handleResultCase(
|
|
@@ -1078,6 +1113,7 @@ async function processEvents(events, context, host) {
|
|
|
1078
1113
|
sessionIdStored: false,
|
|
1079
1114
|
isTyping: false,
|
|
1080
1115
|
retriable: false,
|
|
1116
|
+
sawApiError: false,
|
|
1081
1117
|
resultSummary: void 0,
|
|
1082
1118
|
rateLimitResetsAt: void 0,
|
|
1083
1119
|
staleSession: void 0,
|
|
@@ -1117,7 +1153,7 @@ async function processEvents(events, context, host) {
|
|
|
1117
1153
|
}
|
|
1118
1154
|
stopTypingIfNeeded(host, state.isTyping);
|
|
1119
1155
|
return {
|
|
1120
|
-
retriable: state.retriable,
|
|
1156
|
+
retriable: state.retriable || state.sawApiError,
|
|
1121
1157
|
resultSummary: state.resultSummary,
|
|
1122
1158
|
rateLimitResetsAt: state.rateLimitResetsAt,
|
|
1123
1159
|
...state.staleSession && { staleSession: state.staleSession }
|
|
@@ -1478,6 +1514,8 @@ function buildDiscoveryPrompt(context) {
|
|
|
1478
1514
|
`You are in Discovery mode \u2014 helping plan and scope this task.`,
|
|
1479
1515
|
`- You have read-only codebase access (can read files, run git commands, search code)`,
|
|
1480
1516
|
`- You can write plan files in .claude/plans/ only \u2014 no other file writes`,
|
|
1517
|
+
`- Do NOT attempt to edit, write, or modify source code files \u2014 these operations will be denied`,
|
|
1518
|
+
`- If you identify code changes needed, describe them in the plan instead of implementing them`,
|
|
1481
1519
|
`- You can create and manage subtasks`,
|
|
1482
1520
|
`- Goal: collaborate with the user to create a clear plan`,
|
|
1483
1521
|
`- Proactively fill task properties (SP, tags, icon) as the plan takes shape`,
|
|
@@ -1742,7 +1780,7 @@ function detectRelaunchScenario(context, trustChatHistory = false) {
|
|
|
1742
1780
|
const hasNewUserMessages = messagesAfterAgent.some((m) => m.role === "user");
|
|
1743
1781
|
return hasNewUserMessages ? "feedback_relaunch" : "idle_relaunch";
|
|
1744
1782
|
}
|
|
1745
|
-
function buildRelaunchWithSession(mode, context, agentMode) {
|
|
1783
|
+
function buildRelaunchWithSession(mode, context, agentMode, isAuto) {
|
|
1746
1784
|
const scenario = detectRelaunchScenario(context);
|
|
1747
1785
|
if (!context.claudeSessionId || scenario === "fresh") return null;
|
|
1748
1786
|
const parts = [];
|
|
@@ -1790,7 +1828,7 @@ Address the requested changes. Do NOT re-investigate the codebase from scratch o
|
|
|
1790
1828
|
`Run \`git log --oneline -10\` to review what you already committed.`,
|
|
1791
1829
|
`Review the current state of the codebase and verify everything is working correctly.`
|
|
1792
1830
|
);
|
|
1793
|
-
if (agentMode === "auto" || agentMode === "building") {
|
|
1831
|
+
if (agentMode === "auto" || agentMode === "building" && isAuto) {
|
|
1794
1832
|
parts.push(
|
|
1795
1833
|
`If work is incomplete, continue implementing the plan. When finished, commit, push, and use mcp__conveyor__create_pull_request to open a PR.`,
|
|
1796
1834
|
`Do NOT go idle or wait for instructions \u2014 you are in auto mode.`
|
|
@@ -1996,7 +2034,7 @@ Address the requested changes directly. Do NOT re-investigate the codebase from
|
|
|
1996
2034
|
}
|
|
1997
2035
|
return parts;
|
|
1998
2036
|
}
|
|
1999
|
-
function buildInstructions(mode, context, scenario, agentMode) {
|
|
2037
|
+
function buildInstructions(mode, context, scenario, agentMode, isAuto) {
|
|
2000
2038
|
const parts = [`
|
|
2001
2039
|
## Instructions`];
|
|
2002
2040
|
const isPm = mode === "pm";
|
|
@@ -2028,7 +2066,7 @@ function buildInstructions(mode, context, scenario, agentMode) {
|
|
|
2028
2066
|
`Work on the git branch "${context.githubBranch}". Stay on this branch \u2014 do not checkout or create other branches.`,
|
|
2029
2067
|
`Run \`git log --oneline -10\` to review what you already committed, then verify the current state is correct.`
|
|
2030
2068
|
);
|
|
2031
|
-
if (agentMode === "auto" || agentMode === "building") {
|
|
2069
|
+
if (agentMode === "auto" || agentMode === "building" && isAuto) {
|
|
2032
2070
|
parts.push(
|
|
2033
2071
|
`If work is incomplete, continue implementing the plan. When finished, commit, push, and use mcp__conveyor__create_pull_request to open a PR.`,
|
|
2034
2072
|
`Do NOT go idle or wait for instructions \u2014 you are in auto mode.`
|
|
@@ -2051,13 +2089,13 @@ function buildInstructions(mode, context, scenario, agentMode) {
|
|
|
2051
2089
|
async function buildInitialPrompt(mode, context, isAuto, agentMode) {
|
|
2052
2090
|
const isPackRunner = mode === "pm" && !!isAuto && !!context.isParentTask;
|
|
2053
2091
|
if (!isPackRunner) {
|
|
2054
|
-
const sessionRelaunch = buildRelaunchWithSession(mode, context, agentMode);
|
|
2092
|
+
const sessionRelaunch = buildRelaunchWithSession(mode, context, agentMode, isAuto);
|
|
2055
2093
|
if (sessionRelaunch) return sessionRelaunch;
|
|
2056
2094
|
}
|
|
2057
2095
|
const isPm = mode === "pm";
|
|
2058
2096
|
const scenario = detectRelaunchScenario(context, isPm);
|
|
2059
2097
|
const body = await buildTaskBody(context);
|
|
2060
|
-
const instructions = isPackRunner ? buildPackRunnerInstructions(context, scenario) : buildInstructions(mode, context, scenario, agentMode);
|
|
2098
|
+
const instructions = isPackRunner ? buildPackRunnerInstructions(context, scenario) : buildInstructions(mode, context, scenario, agentMode, isAuto);
|
|
2061
2099
|
return [...body, ...instructions].join("\n");
|
|
2062
2100
|
}
|
|
2063
2101
|
|
|
@@ -2811,7 +2849,9 @@ async function handleAskUserQuestion(host, input) {
|
|
|
2811
2849
|
}
|
|
2812
2850
|
return { behavior: "allow", updatedInput: { questions: input.questions, answers } };
|
|
2813
2851
|
}
|
|
2852
|
+
var DENIAL_WARNING_THRESHOLD = 3;
|
|
2814
2853
|
function buildCanUseTool(host) {
|
|
2854
|
+
let consecutiveDenials = 0;
|
|
2815
2855
|
return async (toolName, input) => {
|
|
2816
2856
|
if (toolName === "ExitPlanMode" && (host.agentMode === "auto" || host.agentMode === "discovery") && !host.hasExitedPlanMode) {
|
|
2817
2857
|
return await handleExitPlanMode(host, input);
|
|
@@ -2819,23 +2859,39 @@ function buildCanUseTool(host) {
|
|
|
2819
2859
|
if (toolName === "AskUserQuestion") {
|
|
2820
2860
|
return await handleAskUserQuestion(host, input);
|
|
2821
2861
|
}
|
|
2862
|
+
let result;
|
|
2822
2863
|
switch (host.agentMode) {
|
|
2823
2864
|
case "discovery":
|
|
2824
|
-
|
|
2865
|
+
result = handleDiscoveryToolAccess(toolName, input);
|
|
2866
|
+
break;
|
|
2825
2867
|
case "building":
|
|
2826
|
-
|
|
2868
|
+
result = handleBuildingToolAccess(toolName, input);
|
|
2869
|
+
break;
|
|
2827
2870
|
case "review":
|
|
2828
|
-
|
|
2871
|
+
result = handleReviewToolAccess(toolName, input, host.isParentTask);
|
|
2872
|
+
break;
|
|
2829
2873
|
case "auto":
|
|
2830
|
-
|
|
2874
|
+
result = handleAutoToolAccess(toolName, input, host.hasExitedPlanMode, host.isParentTask);
|
|
2875
|
+
break;
|
|
2831
2876
|
default:
|
|
2832
|
-
|
|
2877
|
+
result = { behavior: "allow", updatedInput: input };
|
|
2878
|
+
}
|
|
2879
|
+
if (result.behavior === "deny") {
|
|
2880
|
+
consecutiveDenials++;
|
|
2881
|
+
if (consecutiveDenials === DENIAL_WARNING_THRESHOLD) {
|
|
2882
|
+
host.connection.postChatMessage(
|
|
2883
|
+
`\u26A0\uFE0F Multiple tool denials detected. You are in ${host.agentMode} mode \u2014 file writes outside .claude/plans/ are not permitted. Focus on creating a plan instead of implementing code changes.`
|
|
2884
|
+
);
|
|
2885
|
+
}
|
|
2886
|
+
} else {
|
|
2887
|
+
consecutiveDenials = 0;
|
|
2833
2888
|
}
|
|
2889
|
+
return result;
|
|
2834
2890
|
};
|
|
2835
2891
|
}
|
|
2836
2892
|
|
|
2837
2893
|
// src/execution/query-executor.ts
|
|
2838
|
-
var
|
|
2894
|
+
var API_ERROR_PATTERN3 = /API Error: [45]\d\d/;
|
|
2839
2895
|
var IMAGE_ERROR_PATTERN2 = /Could not process image/i;
|
|
2840
2896
|
var RETRY_DELAYS_MS = [6e4, 12e4, 18e4, 3e5];
|
|
2841
2897
|
function buildHooks(host) {
|
|
@@ -3083,12 +3139,17 @@ function isStaleOrExitedSession(error, context) {
|
|
|
3083
3139
|
if (error.message.includes("No conversation found with session ID")) return true;
|
|
3084
3140
|
return !!context.claudeSessionId && error.message.includes("process exited");
|
|
3085
3141
|
}
|
|
3142
|
+
function getErrorMessage(error) {
|
|
3143
|
+
if (error instanceof Error) return error.message;
|
|
3144
|
+
if (typeof error === "string") return error;
|
|
3145
|
+
return String(error);
|
|
3146
|
+
}
|
|
3086
3147
|
function isRetriableError(error) {
|
|
3087
|
-
|
|
3088
|
-
return
|
|
3148
|
+
const message = getErrorMessage(error);
|
|
3149
|
+
return API_ERROR_PATTERN3.test(message) || IMAGE_ERROR_PATTERN2.test(message);
|
|
3089
3150
|
}
|
|
3090
3151
|
function classifyImageError(error) {
|
|
3091
|
-
return
|
|
3152
|
+
return IMAGE_ERROR_PATTERN2.test(getErrorMessage(error));
|
|
3092
3153
|
}
|
|
3093
3154
|
async function emitRetryStatus(host, attempt, delayMs) {
|
|
3094
3155
|
const delayMin = Math.round(delayMs / 6e4);
|
|
@@ -4344,14 +4405,15 @@ var TOOL_MAPPERS = {
|
|
|
4344
4405
|
recommend_merge_tags: mapMergeTags,
|
|
4345
4406
|
recommend_rename_tag: mapRenameTag
|
|
4346
4407
|
};
|
|
4347
|
-
function collectRecommendation(toolName, input, collector) {
|
|
4408
|
+
function collectRecommendation(toolName, input, collector, onRecommendation) {
|
|
4348
4409
|
const mapper = TOOL_MAPPERS[toolName];
|
|
4349
4410
|
if (!mapper) return JSON.stringify({ error: `Unknown tool: ${toolName}` });
|
|
4350
4411
|
const rec = { id: randomUUID3(), ...mapper(input) };
|
|
4351
4412
|
collector.recommendations.push(rec);
|
|
4413
|
+
onRecommendation?.({ tagName: rec.tagName ?? rec.type, type: rec.type });
|
|
4352
4414
|
return JSON.stringify({ success: true, recommendationId: rec.id });
|
|
4353
4415
|
}
|
|
4354
|
-
function createAuditMcpServer(collector) {
|
|
4416
|
+
function createAuditMcpServer(collector, onRecommendation) {
|
|
4355
4417
|
const auditTools = [
|
|
4356
4418
|
tool4(
|
|
4357
4419
|
"recommend_create_tag",
|
|
@@ -4366,7 +4428,8 @@ function createAuditMcpServer(collector) {
|
|
|
4366
4428
|
const result = collectRecommendation(
|
|
4367
4429
|
"recommend_create_tag",
|
|
4368
4430
|
args,
|
|
4369
|
-
collector
|
|
4431
|
+
collector,
|
|
4432
|
+
onRecommendation
|
|
4370
4433
|
);
|
|
4371
4434
|
return { content: [{ type: "text", text: result }] };
|
|
4372
4435
|
}
|
|
@@ -4384,7 +4447,8 @@ function createAuditMcpServer(collector) {
|
|
|
4384
4447
|
const result = collectRecommendation(
|
|
4385
4448
|
"recommend_update_description",
|
|
4386
4449
|
args,
|
|
4387
|
-
collector
|
|
4450
|
+
collector,
|
|
4451
|
+
onRecommendation
|
|
4388
4452
|
);
|
|
4389
4453
|
return { content: [{ type: "text", text: result }] };
|
|
4390
4454
|
}
|
|
@@ -4404,7 +4468,8 @@ function createAuditMcpServer(collector) {
|
|
|
4404
4468
|
const result = collectRecommendation(
|
|
4405
4469
|
"recommend_context_link",
|
|
4406
4470
|
args,
|
|
4407
|
-
collector
|
|
4471
|
+
collector,
|
|
4472
|
+
onRecommendation
|
|
4408
4473
|
);
|
|
4409
4474
|
return { content: [{ type: "text", text: result }] };
|
|
4410
4475
|
}
|
|
@@ -4424,7 +4489,8 @@ function createAuditMcpServer(collector) {
|
|
|
4424
4489
|
const result = collectRecommendation(
|
|
4425
4490
|
"flag_documentation_gap",
|
|
4426
4491
|
args,
|
|
4427
|
-
collector
|
|
4492
|
+
collector,
|
|
4493
|
+
onRecommendation
|
|
4428
4494
|
);
|
|
4429
4495
|
return { content: [{ type: "text", text: result }] };
|
|
4430
4496
|
}
|
|
@@ -4443,7 +4509,8 @@ function createAuditMcpServer(collector) {
|
|
|
4443
4509
|
const result = collectRecommendation(
|
|
4444
4510
|
"recommend_merge_tags",
|
|
4445
4511
|
args,
|
|
4446
|
-
collector
|
|
4512
|
+
collector,
|
|
4513
|
+
onRecommendation
|
|
4447
4514
|
);
|
|
4448
4515
|
return { content: [{ type: "text", text: result }] };
|
|
4449
4516
|
}
|
|
@@ -4461,7 +4528,8 @@ function createAuditMcpServer(collector) {
|
|
|
4461
4528
|
const result = collectRecommendation(
|
|
4462
4529
|
"recommend_rename_tag",
|
|
4463
4530
|
args,
|
|
4464
|
-
collector
|
|
4531
|
+
collector,
|
|
4532
|
+
onRecommendation
|
|
4465
4533
|
);
|
|
4466
4534
|
return { content: [{ type: "text", text: result }] };
|
|
4467
4535
|
}
|
|
@@ -4536,12 +4604,14 @@ function buildAuditSystemPrompt(projectName, tags, heatmapData, projectDir) {
|
|
|
4536
4604
|
].join("\n");
|
|
4537
4605
|
}
|
|
4538
4606
|
async function runAuditQuery(request, connection, projectDir) {
|
|
4607
|
+
connection.emitAgentStatus("fetching_context");
|
|
4539
4608
|
let agentCtx = null;
|
|
4540
4609
|
try {
|
|
4541
4610
|
agentCtx = await connection.fetchAgentContext();
|
|
4542
4611
|
} catch {
|
|
4543
4612
|
logger5.warn("Could not fetch agent context for audit, using defaults");
|
|
4544
4613
|
}
|
|
4614
|
+
connection.emitAgentStatus("running");
|
|
4545
4615
|
const model = agentCtx?.model || FALLBACK_MODEL2;
|
|
4546
4616
|
const settings = agentCtx?.agentSettings ?? {};
|
|
4547
4617
|
const collector = {
|
|
@@ -4549,6 +4619,13 @@ async function runAuditQuery(request, connection, projectDir) {
|
|
|
4549
4619
|
summary: "Audit completed.",
|
|
4550
4620
|
complete: false
|
|
4551
4621
|
};
|
|
4622
|
+
const onRecommendation = (rec) => {
|
|
4623
|
+
connection.emitEvent({
|
|
4624
|
+
type: "audit_recommendation",
|
|
4625
|
+
tagName: rec.tagName,
|
|
4626
|
+
recommendationType: rec.type
|
|
4627
|
+
});
|
|
4628
|
+
};
|
|
4552
4629
|
const systemPrompt = buildAuditSystemPrompt(
|
|
4553
4630
|
request.projectName,
|
|
4554
4631
|
request.tags,
|
|
@@ -4572,20 +4649,27 @@ async function runAuditQuery(request, connection, projectDir) {
|
|
|
4572
4649
|
permissionMode: "bypassPermissions",
|
|
4573
4650
|
allowDangerouslySkipPermissions: true,
|
|
4574
4651
|
tools: { type: "preset", preset: "claude_code" },
|
|
4575
|
-
mcpServers: { "tag-audit": createAuditMcpServer(collector) },
|
|
4652
|
+
mcpServers: { "tag-audit": createAuditMcpServer(collector, onRecommendation) },
|
|
4576
4653
|
maxTurns: settings.maxTurns ?? 30,
|
|
4577
4654
|
maxBudgetUsd: settings.maxBudgetUsd ?? 5,
|
|
4578
4655
|
effort: settings.effort,
|
|
4579
4656
|
thinking: settings.thinking
|
|
4580
4657
|
}
|
|
4581
4658
|
});
|
|
4659
|
+
const responseParts = [];
|
|
4660
|
+
const turnToolCalls = [];
|
|
4661
|
+
const isTyping = { value: false };
|
|
4582
4662
|
for await (const event of events) {
|
|
4583
|
-
|
|
4663
|
+
const done = processEventStream(event, connection, responseParts, turnToolCalls, isTyping);
|
|
4664
|
+
if (done) break;
|
|
4665
|
+
}
|
|
4666
|
+
if (isTyping.value) {
|
|
4667
|
+
connection.emitEvent({ type: "agent_typing_stop" });
|
|
4584
4668
|
}
|
|
4585
4669
|
return collector;
|
|
4586
4670
|
}
|
|
4587
4671
|
async function handleProjectAuditRequest(request, connection, projectDir) {
|
|
4588
|
-
connection.emitAgentStatus("
|
|
4672
|
+
connection.emitAgentStatus("running");
|
|
4589
4673
|
try {
|
|
4590
4674
|
const collector = await runAuditQuery(request, connection, projectDir);
|
|
4591
4675
|
const result = {
|
|
@@ -5063,6 +5147,11 @@ var ProjectRunner = class {
|
|
|
5063
5147
|
this.connection.onGetEnvStatus = (cb) => {
|
|
5064
5148
|
this.handleGetEnvStatus(cb);
|
|
5065
5149
|
};
|
|
5150
|
+
this.connection.onRestartStartCommand = (cb) => {
|
|
5151
|
+
void this.restartStartCommand().then(() => cb({ ok: true })).catch(
|
|
5152
|
+
(err) => cb({ ok: false, error: err instanceof Error ? err.message : "Restart failed" })
|
|
5153
|
+
);
|
|
5154
|
+
};
|
|
5066
5155
|
try {
|
|
5067
5156
|
const context = await this.connection.fetchAgentContext();
|
|
5068
5157
|
this.branchSwitchCommand = context?.branchSwitchCommand ?? process.env.CONVEYOR_BRANCH_SWITCH_COMMAND;
|
|
@@ -5274,4 +5363,4 @@ export {
|
|
|
5274
5363
|
ProjectRunner,
|
|
5275
5364
|
FileCache
|
|
5276
5365
|
};
|
|
5277
|
-
//# sourceMappingURL=chunk-
|
|
5366
|
+
//# sourceMappingURL=chunk-ASK2L7IU.js.map
|