@rallycry/conveyor-agent 8.2.0 → 8.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-KTNGU2WU.js → chunk-ND473JTK.js} +11 -3
- package/dist/chunk-ND473JTK.js.map +1 -0
- package/dist/{chunk-W4NCD23G.js → chunk-WNPFZC3I.js} +299 -67
- package/dist/chunk-WNPFZC3I.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -2
- package/dist/{tag-audit-handler-E6BZGVIG.js → tag-audit-handler-RFGGQWG6.js} +2 -2
- package/dist/{task-audit-handler-MXSNTY22.js → task-audit-handler-BN42VOYM.js} +2 -2
- package/package.json +2 -2
- package/dist/chunk-KTNGU2WU.js.map +0 -1
- package/dist/chunk-W4NCD23G.js.map +0 -1
- /package/dist/{tag-audit-handler-E6BZGVIG.js.map → tag-audit-handler-RFGGQWG6.js.map} +0 -0
- /package/dist/{task-audit-handler-MXSNTY22.js.map → task-audit-handler-BN42VOYM.js.map} +0 -0
|
@@ -7,8 +7,9 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
createHarness,
|
|
9
9
|
createServiceLogger,
|
|
10
|
-
defineTool
|
|
11
|
-
|
|
10
|
+
defineTool,
|
|
11
|
+
sessionTranscriptPath
|
|
12
|
+
} from "./chunk-ND473JTK.js";
|
|
12
13
|
|
|
13
14
|
// src/setup/bootstrap.ts
|
|
14
15
|
var BOOTSTRAP_TIMEOUT_MS = 3e4;
|
|
@@ -1154,28 +1155,118 @@ function updateRemoteToken(cwd, token) {
|
|
|
1154
1155
|
} catch {
|
|
1155
1156
|
}
|
|
1156
1157
|
}
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1158
|
+
function wipRefForBranch(branch) {
|
|
1159
|
+
return `conveyor-wip/${branch}`;
|
|
1160
|
+
}
|
|
1161
|
+
var wipRefPushed = /* @__PURE__ */ new Set();
|
|
1162
|
+
function createWipSnapshot(cwd, message) {
|
|
1163
|
+
try {
|
|
1164
|
+
execSync("git add -A", { cwd, stdio: ["ignore", "pipe", "ignore"] });
|
|
1165
|
+
const sha = execSync(`git stash create ${JSON.stringify(message)}`, {
|
|
1166
|
+
cwd,
|
|
1167
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1168
|
+
}).toString().trim();
|
|
1169
|
+
return sha || null;
|
|
1170
|
+
} catch {
|
|
1171
|
+
return null;
|
|
1172
|
+
} finally {
|
|
1173
|
+
try {
|
|
1174
|
+
execSync("git reset -q", { cwd, stdio: ["ignore", "pipe", "ignore"] });
|
|
1175
|
+
} catch {
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
function tryPushRefspec(cwd, refspec, force = false) {
|
|
1180
|
+
try {
|
|
1181
|
+
execSync(`git push ${force ? "--force " : ""}origin ${JSON.stringify(refspec)}`, {
|
|
1182
|
+
cwd,
|
|
1183
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1184
|
+
timeout: 3e4
|
|
1185
|
+
});
|
|
1186
|
+
return true;
|
|
1187
|
+
} catch {
|
|
1188
|
+
return false;
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
async function refreshRemoteToken(cwd, refreshToken) {
|
|
1192
|
+
if (!refreshToken) return;
|
|
1161
1193
|
try {
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1194
|
+
const token = await refreshToken();
|
|
1195
|
+
if (token) {
|
|
1196
|
+
updateRemoteToken(cwd, token);
|
|
1197
|
+
process.env.GITHUB_TOKEN = token;
|
|
1198
|
+
process.env.GH_TOKEN = token;
|
|
1167
1199
|
}
|
|
1168
1200
|
} catch {
|
|
1169
1201
|
}
|
|
1202
|
+
}
|
|
1203
|
+
function restoreWipSnapshot(cwd, branch) {
|
|
1204
|
+
if (!branch) return "none";
|
|
1205
|
+
const ref = wipRefForBranch(branch);
|
|
1170
1206
|
try {
|
|
1171
|
-
|
|
1172
|
-
|
|
1207
|
+
execSync(`git fetch origin +refs/heads/${ref}:refs/remotes/origin/${ref}`, {
|
|
1208
|
+
cwd,
|
|
1209
|
+
stdio: "ignore",
|
|
1210
|
+
timeout: 6e4
|
|
1211
|
+
});
|
|
1212
|
+
} catch {
|
|
1213
|
+
return "none";
|
|
1214
|
+
}
|
|
1215
|
+
wipRefPushed.add(cwd);
|
|
1216
|
+
try {
|
|
1217
|
+
const sha = execSync(`git rev-parse refs/remotes/origin/${ref}`, {
|
|
1218
|
+
cwd,
|
|
1219
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1220
|
+
}).toString().trim();
|
|
1221
|
+
const parent = execSync(`git rev-parse "${sha}^"`, {
|
|
1222
|
+
cwd,
|
|
1223
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1224
|
+
}).toString().trim();
|
|
1225
|
+
const head = execSync("git rev-parse HEAD", { cwd, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
1226
|
+
if (parent !== head) return "stale";
|
|
1227
|
+
execSync(`git stash apply ${sha}`, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
1228
|
+
return "applied";
|
|
1229
|
+
} catch {
|
|
1230
|
+
return "failed";
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
async function flushPendingChanges(cwd, opts) {
|
|
1234
|
+
let committed = false;
|
|
1235
|
+
let pushed = false;
|
|
1236
|
+
let hadWork = false;
|
|
1237
|
+
try {
|
|
1238
|
+
const branch = getCurrentBranch(cwd);
|
|
1239
|
+
if (!branch) return { committed, pushed, hadWork };
|
|
1240
|
+
const dirty = hasUncommittedChanges(cwd);
|
|
1241
|
+
const unpushed = hasUnpushedCommits(cwd);
|
|
1242
|
+
if (!dirty && !unpushed) {
|
|
1243
|
+
await dropStaleWipRef(cwd, branch, opts?.refreshToken);
|
|
1244
|
+
return { committed, pushed, hadWork };
|
|
1245
|
+
}
|
|
1246
|
+
hadWork = true;
|
|
1247
|
+
await refreshRemoteToken(cwd, opts?.refreshToken);
|
|
1248
|
+
if (unpushed) {
|
|
1173
1249
|
pushed = await pushToOrigin(cwd, opts?.refreshToken);
|
|
1174
1250
|
}
|
|
1251
|
+
if (dirty) {
|
|
1252
|
+
const message = opts?.wipMessage ?? "WIP: conveyor-agent snapshot";
|
|
1253
|
+
const sha = createWipSnapshot(cwd, message);
|
|
1254
|
+
if (sha) {
|
|
1255
|
+
committed = tryPushRefspec(cwd, `${sha}:refs/heads/${wipRefForBranch(branch)}`, true);
|
|
1256
|
+
if (committed) wipRefPushed.add(cwd);
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1175
1259
|
} catch {
|
|
1176
1260
|
}
|
|
1177
1261
|
return { committed, pushed, hadWork };
|
|
1178
1262
|
}
|
|
1263
|
+
async function dropStaleWipRef(cwd, branch, refreshToken) {
|
|
1264
|
+
if (!wipRefPushed.has(cwd)) return;
|
|
1265
|
+
await refreshRemoteToken(cwd, refreshToken);
|
|
1266
|
+
if (tryPushRefspec(cwd, `:refs/heads/${wipRefForBranch(branch)}`)) {
|
|
1267
|
+
wipRefPushed.delete(cwd);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1179
1270
|
async function pushToOrigin(cwd, refreshToken) {
|
|
1180
1271
|
try {
|
|
1181
1272
|
const currentBranch = getCurrentBranch(cwd);
|
|
@@ -1302,9 +1393,7 @@ var PlanSync = class {
|
|
|
1302
1393
|
|
|
1303
1394
|
// src/execution/query-executor.ts
|
|
1304
1395
|
import { createHash } from "crypto";
|
|
1305
|
-
import { existsSync } from "fs";
|
|
1306
|
-
import { homedir } from "os";
|
|
1307
|
-
import { join as join3 } from "path";
|
|
1396
|
+
import { existsSync, readFileSync as readFileSync2, truncateSync } from "fs";
|
|
1308
1397
|
|
|
1309
1398
|
// ../shared/dist/index.js
|
|
1310
1399
|
import { z } from "zod";
|
|
@@ -1313,6 +1402,7 @@ import { z as z3 } from "zod";
|
|
|
1313
1402
|
var MAX_FILE_SIZE_BYTES = 25 * 1024 * 1024;
|
|
1314
1403
|
var EMBED_THRESHOLD_IMAGES = 5 * 1024 * 1024;
|
|
1315
1404
|
var EMBED_THRESHOLD_TEXT = 2 * 1024 * 1024;
|
|
1405
|
+
var IDLE_HEARTBEAT_MS = 90 * 1e3;
|
|
1316
1406
|
var AgentHeartbeatSchema = z.object({
|
|
1317
1407
|
sessionId: z.string().optional(),
|
|
1318
1408
|
timestamp: z.string(),
|
|
@@ -6389,19 +6479,63 @@ function buildHooks(host) {
|
|
|
6389
6479
|
]
|
|
6390
6480
|
};
|
|
6391
6481
|
}
|
|
6392
|
-
function taskIdToSessionUuid(
|
|
6393
|
-
const hash = createHash("sha256").update(
|
|
6482
|
+
function taskIdToSessionUuid(lineageKey) {
|
|
6483
|
+
const hash = createHash("sha256").update(lineageKey).digest("hex");
|
|
6394
6484
|
return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-8${hash.slice(13, 16)}-a${hash.slice(17, 20)}-${hash.slice(20, 32)}`;
|
|
6395
6485
|
}
|
|
6486
|
+
function sessionLineageKey(taskId, agentMode, runnerMode) {
|
|
6487
|
+
return agentMode === "review" || runnerMode === "code-review" ? `${taskId}:review` : taskId;
|
|
6488
|
+
}
|
|
6396
6489
|
function sessionFileExists(sessionUuid, cwd) {
|
|
6397
6490
|
try {
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
return
|
|
6491
|
+
return existsSync(sessionTranscriptPath(cwd, sessionUuid));
|
|
6492
|
+
} catch {
|
|
6493
|
+
return false;
|
|
6494
|
+
}
|
|
6495
|
+
}
|
|
6496
|
+
function hasExistingSessionFile(taskId, cwd, lineage) {
|
|
6497
|
+
const key = sessionLineageKey(taskId, lineage.agentMode, lineage.runnerMode);
|
|
6498
|
+
return sessionFileExists(taskIdToSessionUuid(key), cwd);
|
|
6499
|
+
}
|
|
6500
|
+
function repairTornSessionFile(path2) {
|
|
6501
|
+
try {
|
|
6502
|
+
if (!existsSync(path2)) return false;
|
|
6503
|
+
const content = readFileSync2(path2, "utf8");
|
|
6504
|
+
if (content.length === 0) return false;
|
|
6505
|
+
let keepEnd = content.length;
|
|
6506
|
+
if (!content.endsWith("\n")) {
|
|
6507
|
+
keepEnd = content.lastIndexOf("\n") + 1;
|
|
6508
|
+
}
|
|
6509
|
+
while (keepEnd > 0) {
|
|
6510
|
+
const prevNewline = content.lastIndexOf("\n", keepEnd - 2);
|
|
6511
|
+
const line = content.slice(prevNewline + 1, keepEnd - 1).trim();
|
|
6512
|
+
if (line.length > 0) {
|
|
6513
|
+
try {
|
|
6514
|
+
JSON.parse(line);
|
|
6515
|
+
break;
|
|
6516
|
+
} catch {
|
|
6517
|
+
}
|
|
6518
|
+
}
|
|
6519
|
+
keepEnd = prevNewline + 1;
|
|
6520
|
+
}
|
|
6521
|
+
if (keepEnd === content.length) return false;
|
|
6522
|
+
truncateSync(path2, Buffer.byteLength(content.slice(0, keepEnd), "utf8"));
|
|
6523
|
+
logger2.warn("Repaired torn transcript before resume", {
|
|
6524
|
+
path: path2,
|
|
6525
|
+
trimmedBytes: content.length - keepEnd
|
|
6526
|
+
});
|
|
6527
|
+
return true;
|
|
6401
6528
|
} catch {
|
|
6402
6529
|
return false;
|
|
6403
6530
|
}
|
|
6404
6531
|
}
|
|
6532
|
+
function resolvePromptDelivery(inputs) {
|
|
6533
|
+
if (inputs.harnessKind !== "pty") return "submit";
|
|
6534
|
+
if ((inputs.runnerMode ?? "task") !== "task") return "submit";
|
|
6535
|
+
if (inputs.isFollowUp || inputs.hasExistingSession) return "submit";
|
|
6536
|
+
if (inputs.isAuto || inputs.agentMode === "auto") return "submit";
|
|
6537
|
+
return "prefill";
|
|
6538
|
+
}
|
|
6405
6539
|
function isReadOnlyMode(mode, hasExitedPlanMode) {
|
|
6406
6540
|
return mode === "discovery" || mode === "help" || mode === "auto" && !hasExitedPlanMode;
|
|
6407
6541
|
}
|
|
@@ -6514,7 +6648,17 @@ ${followUpText}` : followUpText;
|
|
|
6514
6648
|
}
|
|
6515
6649
|
return textPrompt;
|
|
6516
6650
|
}
|
|
6517
|
-
async function
|
|
6651
|
+
async function* notifyOnFirstEvent(inner, onFirst) {
|
|
6652
|
+
let fired = false;
|
|
6653
|
+
for await (const event of inner) {
|
|
6654
|
+
if (!fired && event.type !== "system") {
|
|
6655
|
+
fired = true;
|
|
6656
|
+
await onFirst();
|
|
6657
|
+
}
|
|
6658
|
+
yield event;
|
|
6659
|
+
}
|
|
6660
|
+
}
|
|
6661
|
+
async function runSdkQuery(host, context, followUpContent, promptDeliveryOverride) {
|
|
6518
6662
|
if (host.isStopped()) return;
|
|
6519
6663
|
const mode = host.agentMode;
|
|
6520
6664
|
const isDiscoveryLike = mode === "discovery" || mode === "help";
|
|
@@ -6522,10 +6666,24 @@ async function runSdkQuery(host, context, followUpContent) {
|
|
|
6522
6666
|
if (needsPlanSync) {
|
|
6523
6667
|
host.snapshotPlanFiles();
|
|
6524
6668
|
}
|
|
6525
|
-
const sessionUuid = taskIdToSessionUuid(
|
|
6669
|
+
const sessionUuid = taskIdToSessionUuid(
|
|
6670
|
+
sessionLineageKey(context.taskId, mode, host.config.mode)
|
|
6671
|
+
);
|
|
6526
6672
|
const hasExistingSession = sessionFileExists(sessionUuid, host.config.workspaceDir);
|
|
6673
|
+
if (hasExistingSession) {
|
|
6674
|
+
repairTornSessionFile(sessionTranscriptPath(host.config.workspaceDir, sessionUuid));
|
|
6675
|
+
}
|
|
6676
|
+
const promptDelivery = promptDeliveryOverride ?? resolvePromptDelivery({
|
|
6677
|
+
harnessKind: host.harnessKind,
|
|
6678
|
+
runnerMode: host.config.mode,
|
|
6679
|
+
isAuto: host.isAuto,
|
|
6680
|
+
agentMode: mode,
|
|
6681
|
+
isFollowUp: !!followUpContent,
|
|
6682
|
+
hasExistingSession
|
|
6683
|
+
});
|
|
6527
6684
|
const options = {
|
|
6528
6685
|
...buildQueryOptions(host, context),
|
|
6686
|
+
promptDelivery,
|
|
6529
6687
|
...hasExistingSession ? {} : { sessionId: sessionUuid }
|
|
6530
6688
|
};
|
|
6531
6689
|
const resume = hasExistingSession ? sessionUuid : void 0;
|
|
@@ -6536,33 +6694,45 @@ async function runSdkQuery(host, context, followUpContent) {
|
|
|
6536
6694
|
options: { ...options },
|
|
6537
6695
|
resume
|
|
6538
6696
|
});
|
|
6539
|
-
host
|
|
6540
|
-
|
|
6541
|
-
await runWithRetry(agentQuery, context, host, options);
|
|
6542
|
-
} finally {
|
|
6543
|
-
host.activeQuery = null;
|
|
6544
|
-
}
|
|
6545
|
-
} else if (isDiscoveryLike) {
|
|
6697
|
+
await trackAndRun(host, context, options, agentQuery);
|
|
6698
|
+
} else if (isDiscoveryLike && promptDelivery !== "prefill") {
|
|
6546
6699
|
return;
|
|
6547
6700
|
} else {
|
|
6548
|
-
|
|
6549
|
-
const prompt = buildMultimodalPrompt(initialPrompt, context);
|
|
6550
|
-
const agentQuery = host.harness.executeQuery({
|
|
6551
|
-
prompt: host.createInputStream(prompt),
|
|
6552
|
-
options: { ...options },
|
|
6553
|
-
resume
|
|
6554
|
-
});
|
|
6555
|
-
host.activeQuery = agentQuery;
|
|
6556
|
-
try {
|
|
6557
|
-
await runWithRetry(agentQuery, context, host, options);
|
|
6558
|
-
} finally {
|
|
6559
|
-
host.activeQuery = null;
|
|
6560
|
-
}
|
|
6701
|
+
await runInitialQuery(host, context, options, resume, promptDelivery);
|
|
6561
6702
|
}
|
|
6562
6703
|
if (needsPlanSync) {
|
|
6563
6704
|
await host.syncPlanFile();
|
|
6564
6705
|
}
|
|
6565
6706
|
}
|
|
6707
|
+
async function trackAndRun(host, context, options, agentQuery) {
|
|
6708
|
+
host.activeQuery = agentQuery;
|
|
6709
|
+
try {
|
|
6710
|
+
await runWithRetry(agentQuery, context, host, options);
|
|
6711
|
+
} finally {
|
|
6712
|
+
host.activeQuery = null;
|
|
6713
|
+
}
|
|
6714
|
+
}
|
|
6715
|
+
async function runInitialQuery(host, context, options, resume, promptDelivery) {
|
|
6716
|
+
const initialPrompt = await buildInitialPrompt(
|
|
6717
|
+
host.config.mode,
|
|
6718
|
+
context,
|
|
6719
|
+
host.isAuto,
|
|
6720
|
+
host.agentMode
|
|
6721
|
+
);
|
|
6722
|
+
const prompt = buildMultimodalPrompt(initialPrompt, context);
|
|
6723
|
+
let agentQuery = host.harness.executeQuery({
|
|
6724
|
+
prompt: host.createInputStream(prompt),
|
|
6725
|
+
options: { ...options },
|
|
6726
|
+
resume
|
|
6727
|
+
});
|
|
6728
|
+
if (promptDelivery === "prefill") {
|
|
6729
|
+
agentQuery = notifyOnFirstEvent(agentQuery, async () => {
|
|
6730
|
+
host.connection.emitStatus("running");
|
|
6731
|
+
await host.callbacks.onStatusChange("running");
|
|
6732
|
+
});
|
|
6733
|
+
}
|
|
6734
|
+
await trackAndRun(host, context, options, agentQuery);
|
|
6735
|
+
}
|
|
6566
6736
|
async function buildRetryQuery(host, context, options, lastErrorWasImage) {
|
|
6567
6737
|
if (lastErrorWasImage) {
|
|
6568
6738
|
host.connection.postChatMessage(
|
|
@@ -6901,6 +7071,7 @@ var QueryBridge = class {
|
|
|
6901
7071
|
this.runnerConfig = runnerConfig;
|
|
6902
7072
|
this.callbacks = callbacks;
|
|
6903
7073
|
const harnessKind = resolveHarnessKind();
|
|
7074
|
+
this.harnessKind = harnessKind;
|
|
6904
7075
|
this.harness = createHarness(
|
|
6905
7076
|
harnessKind,
|
|
6906
7077
|
harnessKind === "pty" ? buildPtyBridge(connection) : void 0
|
|
@@ -6913,6 +7084,7 @@ var QueryBridge = class {
|
|
|
6913
7084
|
runnerConfig;
|
|
6914
7085
|
callbacks;
|
|
6915
7086
|
harness;
|
|
7087
|
+
harnessKind;
|
|
6916
7088
|
costTracker;
|
|
6917
7089
|
planSync;
|
|
6918
7090
|
sessionIds = /* @__PURE__ */ new Map();
|
|
@@ -6956,18 +7128,40 @@ var QueryBridge = class {
|
|
|
6956
7128
|
seedCostTracker(totalCostUsd, modelUsage) {
|
|
6957
7129
|
this.costTracker.seed(totalCostUsd, modelUsage);
|
|
6958
7130
|
}
|
|
7131
|
+
/**
|
|
7132
|
+
* How the INITIAL instructions for this task would be delivered — "prefill"
|
|
7133
|
+
* means the TUI input is pre-filled but unsubmitted, awaiting the human.
|
|
7134
|
+
* Mirrors the decision runSdkQuery makes for the initial (non-follow-up)
|
|
7135
|
+
* query so SessionRunner can pick the matching state/timers.
|
|
7136
|
+
*/
|
|
7137
|
+
initialPromptDelivery(context) {
|
|
7138
|
+
return resolvePromptDelivery({
|
|
7139
|
+
harnessKind: this.harnessKind,
|
|
7140
|
+
runnerMode: this.runnerConfig.mode,
|
|
7141
|
+
isAuto: this.mode.isAuto,
|
|
7142
|
+
agentMode: this.mode.effectiveMode,
|
|
7143
|
+
isFollowUp: false,
|
|
7144
|
+
hasExistingSession: hasExistingSessionFile(context.taskId, this.runnerConfig.workspaceDir, {
|
|
7145
|
+
agentMode: this.mode.effectiveMode,
|
|
7146
|
+
runnerMode: this.runnerConfig.mode
|
|
7147
|
+
})
|
|
7148
|
+
});
|
|
7149
|
+
}
|
|
6959
7150
|
/**
|
|
6960
7151
|
* Execute a Claude SDK query.
|
|
6961
7152
|
* Without followUpContent: runs initial mode execution (build/plan).
|
|
6962
7153
|
* With followUpContent: processes a follow-up user message.
|
|
7154
|
+
* `promptDelivery` overrides the executor's submit-vs-prefill resolution —
|
|
7155
|
+
* SessionRunner forces "submit" when pending chat messages already direct
|
|
7156
|
+
* the agent (prefilling would park them until a human touched the TUI).
|
|
6963
7157
|
*/
|
|
6964
|
-
async execute(context, followUpContent) {
|
|
7158
|
+
async execute(context, followUpContent, promptDelivery) {
|
|
6965
7159
|
this._stopped = false;
|
|
6966
7160
|
this._wasRateLimited = false;
|
|
6967
7161
|
this._abortController = new AbortController();
|
|
6968
7162
|
const host = this.buildHost();
|
|
6969
7163
|
try {
|
|
6970
|
-
await runSdkQuery(host, context, followUpContent);
|
|
7164
|
+
await runSdkQuery(host, context, followUpContent, promptDelivery);
|
|
6971
7165
|
} catch (err) {
|
|
6972
7166
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6973
7167
|
const isAbort = this._stopped || /abort/i.test(msg);
|
|
@@ -6990,6 +7184,7 @@ var QueryBridge = class {
|
|
|
6990
7184
|
connection: this.connection,
|
|
6991
7185
|
callbacks: this.callbacks,
|
|
6992
7186
|
harness: this.harness,
|
|
7187
|
+
harnessKind: this.harnessKind,
|
|
6993
7188
|
setupLog: [],
|
|
6994
7189
|
costTracker: this.costTracker,
|
|
6995
7190
|
explorationTracker: bridge.mode.effectiveMode === "discovery" || bridge.mode.effectiveMode === "auto" && !bridge.mode.hasExitedPlanMode ? new ExplorationTracker(bridge._isParentTask) : null,
|
|
@@ -7061,8 +7256,8 @@ var QueryBridge = class {
|
|
|
7061
7256
|
};
|
|
7062
7257
|
|
|
7063
7258
|
// src/runner/session-runner-helpers.ts
|
|
7064
|
-
import { readFileSync as
|
|
7065
|
-
import { dirname, join as
|
|
7259
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
7260
|
+
import { dirname, join as join3 } from "path";
|
|
7066
7261
|
import { fileURLToPath } from "url";
|
|
7067
7262
|
function mapChatHistory(messages) {
|
|
7068
7263
|
if (!messages) return [];
|
|
@@ -7091,7 +7286,7 @@ function readAgentVersion() {
|
|
|
7091
7286
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
7092
7287
|
for (const rel of ["../package.json", "../../package.json"]) {
|
|
7093
7288
|
try {
|
|
7094
|
-
const pkg = JSON.parse(
|
|
7289
|
+
const pkg = JSON.parse(readFileSync3(join3(here, rel), "utf-8"));
|
|
7095
7290
|
if (pkg.version) return pkg.version;
|
|
7096
7291
|
} catch {
|
|
7097
7292
|
}
|
|
@@ -7183,6 +7378,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
7183
7378
|
onIdleTimeout: () => {
|
|
7184
7379
|
process.stderr.write("[conveyor-agent] Idle timeout reached, stopping agent\n");
|
|
7185
7380
|
this.stopped = true;
|
|
7381
|
+
this.queryBridge?.stop();
|
|
7186
7382
|
if (this.inputResolver) {
|
|
7187
7383
|
const resolver = this.inputResolver;
|
|
7188
7384
|
this.inputResolver = null;
|
|
@@ -7192,6 +7388,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
7192
7388
|
onDormantTimeout: () => {
|
|
7193
7389
|
process.stderr.write("[conveyor-agent] Dormant idle timeout reached, shutting down\n");
|
|
7194
7390
|
this.stopped = true;
|
|
7391
|
+
this.queryBridge?.stop();
|
|
7195
7392
|
if (this.inputResolver) {
|
|
7196
7393
|
const resolver = this.inputResolver;
|
|
7197
7394
|
this.inputResolver = null;
|
|
@@ -7276,6 +7473,13 @@ var SessionRunner = class _SessionRunner {
|
|
|
7276
7473
|
syncWithBaseBranch(this.config.workspaceDir, this.fullContext.baseBranch);
|
|
7277
7474
|
}
|
|
7278
7475
|
}
|
|
7476
|
+
if (this.fullContext?.githubBranch) {
|
|
7477
|
+
const restored = restoreWipSnapshot(this.config.workspaceDir, this.fullContext.githubBranch);
|
|
7478
|
+
if (restored !== "none") {
|
|
7479
|
+
process.stderr.write(`[conveyor-agent] WIP snapshot restore: ${restored}
|
|
7480
|
+
`);
|
|
7481
|
+
}
|
|
7482
|
+
}
|
|
7279
7483
|
this.mode.applyServerMode(this.fullContext?.agentMode, this.fullContext?.isAuto);
|
|
7280
7484
|
this.mode.resolveInitialMode(this.taskContext);
|
|
7281
7485
|
if (this.fullContext?.isAuto && this.taskContext.status === "Open" && this.mode.isBuildCapable) {
|
|
@@ -7290,6 +7494,12 @@ var SessionRunner = class _SessionRunner {
|
|
|
7290
7494
|
if (staleMessageCount > 0 && didExecuteInitialQuery) {
|
|
7291
7495
|
this.pendingMessages.splice(0, staleMessageCount);
|
|
7292
7496
|
}
|
|
7497
|
+
if (this.queryBridge?.isDiscoveryCompleted) {
|
|
7498
|
+
process.stderr.write(
|
|
7499
|
+
"[conveyor-agent] Discovery completed during initial query \u2014 entering idle\n"
|
|
7500
|
+
);
|
|
7501
|
+
this.queryBridge.isDiscoveryCompleted = false;
|
|
7502
|
+
}
|
|
7293
7503
|
if (!this.stopped && this.pendingMessages.length === 0) {
|
|
7294
7504
|
await this.maybeSendPRNudge();
|
|
7295
7505
|
}
|
|
@@ -7410,16 +7620,32 @@ var SessionRunner = class _SessionRunner {
|
|
|
7410
7620
|
async executeInitialMode() {
|
|
7411
7621
|
if (!this.taskContext || !this.fullContext) return false;
|
|
7412
7622
|
const effectiveMode = this.mode.effectiveMode;
|
|
7413
|
-
const
|
|
7414
|
-
|
|
7623
|
+
const delivery = this.pendingMessages.length > 0 ? "submit" : this.queryBridge?.initialPromptDelivery(this.fullContext) ?? "submit";
|
|
7624
|
+
const shouldRun = effectiveMode === "building" || effectiveMode === "auto" || effectiveMode === "review" || delivery === "prefill";
|
|
7625
|
+
if (!shouldRun) {
|
|
7626
|
+
await this.setState("idle");
|
|
7627
|
+
return false;
|
|
7628
|
+
}
|
|
7629
|
+
if (delivery === "prefill") {
|
|
7630
|
+
await this.setState("waiting_for_input");
|
|
7631
|
+
await this.callbacks.onEvent({ type: "execute_mode", mode: effectiveMode, delivery });
|
|
7632
|
+
if (this.pendingMessages.length > 0) {
|
|
7633
|
+
if (!this.stopped) await this.setState("idle");
|
|
7634
|
+
return false;
|
|
7635
|
+
}
|
|
7636
|
+
this.lifecycle.startIdleTimer();
|
|
7637
|
+
try {
|
|
7638
|
+
await this.executeQuery(void 0, delivery);
|
|
7639
|
+
} finally {
|
|
7640
|
+
this.lifecycle.cancelIdleTimer();
|
|
7641
|
+
}
|
|
7642
|
+
} else {
|
|
7415
7643
|
await this.setState("running");
|
|
7416
7644
|
await this.callbacks.onEvent({ type: "execute_mode", mode: effectiveMode });
|
|
7417
|
-
await this.executeQuery();
|
|
7418
|
-
if (!this.stopped) await this.setState("idle");
|
|
7419
|
-
return true;
|
|
7645
|
+
await this.executeQuery(void 0, delivery);
|
|
7420
7646
|
}
|
|
7421
|
-
await this.setState("idle");
|
|
7422
|
-
return
|
|
7647
|
+
if (!this.stopped) await this.setState("idle");
|
|
7648
|
+
return true;
|
|
7423
7649
|
}
|
|
7424
7650
|
// ── Message waiting ────────────────────────────────────────────────
|
|
7425
7651
|
waitForMessage() {
|
|
@@ -7438,17 +7664,17 @@ var SessionRunner = class _SessionRunner {
|
|
|
7438
7664
|
resolve2(msg);
|
|
7439
7665
|
} else {
|
|
7440
7666
|
this.pendingMessages.push(msg);
|
|
7441
|
-
if (this._state === "running") {
|
|
7667
|
+
if (this._state === "running" || this._state === "waiting_for_input") {
|
|
7442
7668
|
this.queryBridge?.stop();
|
|
7443
7669
|
}
|
|
7444
7670
|
}
|
|
7445
7671
|
}
|
|
7446
7672
|
// ── Query execution with abort handling ────────────────────────────
|
|
7447
7673
|
/** Run queryBridge.execute, swallowing abort errors from stop/softStop. */
|
|
7448
|
-
async executeQuery(followUpContent) {
|
|
7674
|
+
async executeQuery(followUpContent, promptDelivery) {
|
|
7449
7675
|
if (!this.fullContext || !this.queryBridge) return;
|
|
7450
7676
|
try {
|
|
7451
|
-
await this.queryBridge.execute(this.fullContext, followUpContent);
|
|
7677
|
+
await this.queryBridge.execute(this.fullContext, followUpContent, promptDelivery);
|
|
7452
7678
|
} catch (err) {
|
|
7453
7679
|
if (this.interrupted || this.stopped) {
|
|
7454
7680
|
process.stderr.write("[conveyor-agent] Query aborted by stop/softStop signal\n");
|
|
@@ -7647,7 +7873,13 @@ var SessionRunner = class _SessionRunner {
|
|
|
7647
7873
|
this.mode,
|
|
7648
7874
|
runnerConfig,
|
|
7649
7875
|
{
|
|
7650
|
-
onStatusChange: (status) =>
|
|
7876
|
+
onStatusChange: (status) => {
|
|
7877
|
+
if (status === "running" && this._state === "waiting_for_input") {
|
|
7878
|
+
this._state = "running";
|
|
7879
|
+
this.lifecycle.cancelIdleTimer();
|
|
7880
|
+
}
|
|
7881
|
+
return this.callbacks.onStatusChange(status);
|
|
7882
|
+
},
|
|
7651
7883
|
onEvent: (event) => {
|
|
7652
7884
|
if (event.type === "completed") {
|
|
7653
7885
|
this.completedThisTurn = true;
|
|
@@ -8104,13 +8336,13 @@ var CommitWatcher = class {
|
|
|
8104
8336
|
// src/runner/worktree.ts
|
|
8105
8337
|
import { execSync as execSync4 } from "child_process";
|
|
8106
8338
|
import { existsSync as existsSync2 } from "fs";
|
|
8107
|
-
import { join as
|
|
8339
|
+
import { join as join4 } from "path";
|
|
8108
8340
|
var WORKTREE_DIR = ".worktrees";
|
|
8109
8341
|
function ensureWorktree(projectDir, taskId, branch) {
|
|
8110
8342
|
if (projectDir.includes(`/${WORKTREE_DIR}/`)) {
|
|
8111
8343
|
return projectDir;
|
|
8112
8344
|
}
|
|
8113
|
-
const worktreePath =
|
|
8345
|
+
const worktreePath = join4(projectDir, WORKTREE_DIR, taskId);
|
|
8114
8346
|
if (existsSync2(worktreePath)) {
|
|
8115
8347
|
if (branch) {
|
|
8116
8348
|
if (hasUncommittedChanges(worktreePath)) {
|
|
@@ -8156,7 +8388,7 @@ function detachWorktreeBranch(projectDir, branch) {
|
|
|
8156
8388
|
}
|
|
8157
8389
|
}
|
|
8158
8390
|
function removeWorktree(projectDir, taskId) {
|
|
8159
|
-
const worktreePath =
|
|
8391
|
+
const worktreePath = join4(projectDir, WORKTREE_DIR, taskId);
|
|
8160
8392
|
if (!existsSync2(worktreePath)) return;
|
|
8161
8393
|
try {
|
|
8162
8394
|
execSync4(`git worktree remove "${worktreePath}" --force`, {
|
|
@@ -9838,7 +10070,7 @@ var ProjectRunner = class {
|
|
|
9838
10070
|
async handleAuditTags(request) {
|
|
9839
10071
|
this.connection.emitStatus("busy");
|
|
9840
10072
|
try {
|
|
9841
|
-
const { handleTagAudit } = await import("./tag-audit-handler-
|
|
10073
|
+
const { handleTagAudit } = await import("./tag-audit-handler-RFGGQWG6.js");
|
|
9842
10074
|
await handleTagAudit(request, this.connection, this.projectDir);
|
|
9843
10075
|
} catch (error) {
|
|
9844
10076
|
const msg = parseErrorMessage(error);
|
|
@@ -9861,7 +10093,7 @@ var ProjectRunner = class {
|
|
|
9861
10093
|
async handleAuditTasks(request) {
|
|
9862
10094
|
this.connection.emitStatus("busy");
|
|
9863
10095
|
try {
|
|
9864
|
-
const { handleTaskAudit } = await import("./task-audit-handler-
|
|
10096
|
+
const { handleTaskAudit } = await import("./task-audit-handler-BN42VOYM.js");
|
|
9865
10097
|
await handleTaskAudit(request, this.connection, this.projectDir);
|
|
9866
10098
|
} catch (error) {
|
|
9867
10099
|
const msg = parseErrorMessage(error);
|
|
@@ -9910,12 +10142,12 @@ var ProjectRunner = class {
|
|
|
9910
10142
|
|
|
9911
10143
|
// src/setup/config.ts
|
|
9912
10144
|
import { readFile as readFile3 } from "fs/promises";
|
|
9913
|
-
import { join as
|
|
10145
|
+
import { join as join5 } from "path";
|
|
9914
10146
|
var DEVCONTAINER_PATH = ".devcontainer/conveyor/devcontainer.json";
|
|
9915
10147
|
var DEVCONTAINER_PORT_DENY_LIST = /* @__PURE__ */ new Set([5432, 6379, 9200]);
|
|
9916
10148
|
async function loadForwardPorts(workspaceDir) {
|
|
9917
10149
|
try {
|
|
9918
|
-
const raw = await readFile3(
|
|
10150
|
+
const raw = await readFile3(join5(workspaceDir, DEVCONTAINER_PATH), "utf-8");
|
|
9919
10151
|
const parsed = JSON.parse(raw);
|
|
9920
10152
|
const ports = (parsed.forwardPorts ?? []).filter(
|
|
9921
10153
|
(p) => typeof p === "number" && !DEVCONTAINER_PORT_DENY_LIST.has(p)
|
|
@@ -10002,4 +10234,4 @@ export {
|
|
|
10002
10234
|
loadConveyorConfig,
|
|
10003
10235
|
unshallowRepo
|
|
10004
10236
|
};
|
|
10005
|
-
//# sourceMappingURL=chunk-
|
|
10237
|
+
//# sourceMappingURL=chunk-WNPFZC3I.js.map
|