@sideboard-ai/core 0.1.211 → 0.1.213
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/{agents-GQANI7M5.js → agents-HETHRRZJ.js} +4 -4
- package/dist/{agents-A2U3K7VK.js → agents-WBDDLRBY.js} +4 -4
- package/dist/{chunk-JJ3ONQ4Q.js → chunk-3IMSQNTS.js} +12 -2
- package/dist/{chunk-IA5IPGZI.js → chunk-7MTVRNP4.js} +3 -3
- package/dist/{chunk-KZUA4QG2.js → chunk-C32SBNA3.js} +198 -97
- package/dist/{chunk-ERNK7AWM.js → chunk-D2IKXMF3.js} +196 -96
- package/dist/{chunk-IRCAWYTN.js → chunk-DFTVZEZY.js} +3 -3
- package/dist/{chunk-2PE6SZCM.js → chunk-FNGXKY5W.js} +2 -2
- package/dist/{chunk-GHKFSBES.js → chunk-HY2GFZ5S.js} +12 -2
- package/dist/{chunk-WNVQJZ7P.js → chunk-KFD2OXCE.js} +2 -2
- package/dist/{chunk-NRKDRQM3.js → chunk-NI243N27.js} +1 -1
- package/dist/{chunk-VPQXJYIW.js → chunk-XYKVRRC2.js} +1 -1
- package/dist/{coordinator-prompt-LMTMWCPN.js → coordinator-prompt-FQX6ALAI.js} +3 -3
- package/dist/{coordinator-prompt-EHRDZ2ZU.js → coordinator-prompt-LE2GQZ2X.js} +3 -3
- package/dist/{global-workspace-NG2TBUI5.js → global-workspace-6P236KKG.js} +3 -3
- package/dist/{global-workspace-RHABXQWB.js → global-workspace-KT3FRHZL.js} +3 -3
- package/dist/index.cjs +210 -88
- package/dist/index.d.cts +61 -6
- package/dist/index.d.ts +61 -6
- package/dist/index.js +11 -5
- package/dist/mcp/run-stdio.cjs +204 -88
- package/dist/mcp/run-stdio.js +5 -5
- package/dist/{orchestrator-NZO4PVFH.js → orchestrator-MI7A5DQZ.js} +7 -5
- package/dist/{orchestrator-QMGH4V4K.js → orchestrator-WVZPTHBV.js} +7 -5
- package/dist/{thread-store-MSMBQ3V4.js → thread-store-KDPPXJJ3.js} +3 -1
- package/dist/{thread-store-4M6WETL6.js → thread-store-N6WQIWZ4.js} +3 -1
- package/dist/{workspaces-VIUUE4RT.js → workspaces-KM7KTLVO.js} +3 -3
- package/dist/{workspaces-FRR6Y4BY.js → workspaces-R5LJCJRB.js} +3 -3
- package/dist/{worktree-GKUOHXXB.js → worktree-MDMTCAHX.js} +2 -2
- package/dist/{worktree-3MEG62KB.js → worktree-VXRI7LYM.js} +2 -2
- package/package.json +1 -1
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
summarizeTurnStderr,
|
|
43
43
|
toolDescription,
|
|
44
44
|
turnFailChatText
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-7MTVRNP4.js";
|
|
46
46
|
import {
|
|
47
47
|
SLACK_REPLY_FORMATTING,
|
|
48
48
|
addWorkspace,
|
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
stageAbsolutePathsAsAttachments,
|
|
66
66
|
stageBuffersAsAttachments,
|
|
67
67
|
syncWorkspacesFromThreads
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-KFD2OXCE.js";
|
|
69
69
|
import {
|
|
70
70
|
addPrStackLayer,
|
|
71
71
|
allocateTeamName,
|
|
@@ -115,7 +115,7 @@ import {
|
|
|
115
115
|
worktreeDisplayLabelForGroup,
|
|
116
116
|
worktreeNameFromPath,
|
|
117
117
|
worktreeSlugForTicket
|
|
118
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-XYKVRRC2.js";
|
|
119
119
|
import {
|
|
120
120
|
ATTACHMENTS_DIR,
|
|
121
121
|
DETACHED_JOBS_DIR,
|
|
@@ -133,7 +133,7 @@ import {
|
|
|
133
133
|
updateThread,
|
|
134
134
|
withThreadLock,
|
|
135
135
|
writeThread
|
|
136
|
-
} from "./chunk-
|
|
136
|
+
} from "./chunk-HY2GFZ5S.js";
|
|
137
137
|
import {
|
|
138
138
|
ensureWorktreeSideboardIgnored
|
|
139
139
|
} from "./chunk-SYFVUF2C.js";
|
|
@@ -417,7 +417,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
417
417
|
await continueOnReply(threadId, prompt);
|
|
418
418
|
return;
|
|
419
419
|
}
|
|
420
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
420
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-MI7A5DQZ.js");
|
|
421
421
|
await getOrchestrator2().send(threadId, prompt);
|
|
422
422
|
} catch {
|
|
423
423
|
}
|
|
@@ -810,9 +810,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
810
810
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
811
811
|
);
|
|
812
812
|
}
|
|
813
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
813
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-KT3FRHZL.js");
|
|
814
814
|
if (isGlobalThread2(thread)) {
|
|
815
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
815
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-LE2GQZ2X.js");
|
|
816
816
|
ensureGlobalCoordinatorCwd2(
|
|
817
817
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
818
818
|
);
|
|
@@ -2317,6 +2317,29 @@ ${line}` : line;
|
|
|
2317
2317
|
}
|
|
2318
2318
|
var memory = /* @__PURE__ */ new Map();
|
|
2319
2319
|
var persistTimers = /* @__PURE__ */ new Map();
|
|
2320
|
+
function fromSnapshot(snap) {
|
|
2321
|
+
return {
|
|
2322
|
+
chunks: snap.output ? [snap.output] : [],
|
|
2323
|
+
length: snap.output.length,
|
|
2324
|
+
running: snap.running,
|
|
2325
|
+
exitCode: snap.exitCode,
|
|
2326
|
+
source: snap.source
|
|
2327
|
+
};
|
|
2328
|
+
}
|
|
2329
|
+
function materialize(mem) {
|
|
2330
|
+
let output = mem.chunks.join("\n");
|
|
2331
|
+
if (output.length > MAX_SETUP_LOG_CHARS) {
|
|
2332
|
+
output = appendSetupOutput("", output);
|
|
2333
|
+
mem.chunks = [output];
|
|
2334
|
+
mem.length = output.length;
|
|
2335
|
+
}
|
|
2336
|
+
return {
|
|
2337
|
+
output,
|
|
2338
|
+
running: mem.running,
|
|
2339
|
+
exitCode: mem.exitCode,
|
|
2340
|
+
source: mem.source
|
|
2341
|
+
};
|
|
2342
|
+
}
|
|
2320
2343
|
function setupLogPath(threadId) {
|
|
2321
2344
|
return join7(threadsDir(), `${threadId}.setup.log.json`);
|
|
2322
2345
|
}
|
|
@@ -2327,20 +2350,22 @@ function setupLogKeyForWorktree(worktreePath) {
|
|
|
2327
2350
|
function emptySetupLog() {
|
|
2328
2351
|
return { ...EMPTY };
|
|
2329
2352
|
}
|
|
2330
|
-
|
|
2331
|
-
return { ...snap };
|
|
2332
|
-
}
|
|
2353
|
+
var PERSIST_DEBOUNCE_MS = 500;
|
|
2333
2354
|
function persistNow(threadId) {
|
|
2334
2355
|
const timer = persistTimers.get(threadId);
|
|
2335
2356
|
if (timer) {
|
|
2336
2357
|
clearTimeout(timer);
|
|
2337
2358
|
persistTimers.delete(threadId);
|
|
2338
2359
|
}
|
|
2339
|
-
const
|
|
2340
|
-
if (!
|
|
2360
|
+
const mem = memory.get(threadId);
|
|
2361
|
+
if (!mem) return;
|
|
2341
2362
|
try {
|
|
2342
|
-
writeFileSync2(
|
|
2343
|
-
|
|
2363
|
+
writeFileSync2(
|
|
2364
|
+
setupLogPath(threadId),
|
|
2365
|
+
`${JSON.stringify(materialize(mem))}
|
|
2366
|
+
`,
|
|
2367
|
+
"utf8"
|
|
2368
|
+
);
|
|
2344
2369
|
} catch {
|
|
2345
2370
|
}
|
|
2346
2371
|
}
|
|
@@ -2351,7 +2376,7 @@ function schedulePersist(threadId) {
|
|
|
2351
2376
|
setTimeout(() => {
|
|
2352
2377
|
persistTimers.delete(threadId);
|
|
2353
2378
|
persistNow(threadId);
|
|
2354
|
-
},
|
|
2379
|
+
}, PERSIST_DEBOUNCE_MS)
|
|
2355
2380
|
);
|
|
2356
2381
|
}
|
|
2357
2382
|
function loadFromDisk(threadId) {
|
|
@@ -2369,49 +2394,50 @@ function loadFromDisk(threadId) {
|
|
|
2369
2394
|
return null;
|
|
2370
2395
|
}
|
|
2371
2396
|
}
|
|
2397
|
+
function memFor(threadId) {
|
|
2398
|
+
const cached = memory.get(threadId);
|
|
2399
|
+
if (cached) return cached;
|
|
2400
|
+
const mem = fromSnapshot(loadFromDisk(threadId) ?? emptySetupLog());
|
|
2401
|
+
memory.set(threadId, mem);
|
|
2402
|
+
return mem;
|
|
2403
|
+
}
|
|
2372
2404
|
function readSetupLog(threadId) {
|
|
2373
2405
|
const cached = memory.get(threadId);
|
|
2374
|
-
if (cached) return
|
|
2406
|
+
if (cached) return materialize(cached);
|
|
2375
2407
|
const disk = loadFromDisk(threadId);
|
|
2376
2408
|
if (disk) {
|
|
2377
|
-
memory.set(threadId, disk);
|
|
2378
|
-
return
|
|
2409
|
+
memory.set(threadId, fromSnapshot(disk));
|
|
2410
|
+
return disk;
|
|
2379
2411
|
}
|
|
2380
2412
|
return emptySetupLog();
|
|
2381
2413
|
}
|
|
2382
2414
|
function beginSetupLog(threadId) {
|
|
2383
|
-
const
|
|
2384
|
-
|
|
2415
|
+
const mem = {
|
|
2416
|
+
chunks: [],
|
|
2417
|
+
length: 0,
|
|
2385
2418
|
running: true,
|
|
2386
2419
|
exitCode: null,
|
|
2387
2420
|
source: null
|
|
2388
2421
|
};
|
|
2389
|
-
memory.set(threadId,
|
|
2422
|
+
memory.set(threadId, mem);
|
|
2390
2423
|
persistNow(threadId);
|
|
2391
|
-
return
|
|
2424
|
+
return materialize(mem);
|
|
2392
2425
|
}
|
|
2393
2426
|
function appendSetupLog(threadId, line) {
|
|
2394
|
-
const
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
};
|
|
2400
|
-
memory.set(threadId, snap);
|
|
2427
|
+
const mem = memFor(threadId);
|
|
2428
|
+
mem.chunks.push(line);
|
|
2429
|
+
mem.length += line.length + 1;
|
|
2430
|
+
mem.running = true;
|
|
2431
|
+
if (mem.length > MAX_SETUP_LOG_CHARS * 2) materialize(mem);
|
|
2401
2432
|
schedulePersist(threadId);
|
|
2402
|
-
return clone(snap);
|
|
2403
2433
|
}
|
|
2404
2434
|
function finishSetupLog(threadId, exitCode, source) {
|
|
2405
|
-
const
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
exitCode,
|
|
2410
|
-
source: source ?? current.source
|
|
2411
|
-
};
|
|
2412
|
-
memory.set(threadId, snap);
|
|
2435
|
+
const mem = memFor(threadId);
|
|
2436
|
+
mem.running = false;
|
|
2437
|
+
mem.exitCode = exitCode;
|
|
2438
|
+
mem.source = source ?? mem.source;
|
|
2413
2439
|
persistNow(threadId);
|
|
2414
|
-
return
|
|
2440
|
+
return materialize(mem);
|
|
2415
2441
|
}
|
|
2416
2442
|
|
|
2417
2443
|
// src/git/orphan-cleanup.ts
|
|
@@ -3903,6 +3929,33 @@ function shouldRemoveWorktreeOnTeardown(thread) {
|
|
|
3903
3929
|
return !isCowboyThread(thread) && !isPrimaryCheckoutThread(thread);
|
|
3904
3930
|
}
|
|
3905
3931
|
|
|
3932
|
+
// src/util/line-coalescer.ts
|
|
3933
|
+
function createLineCoalescer(onChunk, opts) {
|
|
3934
|
+
const delayMs = opts?.delayMs ?? 50;
|
|
3935
|
+
const maxLines = opts?.maxLines ?? 200;
|
|
3936
|
+
let buffer = [];
|
|
3937
|
+
let timer = null;
|
|
3938
|
+
const flush2 = () => {
|
|
3939
|
+
if (timer) {
|
|
3940
|
+
clearTimeout(timer);
|
|
3941
|
+
timer = null;
|
|
3942
|
+
}
|
|
3943
|
+
if (buffer.length === 0) return;
|
|
3944
|
+
const chunk = buffer.join("\n");
|
|
3945
|
+
buffer = [];
|
|
3946
|
+
onChunk(chunk);
|
|
3947
|
+
};
|
|
3948
|
+
const push = (line) => {
|
|
3949
|
+
buffer.push(line);
|
|
3950
|
+
if (buffer.length >= maxLines) {
|
|
3951
|
+
flush2();
|
|
3952
|
+
return;
|
|
3953
|
+
}
|
|
3954
|
+
if (!timer) timer = setTimeout(flush2, delayMs);
|
|
3955
|
+
};
|
|
3956
|
+
return { push, flush: flush2 };
|
|
3957
|
+
}
|
|
3958
|
+
|
|
3906
3959
|
// src/store/turn-live.ts
|
|
3907
3960
|
import {
|
|
3908
3961
|
existsSync as existsSync11,
|
|
@@ -4314,7 +4367,7 @@ async function adoptThread(input) {
|
|
|
4314
4367
|
messages: input.messages ?? []
|
|
4315
4368
|
});
|
|
4316
4369
|
writeThread(thread);
|
|
4317
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
4370
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-KM7KTLVO.js");
|
|
4318
4371
|
await ensureWorkspace2(repoPath);
|
|
4319
4372
|
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
|
|
4320
4373
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
@@ -5521,6 +5574,29 @@ function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
|
5521
5574
|
writeFileSync6(abs, content, "utf8");
|
|
5522
5575
|
return { path: relativePath };
|
|
5523
5576
|
}
|
|
5577
|
+
async function getWorktreeDirtyStat(worktreePath) {
|
|
5578
|
+
const status = await inspectGitWorktree(worktreePath);
|
|
5579
|
+
if (status !== "ok") {
|
|
5580
|
+
return { additions: 0, deletions: 0, dirty: false };
|
|
5581
|
+
}
|
|
5582
|
+
const head = await git(["rev-parse", "--verify", "HEAD"], worktreePath, {
|
|
5583
|
+
reject: false,
|
|
5584
|
+
timeoutMs: 4e3
|
|
5585
|
+
});
|
|
5586
|
+
if (head.exitCode !== 0) {
|
|
5587
|
+
return { additions: 0, deletions: 0, dirty: await isDirty(worktreePath) };
|
|
5588
|
+
}
|
|
5589
|
+
const [num, dirty] = await Promise.all([
|
|
5590
|
+
gitDiff(["--numstat", "HEAD"], worktreePath, { timeoutMs: 4e3 }),
|
|
5591
|
+
isDirty(worktreePath)
|
|
5592
|
+
]);
|
|
5593
|
+
const counts = statFromNumstat(num.stdout);
|
|
5594
|
+
return {
|
|
5595
|
+
additions: counts.additions,
|
|
5596
|
+
deletions: counts.deletions,
|
|
5597
|
+
dirty: dirty || counts.additions > 0 || counts.deletions > 0
|
|
5598
|
+
};
|
|
5599
|
+
}
|
|
5524
5600
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
5525
5601
|
const full = await getDiff(worktreePath, repoPath, {
|
|
5526
5602
|
maxHunkChars: opts?.maxHunkChars ?? 2e3,
|
|
@@ -6067,9 +6143,7 @@ function consumeComposerAttachments(thread) {
|
|
|
6067
6143
|
};
|
|
6068
6144
|
}
|
|
6069
6145
|
function takePendingTurnAttachments(thread) {
|
|
6070
|
-
|
|
6071
|
-
if (pending.length > 0) return [...pending];
|
|
6072
|
-
return thread.attachments.length > 0 ? [...thread.attachments] : [];
|
|
6146
|
+
return [...thread.pendingTurnAttachments ?? []];
|
|
6073
6147
|
}
|
|
6074
6148
|
function alignQueueAttachments(queueLength, existing) {
|
|
6075
6149
|
const next = (existing ?? []).slice(0, queueLength).map((slot) => [...slot ?? []]);
|
|
@@ -6746,7 +6820,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
6746
6820
|
${prompt}`;
|
|
6747
6821
|
}
|
|
6748
6822
|
async function defaultDeps() {
|
|
6749
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
6823
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-MI7A5DQZ.js");
|
|
6750
6824
|
const orch = getOrchestrator2();
|
|
6751
6825
|
return {
|
|
6752
6826
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -6877,6 +6951,7 @@ function resolveOrchChildFollowUp(requested) {
|
|
|
6877
6951
|
return followUpBehavior();
|
|
6878
6952
|
}
|
|
6879
6953
|
var STALE_AGENT_PID_WAIT_MS = 2500;
|
|
6954
|
+
var LIGHT_RECONCILE_THROTTLE_MS = 1e4;
|
|
6880
6955
|
function writeLiveStatus(threadId, status, lastError) {
|
|
6881
6956
|
const latest = readThread(threadId);
|
|
6882
6957
|
if (!latest || latest.status === "archived") return latest;
|
|
@@ -6891,6 +6966,8 @@ var Orchestrator = class {
|
|
|
6891
6966
|
startingTurns = /* @__PURE__ */ new Set();
|
|
6892
6967
|
/** Last sync thread-file read for false-stop heal (throttled per thread). */
|
|
6893
6968
|
lastReconcileHealAt = /* @__PURE__ */ new Map();
|
|
6969
|
+
/** Per-repo timestamp of the last `reconcile(repo, { light: true })`. */
|
|
6970
|
+
lightReconcileAt = /* @__PURE__ */ new Map();
|
|
6894
6971
|
/**
|
|
6895
6972
|
* Threads intentionally force-stopped. Prevents runTurn from re-asserting
|
|
6896
6973
|
* `running` after spawn, and from overwriting `stopped` with idle/error when
|
|
@@ -6976,6 +7053,20 @@ var Orchestrator = class {
|
|
|
6976
7053
|
async reconcile(repoPath, opts) {
|
|
6977
7054
|
const reclaimStaleTurns = opts?.reclaimStaleTurns === true;
|
|
6978
7055
|
const drainQueues = opts?.drainQueues !== false;
|
|
7056
|
+
if (opts?.light && repoPath) {
|
|
7057
|
+
const last = this.lightReconcileAt.get(repoPath) ?? 0;
|
|
7058
|
+
if (Date.now() - last < LIGHT_RECONCILE_THROTTLE_MS) return;
|
|
7059
|
+
this.lightReconcileAt.set(repoPath, Date.now());
|
|
7060
|
+
for (const thread of listThreads()) {
|
|
7061
|
+
if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
|
|
7062
|
+
if (!existsSync19(thread.worktreePath)) {
|
|
7063
|
+
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
7064
|
+
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
7065
|
+
}
|
|
7066
|
+
}
|
|
7067
|
+
await this.reconcileOrphans([repoPath]);
|
|
7068
|
+
return;
|
|
7069
|
+
}
|
|
6979
7070
|
healOrchestrationSoccerTitles();
|
|
6980
7071
|
for (const thread of listThreads({ includeArchived: true })) {
|
|
6981
7072
|
if (thread.status === "archived") continue;
|
|
@@ -7008,6 +7099,21 @@ var Orchestrator = class {
|
|
|
7008
7099
|
}
|
|
7009
7100
|
}
|
|
7010
7101
|
const repoPaths = (repoPath ? [repoPath] : [...new Set(listThreads({ includeArchived: true }).map((t) => t.repoPath))]).filter((p) => !isGlobalRepoPath(p));
|
|
7102
|
+
await this.reconcileOrphans(repoPaths);
|
|
7103
|
+
try {
|
|
7104
|
+
if (shouldRunHistoryCleanup()) {
|
|
7105
|
+
cleanupArchivedHistory();
|
|
7106
|
+
}
|
|
7107
|
+
} catch {
|
|
7108
|
+
}
|
|
7109
|
+
if (drainQueues) {
|
|
7110
|
+
this.adoptPersistedQueues();
|
|
7111
|
+
}
|
|
7112
|
+
this.schedulePendingQuotaResumes();
|
|
7113
|
+
armSchedules();
|
|
7114
|
+
}
|
|
7115
|
+
/** Surface (and, when enabled, clean up) worktrees git knows about but no thread owns. */
|
|
7116
|
+
async reconcileOrphans(repoPaths) {
|
|
7011
7117
|
try {
|
|
7012
7118
|
const orphans = await findOrphanWorktrees(repoPaths);
|
|
7013
7119
|
if (orphans.length) {
|
|
@@ -7022,17 +7128,6 @@ var Orchestrator = class {
|
|
|
7022
7128
|
}
|
|
7023
7129
|
} catch {
|
|
7024
7130
|
}
|
|
7025
|
-
try {
|
|
7026
|
-
if (shouldRunHistoryCleanup()) {
|
|
7027
|
-
cleanupArchivedHistory();
|
|
7028
|
-
}
|
|
7029
|
-
} catch {
|
|
7030
|
-
}
|
|
7031
|
-
if (drainQueues) {
|
|
7032
|
-
this.adoptPersistedQueues();
|
|
7033
|
-
}
|
|
7034
|
-
this.schedulePendingQuotaResumes();
|
|
7035
|
-
armSchedules();
|
|
7036
7131
|
}
|
|
7037
7132
|
/**
|
|
7038
7133
|
* Adopt queues persisted by another process (MCP stdio / CLI) into this
|
|
@@ -7266,7 +7361,7 @@ var Orchestrator = class {
|
|
|
7266
7361
|
return listThreads({ includeArchived });
|
|
7267
7362
|
}
|
|
7268
7363
|
getThread(idOrRef) {
|
|
7269
|
-
return
|
|
7364
|
+
return readThread(idOrRef) ?? findThreadByRef(idOrRef);
|
|
7270
7365
|
}
|
|
7271
7366
|
async createThread(input) {
|
|
7272
7367
|
const prior = new Set(
|
|
@@ -7437,9 +7532,11 @@ var Orchestrator = class {
|
|
|
7437
7532
|
const inFlight = this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id);
|
|
7438
7533
|
updateThread(thread.id, {
|
|
7439
7534
|
...removed,
|
|
7440
|
-
//
|
|
7441
|
-
//
|
|
7442
|
-
|
|
7535
|
+
// Follow-up files live on queueAttachments. pendingTurnAttachments is
|
|
7536
|
+
// the in-flight / just-dequeued snapshot — do not wipe it when a
|
|
7537
|
+
// later follow-up is removed. Only drop a leftover bag when nothing
|
|
7538
|
+
// is running and the queue is empty (legacy sends that never drained).
|
|
7539
|
+
...stillQueued || inFlight ? {} : { pendingTurnAttachments: [] },
|
|
7443
7540
|
status: !stillQueued && !inFlight && current.status === "queued" ? "idle" : current.status
|
|
7444
7541
|
});
|
|
7445
7542
|
this.emit({ type: "queue_changed", threadId: thread.id, queue: removed.queue });
|
|
@@ -7521,7 +7618,9 @@ var Orchestrator = class {
|
|
|
7521
7618
|
updateThread(threadId, {
|
|
7522
7619
|
queue: shifted.queue,
|
|
7523
7620
|
queueAttachments: shifted.queueAttachments,
|
|
7524
|
-
|
|
7621
|
+
// Always write the snapshot, including [] for text-only, so
|
|
7622
|
+
// takePending cannot fall back to leftover pending or composer files.
|
|
7623
|
+
pendingTurnAttachments: shifted.attachments
|
|
7525
7624
|
});
|
|
7526
7625
|
this.emit({ type: "queue_changed", threadId, queue: shifted.queue });
|
|
7527
7626
|
await this.runTurn(threadId, shifted.prompt);
|
|
@@ -7569,7 +7668,6 @@ var Orchestrator = class {
|
|
|
7569
7668
|
thread = this.requireThread(threadId);
|
|
7570
7669
|
}
|
|
7571
7670
|
const autoContinue = isJobContinuePrompt(prompt) || prompt.trim().startsWith("The previous agent process ended before it finished.");
|
|
7572
|
-
const parkedSnapshot = thread.pendingTurnAttachments ?? [];
|
|
7573
7671
|
const parked = takePendingTurnAttachments(thread);
|
|
7574
7672
|
const sentAttachments = !autoContinue && parked.length > 0 ? parked : void 0;
|
|
7575
7673
|
appendMessage(threadId, {
|
|
@@ -7585,7 +7683,7 @@ var Orchestrator = class {
|
|
|
7585
7683
|
thread.worktreePath,
|
|
7586
7684
|
gitPrompt,
|
|
7587
7685
|
{
|
|
7588
|
-
attachments: autoContinue ? [] : sentAttachments ??
|
|
7686
|
+
attachments: autoContinue ? [] : sentAttachments ?? []
|
|
7589
7687
|
}
|
|
7590
7688
|
);
|
|
7591
7689
|
const slackInbound = /^(Slack DM|Slack @mention)(?:\n|$)/.test(
|
|
@@ -7639,10 +7737,7 @@ var Orchestrator = class {
|
|
|
7639
7737
|
expandedPrompt
|
|
7640
7738
|
].filter(Boolean).join("\n\n");
|
|
7641
7739
|
if (!autoContinue && sentAttachments) {
|
|
7642
|
-
updateThread(
|
|
7643
|
-
threadId,
|
|
7644
|
-
parkedSnapshot.length > 0 ? { pendingTurnAttachments: [] } : { attachments: [], pendingTurnAttachments: [] }
|
|
7645
|
-
);
|
|
7740
|
+
updateThread(threadId, { pendingTurnAttachments: [] });
|
|
7646
7741
|
}
|
|
7647
7742
|
const adapter = getAdapter(thread.agent);
|
|
7648
7743
|
const resolved = await adapter.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
@@ -8122,17 +8217,18 @@ var Orchestrator = class {
|
|
|
8122
8217
|
}
|
|
8123
8218
|
}
|
|
8124
8219
|
}
|
|
8220
|
+
const runOutput = createLineCoalescer((chunk) => {
|
|
8221
|
+
this.emit({
|
|
8222
|
+
type: "run_output",
|
|
8223
|
+
threadId: thread.id,
|
|
8224
|
+
scriptName: resolvedName,
|
|
8225
|
+
line: chunk
|
|
8226
|
+
});
|
|
8227
|
+
});
|
|
8125
8228
|
const handle = await startDevServer(
|
|
8126
8229
|
thread.repoPath,
|
|
8127
8230
|
thread.worktreePath,
|
|
8128
|
-
|
|
8129
|
-
this.emit({
|
|
8130
|
-
type: "run_output",
|
|
8131
|
-
threadId: thread.id,
|
|
8132
|
-
scriptName: resolvedName,
|
|
8133
|
-
line
|
|
8134
|
-
});
|
|
8135
|
-
},
|
|
8231
|
+
runOutput.push,
|
|
8136
8232
|
{ scriptName: resolvedName }
|
|
8137
8233
|
);
|
|
8138
8234
|
if (!handle) {
|
|
@@ -8178,6 +8274,7 @@ var Orchestrator = class {
|
|
|
8178
8274
|
scriptName: resolvedName
|
|
8179
8275
|
});
|
|
8180
8276
|
void handle.done.then(() => {
|
|
8277
|
+
runOutput.flush();
|
|
8181
8278
|
this.processes.delete(runKey);
|
|
8182
8279
|
if (isDefault) this.processes.delete(worktreeDevProcessKey(thread.worktreePath));
|
|
8183
8280
|
const latest = mergeWorktreeActiveRuns(threadsSharingWorktree(thread.worktreePath));
|
|
@@ -8263,9 +8360,14 @@ var Orchestrator = class {
|
|
|
8263
8360
|
(t) => this.processes.has(`${t.id}:setup`)
|
|
8264
8361
|
);
|
|
8265
8362
|
}
|
|
8266
|
-
|
|
8363
|
+
/**
|
|
8364
|
+
* The worktree-keyed log is canonical (`resolveWorktreeSetupLog` prefers it
|
|
8365
|
+
* whenever it has output/running/exitCode); per-chat keys only exist for
|
|
8366
|
+
* records that predate it. Writing one key halves the sync persists during
|
|
8367
|
+
* `pnpm install`.
|
|
8368
|
+
*/
|
|
8369
|
+
writeSetupLog(worktreePath, fn) {
|
|
8267
8370
|
fn(setupLogKeyForWorktree(worktreePath));
|
|
8268
|
-
fn(threadId);
|
|
8269
8371
|
}
|
|
8270
8372
|
async runSetup(threadRef, opts) {
|
|
8271
8373
|
const thread = this.requireThread(threadRef);
|
|
@@ -8280,14 +8382,18 @@ var Orchestrator = class {
|
|
|
8280
8382
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8281
8383
|
kill: () => abort.abort()
|
|
8282
8384
|
});
|
|
8283
|
-
this.writeSetupLog(thread.
|
|
8385
|
+
this.writeSetupLog(thread.worktreePath, beginSetupLog);
|
|
8284
8386
|
this.emit({ type: "setup_started", threadId: thread.id });
|
|
8387
|
+
const output = createLineCoalescer((chunk) => {
|
|
8388
|
+
this.writeSetupLog(thread.worktreePath, (logKey) => appendSetupLog(logKey, chunk));
|
|
8389
|
+
this.emit({ type: "setup_output", threadId: thread.id, line: chunk });
|
|
8390
|
+
});
|
|
8285
8391
|
let finished = false;
|
|
8286
8392
|
const finish = (exitCode, source) => {
|
|
8287
8393
|
if (finished) return;
|
|
8288
8394
|
finished = true;
|
|
8395
|
+
output.flush();
|
|
8289
8396
|
this.writeSetupLog(
|
|
8290
|
-
thread.id,
|
|
8291
8397
|
thread.worktreePath,
|
|
8292
8398
|
(logKey) => finishSetupLog(logKey, exitCode, source)
|
|
8293
8399
|
);
|
|
@@ -8297,24 +8403,12 @@ var Orchestrator = class {
|
|
|
8297
8403
|
const setup = await runWorkspaceSetup(
|
|
8298
8404
|
thread.repoPath,
|
|
8299
8405
|
thread.worktreePath,
|
|
8300
|
-
|
|
8301
|
-
this.writeSetupLog(
|
|
8302
|
-
thread.id,
|
|
8303
|
-
thread.worktreePath,
|
|
8304
|
-
(logKey) => appendSetupLog(logKey, line)
|
|
8305
|
-
);
|
|
8306
|
-
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
8307
|
-
},
|
|
8406
|
+
output.push,
|
|
8308
8407
|
{ signal: abort.signal }
|
|
8309
8408
|
);
|
|
8310
8409
|
if (!setup.ran) {
|
|
8311
8410
|
const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
|
|
8312
|
-
|
|
8313
|
-
thread.id,
|
|
8314
|
-
thread.worktreePath,
|
|
8315
|
-
(logKey) => appendSetupLog(logKey, line)
|
|
8316
|
-
);
|
|
8317
|
-
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
8411
|
+
output.push(line);
|
|
8318
8412
|
finish(null, null);
|
|
8319
8413
|
throw new Error(line);
|
|
8320
8414
|
}
|
|
@@ -8520,6 +8614,11 @@ var Orchestrator = class {
|
|
|
8520
8614
|
lastTurnBase: this.turnBaselines.get(thread.id) ?? null
|
|
8521
8615
|
});
|
|
8522
8616
|
}
|
|
8617
|
+
async worktreeDirtyStat(threadRef) {
|
|
8618
|
+
const thread = this.requireThread(threadRef);
|
|
8619
|
+
this.assertNotGlobal(thread, "Diff");
|
|
8620
|
+
return getWorktreeDirtyStat(thread.worktreePath);
|
|
8621
|
+
}
|
|
8523
8622
|
async diffSummary(threadRef) {
|
|
8524
8623
|
const thread = this.requireThread(threadRef);
|
|
8525
8624
|
this.assertNotGlobal(thread, "Diff");
|
|
@@ -8968,7 +9067,7 @@ var Orchestrator = class {
|
|
|
8968
9067
|
this.enforceHistoryRetention();
|
|
8969
9068
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
8970
9069
|
try {
|
|
8971
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
9070
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-KM7KTLVO.js");
|
|
8972
9071
|
await ensureWorkspace2(thread.repoPath);
|
|
8973
9072
|
} catch {
|
|
8974
9073
|
}
|
|
@@ -9022,7 +9121,7 @@ var Orchestrator = class {
|
|
|
9022
9121
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
9023
9122
|
);
|
|
9024
9123
|
}
|
|
9025
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
9124
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-VXRI7LYM.js");
|
|
9026
9125
|
const slug = thread.worktreePath.split("/").pop();
|
|
9027
9126
|
const dest = thread.worktreePath;
|
|
9028
9127
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -9132,7 +9231,7 @@ async function startOrchestration(opts) {
|
|
|
9132
9231
|
sourceRef: "default",
|
|
9133
9232
|
...createOpts
|
|
9134
9233
|
}).catch(async () => {
|
|
9135
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
9234
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-VXRI7LYM.js");
|
|
9136
9235
|
const repo = await resolveRepoRoot2(repoPath);
|
|
9137
9236
|
const def = await resolveDefaultBranch2(repo);
|
|
9138
9237
|
return orch.createThread({
|
|
@@ -9142,7 +9241,7 @@ async function startOrchestration(opts) {
|
|
|
9142
9241
|
repoPath: repo
|
|
9143
9242
|
});
|
|
9144
9243
|
});
|
|
9145
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
9244
|
+
const { updateThread: upd } = await import("./thread-store-KDPPXJJ3.js");
|
|
9146
9245
|
const updated = upd(thread.id, {
|
|
9147
9246
|
sourceType: "orchestration",
|
|
9148
9247
|
sourceRef: goal
|
|
@@ -9194,6 +9293,7 @@ export {
|
|
|
9194
9293
|
waitForPidExit,
|
|
9195
9294
|
resolveSendFollowUp,
|
|
9196
9295
|
resolveOrchChildFollowUp,
|
|
9296
|
+
LIGHT_RECONCILE_THROTTLE_MS,
|
|
9197
9297
|
Orchestrator,
|
|
9198
9298
|
getOrchestrator,
|
|
9199
9299
|
startOrchestration
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isOrchestratorThread
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FNGXKY5W.js";
|
|
4
4
|
import {
|
|
5
5
|
codexUnattendedGitConfigArgs,
|
|
6
6
|
mergeAgentGitAuthEnv,
|
|
7
7
|
resolveAgentGitAuthEnv,
|
|
8
8
|
resolveCodexGitWritableRoots
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-NI243N27.js";
|
|
10
10
|
import {
|
|
11
11
|
applyConnectedTeamToCli,
|
|
12
12
|
brightsyMcpServerName,
|
|
@@ -1903,7 +1903,7 @@ var claudeAdapter = {
|
|
|
1903
1903
|
);
|
|
1904
1904
|
}
|
|
1905
1905
|
const mode = permissionMode(thread);
|
|
1906
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
1906
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-6P236KKG.js");
|
|
1907
1907
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
1908
1908
|
const injectedServers = await buildInjectedMcpServers({
|
|
1909
1909
|
includeSideboard: true,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
resolveRepoRoot,
|
|
6
6
|
takenSlugsFromThread,
|
|
7
7
|
teamSlugFromName
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-NI243N27.js";
|
|
9
9
|
import {
|
|
10
10
|
ATTACHMENTS_DIR,
|
|
11
11
|
attachmentsGitignoreBody
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
listThreads,
|
|
29
29
|
updateThread,
|
|
30
30
|
writeThread
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-3IMSQNTS.js";
|
|
32
32
|
import {
|
|
33
33
|
appDataDir,
|
|
34
34
|
globalAgentCwd,
|
|
@@ -146,6 +146,7 @@ function forgetThread(id) {
|
|
|
146
146
|
const cache = cacheForDir();
|
|
147
147
|
cache.byId.delete(id);
|
|
148
148
|
cache.mtimeMs.delete(id);
|
|
149
|
+
selfWriteMtimes.delete(id);
|
|
149
150
|
}
|
|
150
151
|
function invalidateThreadListCache() {
|
|
151
152
|
listCache = null;
|
|
@@ -169,20 +170,28 @@ function readThread(id) {
|
|
|
169
170
|
rememberThread(thread, mtimeMs);
|
|
170
171
|
return thread;
|
|
171
172
|
}
|
|
173
|
+
var selfWriteMtimes = /* @__PURE__ */ new Map();
|
|
172
174
|
function writeThread(thread, opts) {
|
|
173
175
|
const path = threadFilePath(idPath(thread.id));
|
|
174
176
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
175
177
|
const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso() };
|
|
176
178
|
writeFileSync(tmp, JSON.stringify(next, null, 2), "utf8");
|
|
177
179
|
renameSync(tmp, path);
|
|
178
|
-
|
|
180
|
+
const mtimeMs = fileMtimeMs(path) ?? Date.now();
|
|
181
|
+
rememberThread(next, mtimeMs);
|
|
182
|
+
selfWriteMtimes.set(thread.id, mtimeMs);
|
|
183
|
+
}
|
|
184
|
+
function isSelfWrittenRecord(id) {
|
|
185
|
+
const ours = selfWriteMtimes.get(id);
|
|
186
|
+
if (ours == null) return false;
|
|
187
|
+
return fileMtimeMs(threadFilePath(id)) === ours;
|
|
179
188
|
}
|
|
180
189
|
function idPath(id) {
|
|
181
190
|
return id;
|
|
182
191
|
}
|
|
183
192
|
function isThreadRecordFile(nameOrPath) {
|
|
184
193
|
const name = basename(nameOrPath);
|
|
185
|
-
return name.endsWith(".json") && !name.endsWith(".live.json");
|
|
194
|
+
return name.endsWith(".json") && !name.endsWith(".live.json") && !name.endsWith(".setup.log.json");
|
|
186
195
|
}
|
|
187
196
|
function listThreads(opts) {
|
|
188
197
|
const cache = cacheForDir();
|
|
@@ -258,6 +267,7 @@ export {
|
|
|
258
267
|
invalidateThreadRecord,
|
|
259
268
|
readThread,
|
|
260
269
|
writeThread,
|
|
270
|
+
isSelfWrittenRecord,
|
|
261
271
|
isThreadRecordFile,
|
|
262
272
|
listThreads,
|
|
263
273
|
deleteThreadRecord,
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
resolveRepoRoot,
|
|
8
8
|
takenSlugsFromThread,
|
|
9
9
|
teamSlugFromName
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-XYKVRRC2.js";
|
|
11
11
|
import {
|
|
12
12
|
ATTACHMENTS_DIR,
|
|
13
13
|
attachmentsGitignoreBody
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
listThreads,
|
|
18
18
|
updateThread,
|
|
19
19
|
writeThread
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-HY2GFZ5S.js";
|
|
21
21
|
import {
|
|
22
22
|
assertOrchestratorCapableAgent,
|
|
23
23
|
formatAccountProfilePlaybookLine,
|