@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
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -841,6 +841,7 @@ __export(thread_store_exports, {
|
|
|
841
841
|
findThreadByRef: () => findThreadByRef,
|
|
842
842
|
invalidateThreadListCache: () => invalidateThreadListCache,
|
|
843
843
|
invalidateThreadRecord: () => invalidateThreadRecord,
|
|
844
|
+
isSelfWrittenRecord: () => isSelfWrittenRecord,
|
|
844
845
|
isThreadRecordFile: () => isThreadRecordFile,
|
|
845
846
|
listThreads: () => listThreads,
|
|
846
847
|
normalizeThread: () => normalizeThread,
|
|
@@ -970,6 +971,7 @@ function forgetThread(id) {
|
|
|
970
971
|
const cache = cacheForDir();
|
|
971
972
|
cache.byId.delete(id);
|
|
972
973
|
cache.mtimeMs.delete(id);
|
|
974
|
+
selfWriteMtimes.delete(id);
|
|
973
975
|
}
|
|
974
976
|
function invalidateThreadListCache() {
|
|
975
977
|
listCache = null;
|
|
@@ -999,14 +1001,21 @@ function writeThread(thread, opts) {
|
|
|
999
1001
|
const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso() };
|
|
1000
1002
|
(0, import_node_fs8.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
|
|
1001
1003
|
(0, import_node_fs8.renameSync)(tmp, path);
|
|
1002
|
-
|
|
1004
|
+
const mtimeMs = fileMtimeMs(path) ?? Date.now();
|
|
1005
|
+
rememberThread(next, mtimeMs);
|
|
1006
|
+
selfWriteMtimes.set(thread.id, mtimeMs);
|
|
1007
|
+
}
|
|
1008
|
+
function isSelfWrittenRecord(id) {
|
|
1009
|
+
const ours = selfWriteMtimes.get(id);
|
|
1010
|
+
if (ours == null) return false;
|
|
1011
|
+
return fileMtimeMs(threadFilePath(id)) === ours;
|
|
1003
1012
|
}
|
|
1004
1013
|
function idPath(id) {
|
|
1005
1014
|
return id;
|
|
1006
1015
|
}
|
|
1007
1016
|
function isThreadRecordFile(nameOrPath) {
|
|
1008
1017
|
const name = (0, import_node_path9.basename)(nameOrPath);
|
|
1009
|
-
return name.endsWith(".json") && !name.endsWith(".live.json");
|
|
1018
|
+
return name.endsWith(".json") && !name.endsWith(".live.json") && !name.endsWith(".setup.log.json");
|
|
1010
1019
|
}
|
|
1011
1020
|
function listThreads(opts) {
|
|
1012
1021
|
const cache = cacheForDir();
|
|
@@ -1072,7 +1081,7 @@ function findThreadByRef(ref) {
|
|
|
1072
1081
|
(t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref
|
|
1073
1082
|
) ?? null;
|
|
1074
1083
|
}
|
|
1075
|
-
var import_node_crypto2, import_node_fs8, import_node_path9, import_proper_lockfile, listCache;
|
|
1084
|
+
var import_node_crypto2, import_node_fs8, import_node_path9, import_proper_lockfile, listCache, selfWriteMtimes;
|
|
1076
1085
|
var init_thread_store = __esm({
|
|
1077
1086
|
"src/store/thread-store.ts"() {
|
|
1078
1087
|
"use strict";
|
|
@@ -1084,6 +1093,7 @@ var init_thread_store = __esm({
|
|
|
1084
1093
|
init_cursor_store();
|
|
1085
1094
|
init_paths();
|
|
1086
1095
|
listCache = null;
|
|
1096
|
+
selfWriteMtimes = /* @__PURE__ */ new Map();
|
|
1087
1097
|
}
|
|
1088
1098
|
});
|
|
1089
1099
|
|
|
@@ -14372,6 +14382,29 @@ ${line}` : line;
|
|
|
14372
14382
|
const nl = cut.indexOf("\n");
|
|
14373
14383
|
return nl >= 0 && nl < cut.length - 1 ? cut.slice(nl + 1) : cut;
|
|
14374
14384
|
}
|
|
14385
|
+
function fromSnapshot(snap) {
|
|
14386
|
+
return {
|
|
14387
|
+
chunks: snap.output ? [snap.output] : [],
|
|
14388
|
+
length: snap.output.length,
|
|
14389
|
+
running: snap.running,
|
|
14390
|
+
exitCode: snap.exitCode,
|
|
14391
|
+
source: snap.source
|
|
14392
|
+
};
|
|
14393
|
+
}
|
|
14394
|
+
function materialize(mem) {
|
|
14395
|
+
let output = mem.chunks.join("\n");
|
|
14396
|
+
if (output.length > MAX_SETUP_LOG_CHARS) {
|
|
14397
|
+
output = appendSetupOutput("", output);
|
|
14398
|
+
mem.chunks = [output];
|
|
14399
|
+
mem.length = output.length;
|
|
14400
|
+
}
|
|
14401
|
+
return {
|
|
14402
|
+
output,
|
|
14403
|
+
running: mem.running,
|
|
14404
|
+
exitCode: mem.exitCode,
|
|
14405
|
+
source: mem.source
|
|
14406
|
+
};
|
|
14407
|
+
}
|
|
14375
14408
|
function setupLogPath(threadId) {
|
|
14376
14409
|
return (0, import_node_path38.join)(threadsDir(), `${threadId}.setup.log.json`);
|
|
14377
14410
|
}
|
|
@@ -14382,20 +14415,21 @@ function setupLogKeyForWorktree(worktreePath) {
|
|
|
14382
14415
|
function emptySetupLog() {
|
|
14383
14416
|
return { ...EMPTY };
|
|
14384
14417
|
}
|
|
14385
|
-
function clone(snap) {
|
|
14386
|
-
return { ...snap };
|
|
14387
|
-
}
|
|
14388
14418
|
function persistNow(threadId) {
|
|
14389
14419
|
const timer = persistTimers.get(threadId);
|
|
14390
14420
|
if (timer) {
|
|
14391
14421
|
clearTimeout(timer);
|
|
14392
14422
|
persistTimers.delete(threadId);
|
|
14393
14423
|
}
|
|
14394
|
-
const
|
|
14395
|
-
if (!
|
|
14424
|
+
const mem = memory.get(threadId);
|
|
14425
|
+
if (!mem) return;
|
|
14396
14426
|
try {
|
|
14397
|
-
(0, import_node_fs37.writeFileSync)(
|
|
14398
|
-
|
|
14427
|
+
(0, import_node_fs37.writeFileSync)(
|
|
14428
|
+
setupLogPath(threadId),
|
|
14429
|
+
`${JSON.stringify(materialize(mem))}
|
|
14430
|
+
`,
|
|
14431
|
+
"utf8"
|
|
14432
|
+
);
|
|
14399
14433
|
} catch {
|
|
14400
14434
|
}
|
|
14401
14435
|
}
|
|
@@ -14406,7 +14440,7 @@ function schedulePersist(threadId) {
|
|
|
14406
14440
|
setTimeout(() => {
|
|
14407
14441
|
persistTimers.delete(threadId);
|
|
14408
14442
|
persistNow(threadId);
|
|
14409
|
-
},
|
|
14443
|
+
}, PERSIST_DEBOUNCE_MS)
|
|
14410
14444
|
);
|
|
14411
14445
|
}
|
|
14412
14446
|
function loadFromDisk(threadId) {
|
|
@@ -14424,51 +14458,52 @@ function loadFromDisk(threadId) {
|
|
|
14424
14458
|
return null;
|
|
14425
14459
|
}
|
|
14426
14460
|
}
|
|
14461
|
+
function memFor(threadId) {
|
|
14462
|
+
const cached = memory.get(threadId);
|
|
14463
|
+
if (cached) return cached;
|
|
14464
|
+
const mem = fromSnapshot(loadFromDisk(threadId) ?? emptySetupLog());
|
|
14465
|
+
memory.set(threadId, mem);
|
|
14466
|
+
return mem;
|
|
14467
|
+
}
|
|
14427
14468
|
function readSetupLog(threadId) {
|
|
14428
14469
|
const cached = memory.get(threadId);
|
|
14429
|
-
if (cached) return
|
|
14470
|
+
if (cached) return materialize(cached);
|
|
14430
14471
|
const disk = loadFromDisk(threadId);
|
|
14431
14472
|
if (disk) {
|
|
14432
|
-
memory.set(threadId, disk);
|
|
14433
|
-
return
|
|
14473
|
+
memory.set(threadId, fromSnapshot(disk));
|
|
14474
|
+
return disk;
|
|
14434
14475
|
}
|
|
14435
14476
|
return emptySetupLog();
|
|
14436
14477
|
}
|
|
14437
14478
|
function beginSetupLog(threadId) {
|
|
14438
|
-
const
|
|
14439
|
-
|
|
14479
|
+
const mem = {
|
|
14480
|
+
chunks: [],
|
|
14481
|
+
length: 0,
|
|
14440
14482
|
running: true,
|
|
14441
14483
|
exitCode: null,
|
|
14442
14484
|
source: null
|
|
14443
14485
|
};
|
|
14444
|
-
memory.set(threadId,
|
|
14486
|
+
memory.set(threadId, mem);
|
|
14445
14487
|
persistNow(threadId);
|
|
14446
|
-
return
|
|
14488
|
+
return materialize(mem);
|
|
14447
14489
|
}
|
|
14448
14490
|
function appendSetupLog(threadId, line) {
|
|
14449
|
-
const
|
|
14450
|
-
|
|
14451
|
-
|
|
14452
|
-
|
|
14453
|
-
|
|
14454
|
-
};
|
|
14455
|
-
memory.set(threadId, snap);
|
|
14491
|
+
const mem = memFor(threadId);
|
|
14492
|
+
mem.chunks.push(line);
|
|
14493
|
+
mem.length += line.length + 1;
|
|
14494
|
+
mem.running = true;
|
|
14495
|
+
if (mem.length > MAX_SETUP_LOG_CHARS * 2) materialize(mem);
|
|
14456
14496
|
schedulePersist(threadId);
|
|
14457
|
-
return clone(snap);
|
|
14458
14497
|
}
|
|
14459
14498
|
function finishSetupLog(threadId, exitCode, source) {
|
|
14460
|
-
const
|
|
14461
|
-
|
|
14462
|
-
|
|
14463
|
-
|
|
14464
|
-
exitCode,
|
|
14465
|
-
source: source ?? current.source
|
|
14466
|
-
};
|
|
14467
|
-
memory.set(threadId, snap);
|
|
14499
|
+
const mem = memFor(threadId);
|
|
14500
|
+
mem.running = false;
|
|
14501
|
+
mem.exitCode = exitCode;
|
|
14502
|
+
mem.source = source ?? mem.source;
|
|
14468
14503
|
persistNow(threadId);
|
|
14469
|
-
return
|
|
14504
|
+
return materialize(mem);
|
|
14470
14505
|
}
|
|
14471
|
-
var import_node_crypto8, import_node_fs37, import_node_path38, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers;
|
|
14506
|
+
var import_node_crypto8, import_node_fs37, import_node_path38, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
|
|
14472
14507
|
var init_setup_log = __esm({
|
|
14473
14508
|
"src/store/setup-log.ts"() {
|
|
14474
14509
|
"use strict";
|
|
@@ -14486,6 +14521,7 @@ var init_setup_log = __esm({
|
|
|
14486
14521
|
MAX_SETUP_LOG_CHARS = 256e3;
|
|
14487
14522
|
memory = /* @__PURE__ */ new Map();
|
|
14488
14523
|
persistTimers = /* @__PURE__ */ new Map();
|
|
14524
|
+
PERSIST_DEBOUNCE_MS = 500;
|
|
14489
14525
|
}
|
|
14490
14526
|
});
|
|
14491
14527
|
|
|
@@ -17526,6 +17562,38 @@ var init_cowboy = __esm({
|
|
|
17526
17562
|
}
|
|
17527
17563
|
});
|
|
17528
17564
|
|
|
17565
|
+
// src/util/line-coalescer.ts
|
|
17566
|
+
function createLineCoalescer(onChunk, opts) {
|
|
17567
|
+
const delayMs = opts?.delayMs ?? 50;
|
|
17568
|
+
const maxLines = opts?.maxLines ?? 200;
|
|
17569
|
+
let buffer = [];
|
|
17570
|
+
let timer = null;
|
|
17571
|
+
const flush2 = () => {
|
|
17572
|
+
if (timer) {
|
|
17573
|
+
clearTimeout(timer);
|
|
17574
|
+
timer = null;
|
|
17575
|
+
}
|
|
17576
|
+
if (buffer.length === 0) return;
|
|
17577
|
+
const chunk = buffer.join("\n");
|
|
17578
|
+
buffer = [];
|
|
17579
|
+
onChunk(chunk);
|
|
17580
|
+
};
|
|
17581
|
+
const push = (line) => {
|
|
17582
|
+
buffer.push(line);
|
|
17583
|
+
if (buffer.length >= maxLines) {
|
|
17584
|
+
flush2();
|
|
17585
|
+
return;
|
|
17586
|
+
}
|
|
17587
|
+
if (!timer) timer = setTimeout(flush2, delayMs);
|
|
17588
|
+
};
|
|
17589
|
+
return { push, flush: flush2 };
|
|
17590
|
+
}
|
|
17591
|
+
var init_line_coalescer = __esm({
|
|
17592
|
+
"src/util/line-coalescer.ts"() {
|
|
17593
|
+
"use strict";
|
|
17594
|
+
}
|
|
17595
|
+
});
|
|
17596
|
+
|
|
17529
17597
|
// src/store/turn-live.ts
|
|
17530
17598
|
function trimParts(parts) {
|
|
17531
17599
|
if (parts.length <= MAX_PARTS) return parts;
|
|
@@ -19175,6 +19243,29 @@ function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
|
19175
19243
|
(0, import_node_fs46.writeFileSync)(abs, content, "utf8");
|
|
19176
19244
|
return { path: relativePath };
|
|
19177
19245
|
}
|
|
19246
|
+
async function getWorktreeDirtyStat(worktreePath) {
|
|
19247
|
+
const status = await inspectGitWorktree(worktreePath);
|
|
19248
|
+
if (status !== "ok") {
|
|
19249
|
+
return { additions: 0, deletions: 0, dirty: false };
|
|
19250
|
+
}
|
|
19251
|
+
const head = await git(["rev-parse", "--verify", "HEAD"], worktreePath, {
|
|
19252
|
+
reject: false,
|
|
19253
|
+
timeoutMs: 4e3
|
|
19254
|
+
});
|
|
19255
|
+
if (head.exitCode !== 0) {
|
|
19256
|
+
return { additions: 0, deletions: 0, dirty: await isDirty(worktreePath) };
|
|
19257
|
+
}
|
|
19258
|
+
const [num2, dirty] = await Promise.all([
|
|
19259
|
+
gitDiff(["--numstat", "HEAD"], worktreePath, { timeoutMs: 4e3 }),
|
|
19260
|
+
isDirty(worktreePath)
|
|
19261
|
+
]);
|
|
19262
|
+
const counts = statFromNumstat(num2.stdout);
|
|
19263
|
+
return {
|
|
19264
|
+
additions: counts.additions,
|
|
19265
|
+
deletions: counts.deletions,
|
|
19266
|
+
dirty: dirty || counts.additions > 0 || counts.deletions > 0
|
|
19267
|
+
};
|
|
19268
|
+
}
|
|
19178
19269
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
19179
19270
|
const full = await getDiff(worktreePath, repoPath, {
|
|
19180
19271
|
maxHunkChars: opts?.maxHunkChars ?? 2e3,
|
|
@@ -19781,9 +19872,7 @@ function consumeComposerAttachments(thread) {
|
|
|
19781
19872
|
};
|
|
19782
19873
|
}
|
|
19783
19874
|
function takePendingTurnAttachments(thread) {
|
|
19784
|
-
|
|
19785
|
-
if (pending.length > 0) return [...pending];
|
|
19786
|
-
return thread.attachments.length > 0 ? [...thread.attachments] : [];
|
|
19875
|
+
return [...thread.pendingTurnAttachments ?? []];
|
|
19787
19876
|
}
|
|
19788
19877
|
function alignQueueAttachments(queueLength, existing) {
|
|
19789
19878
|
const next = (existing ?? []).slice(0, queueLength).map((slot) => [...slot ?? []]);
|
|
@@ -20995,6 +21084,7 @@ var init_title = __esm({
|
|
|
20995
21084
|
// src/orchestrator/orchestrator.ts
|
|
20996
21085
|
var orchestrator_exports = {};
|
|
20997
21086
|
__export(orchestrator_exports, {
|
|
21087
|
+
LIGHT_RECONCILE_THROTTLE_MS: () => LIGHT_RECONCILE_THROTTLE_MS,
|
|
20998
21088
|
LIVE_TURN_SPAWN_GRACE_MS: () => LIVE_TURN_SPAWN_GRACE_MS,
|
|
20999
21089
|
Orchestrator: () => Orchestrator,
|
|
21000
21090
|
getOrchestrator: () => getOrchestrator,
|
|
@@ -21098,7 +21188,7 @@ async function startOrchestration(opts) {
|
|
|
21098
21188
|
}
|
|
21099
21189
|
return updated;
|
|
21100
21190
|
}
|
|
21101
|
-
var import_node_events, import_node_fs54, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
|
|
21191
|
+
var import_node_events, import_node_fs54, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
|
|
21102
21192
|
var init_orchestrator = __esm({
|
|
21103
21193
|
"src/orchestrator/orchestrator.ts"() {
|
|
21104
21194
|
"use strict";
|
|
@@ -21132,6 +21222,7 @@ var init_orchestrator = __esm({
|
|
|
21132
21222
|
init_orchestrator_capable();
|
|
21133
21223
|
init_chat_tabs();
|
|
21134
21224
|
init_enqueue_by_key();
|
|
21225
|
+
init_line_coalescer();
|
|
21135
21226
|
init_run();
|
|
21136
21227
|
init_repo_git_lock();
|
|
21137
21228
|
init_turn_live();
|
|
@@ -21165,6 +21256,7 @@ var init_orchestrator = __esm({
|
|
|
21165
21256
|
init_coordinator_prompt();
|
|
21166
21257
|
LIVE_TURN_SPAWN_GRACE_MS = 15e3;
|
|
21167
21258
|
STALE_AGENT_PID_WAIT_MS = 2500;
|
|
21259
|
+
LIGHT_RECONCILE_THROTTLE_MS = 1e4;
|
|
21168
21260
|
Orchestrator = class {
|
|
21169
21261
|
events = new import_node_events.EventEmitter();
|
|
21170
21262
|
processes = /* @__PURE__ */ new Map();
|
|
@@ -21174,6 +21266,8 @@ var init_orchestrator = __esm({
|
|
|
21174
21266
|
startingTurns = /* @__PURE__ */ new Set();
|
|
21175
21267
|
/** Last sync thread-file read for false-stop heal (throttled per thread). */
|
|
21176
21268
|
lastReconcileHealAt = /* @__PURE__ */ new Map();
|
|
21269
|
+
/** Per-repo timestamp of the last `reconcile(repo, { light: true })`. */
|
|
21270
|
+
lightReconcileAt = /* @__PURE__ */ new Map();
|
|
21177
21271
|
/**
|
|
21178
21272
|
* Threads intentionally force-stopped. Prevents runTurn from re-asserting
|
|
21179
21273
|
* `running` after spawn, and from overwriting `stopped` with idle/error when
|
|
@@ -21259,6 +21353,20 @@ var init_orchestrator = __esm({
|
|
|
21259
21353
|
async reconcile(repoPath, opts) {
|
|
21260
21354
|
const reclaimStaleTurns = opts?.reclaimStaleTurns === true;
|
|
21261
21355
|
const drainQueues = opts?.drainQueues !== false;
|
|
21356
|
+
if (opts?.light && repoPath) {
|
|
21357
|
+
const last = this.lightReconcileAt.get(repoPath) ?? 0;
|
|
21358
|
+
if (Date.now() - last < LIGHT_RECONCILE_THROTTLE_MS) return;
|
|
21359
|
+
this.lightReconcileAt.set(repoPath, Date.now());
|
|
21360
|
+
for (const thread of listThreads()) {
|
|
21361
|
+
if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
|
|
21362
|
+
if (!(0, import_node_fs54.existsSync)(thread.worktreePath)) {
|
|
21363
|
+
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
21364
|
+
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
21365
|
+
}
|
|
21366
|
+
}
|
|
21367
|
+
await this.reconcileOrphans([repoPath]);
|
|
21368
|
+
return;
|
|
21369
|
+
}
|
|
21262
21370
|
healOrchestrationSoccerTitles();
|
|
21263
21371
|
for (const thread of listThreads({ includeArchived: true })) {
|
|
21264
21372
|
if (thread.status === "archived") continue;
|
|
@@ -21291,6 +21399,21 @@ var init_orchestrator = __esm({
|
|
|
21291
21399
|
}
|
|
21292
21400
|
}
|
|
21293
21401
|
const repoPaths = (repoPath ? [repoPath] : [...new Set(listThreads({ includeArchived: true }).map((t) => t.repoPath))]).filter((p) => !isGlobalRepoPath(p));
|
|
21402
|
+
await this.reconcileOrphans(repoPaths);
|
|
21403
|
+
try {
|
|
21404
|
+
if (shouldRunHistoryCleanup()) {
|
|
21405
|
+
cleanupArchivedHistory();
|
|
21406
|
+
}
|
|
21407
|
+
} catch {
|
|
21408
|
+
}
|
|
21409
|
+
if (drainQueues) {
|
|
21410
|
+
this.adoptPersistedQueues();
|
|
21411
|
+
}
|
|
21412
|
+
this.schedulePendingQuotaResumes();
|
|
21413
|
+
armSchedules();
|
|
21414
|
+
}
|
|
21415
|
+
/** Surface (and, when enabled, clean up) worktrees git knows about but no thread owns. */
|
|
21416
|
+
async reconcileOrphans(repoPaths) {
|
|
21294
21417
|
try {
|
|
21295
21418
|
const orphans = await findOrphanWorktrees(repoPaths);
|
|
21296
21419
|
if (orphans.length) {
|
|
@@ -21305,17 +21428,6 @@ var init_orchestrator = __esm({
|
|
|
21305
21428
|
}
|
|
21306
21429
|
} catch {
|
|
21307
21430
|
}
|
|
21308
|
-
try {
|
|
21309
|
-
if (shouldRunHistoryCleanup()) {
|
|
21310
|
-
cleanupArchivedHistory();
|
|
21311
|
-
}
|
|
21312
|
-
} catch {
|
|
21313
|
-
}
|
|
21314
|
-
if (drainQueues) {
|
|
21315
|
-
this.adoptPersistedQueues();
|
|
21316
|
-
}
|
|
21317
|
-
this.schedulePendingQuotaResumes();
|
|
21318
|
-
armSchedules();
|
|
21319
21431
|
}
|
|
21320
21432
|
/**
|
|
21321
21433
|
* Adopt queues persisted by another process (MCP stdio / CLI) into this
|
|
@@ -21549,7 +21661,7 @@ var init_orchestrator = __esm({
|
|
|
21549
21661
|
return listThreads({ includeArchived });
|
|
21550
21662
|
}
|
|
21551
21663
|
getThread(idOrRef) {
|
|
21552
|
-
return
|
|
21664
|
+
return readThread(idOrRef) ?? findThreadByRef(idOrRef);
|
|
21553
21665
|
}
|
|
21554
21666
|
async createThread(input) {
|
|
21555
21667
|
const prior = new Set(
|
|
@@ -21720,9 +21832,11 @@ var init_orchestrator = __esm({
|
|
|
21720
21832
|
const inFlight = this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id);
|
|
21721
21833
|
updateThread(thread.id, {
|
|
21722
21834
|
...removed,
|
|
21723
|
-
//
|
|
21724
|
-
//
|
|
21725
|
-
|
|
21835
|
+
// Follow-up files live on queueAttachments. pendingTurnAttachments is
|
|
21836
|
+
// the in-flight / just-dequeued snapshot — do not wipe it when a
|
|
21837
|
+
// later follow-up is removed. Only drop a leftover bag when nothing
|
|
21838
|
+
// is running and the queue is empty (legacy sends that never drained).
|
|
21839
|
+
...stillQueued || inFlight ? {} : { pendingTurnAttachments: [] },
|
|
21726
21840
|
status: !stillQueued && !inFlight && current.status === "queued" ? "idle" : current.status
|
|
21727
21841
|
});
|
|
21728
21842
|
this.emit({ type: "queue_changed", threadId: thread.id, queue: removed.queue });
|
|
@@ -21804,7 +21918,9 @@ var init_orchestrator = __esm({
|
|
|
21804
21918
|
updateThread(threadId, {
|
|
21805
21919
|
queue: shifted.queue,
|
|
21806
21920
|
queueAttachments: shifted.queueAttachments,
|
|
21807
|
-
|
|
21921
|
+
// Always write the snapshot, including [] for text-only, so
|
|
21922
|
+
// takePending cannot fall back to leftover pending or composer files.
|
|
21923
|
+
pendingTurnAttachments: shifted.attachments
|
|
21808
21924
|
});
|
|
21809
21925
|
this.emit({ type: "queue_changed", threadId, queue: shifted.queue });
|
|
21810
21926
|
await this.runTurn(threadId, shifted.prompt);
|
|
@@ -21852,7 +21968,6 @@ var init_orchestrator = __esm({
|
|
|
21852
21968
|
thread = this.requireThread(threadId);
|
|
21853
21969
|
}
|
|
21854
21970
|
const autoContinue = isJobContinuePrompt(prompt) || prompt.trim().startsWith("The previous agent process ended before it finished.");
|
|
21855
|
-
const parkedSnapshot = thread.pendingTurnAttachments ?? [];
|
|
21856
21971
|
const parked = takePendingTurnAttachments(thread);
|
|
21857
21972
|
const sentAttachments = !autoContinue && parked.length > 0 ? parked : void 0;
|
|
21858
21973
|
appendMessage(threadId, {
|
|
@@ -21868,7 +21983,7 @@ var init_orchestrator = __esm({
|
|
|
21868
21983
|
thread.worktreePath,
|
|
21869
21984
|
gitPrompt,
|
|
21870
21985
|
{
|
|
21871
|
-
attachments: autoContinue ? [] : sentAttachments ??
|
|
21986
|
+
attachments: autoContinue ? [] : sentAttachments ?? []
|
|
21872
21987
|
}
|
|
21873
21988
|
);
|
|
21874
21989
|
const slackInbound = /^(Slack DM|Slack @mention)(?:\n|$)/.test(
|
|
@@ -21922,10 +22037,7 @@ var init_orchestrator = __esm({
|
|
|
21922
22037
|
expandedPrompt
|
|
21923
22038
|
].filter(Boolean).join("\n\n");
|
|
21924
22039
|
if (!autoContinue && sentAttachments) {
|
|
21925
|
-
updateThread(
|
|
21926
|
-
threadId,
|
|
21927
|
-
parkedSnapshot.length > 0 ? { pendingTurnAttachments: [] } : { attachments: [], pendingTurnAttachments: [] }
|
|
21928
|
-
);
|
|
22040
|
+
updateThread(threadId, { pendingTurnAttachments: [] });
|
|
21929
22041
|
}
|
|
21930
22042
|
const adapter = getAdapter(thread.agent);
|
|
21931
22043
|
const resolved = await adapter.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
@@ -22405,17 +22517,18 @@ var init_orchestrator = __esm({
|
|
|
22405
22517
|
}
|
|
22406
22518
|
}
|
|
22407
22519
|
}
|
|
22520
|
+
const runOutput = createLineCoalescer((chunk) => {
|
|
22521
|
+
this.emit({
|
|
22522
|
+
type: "run_output",
|
|
22523
|
+
threadId: thread.id,
|
|
22524
|
+
scriptName: resolvedName,
|
|
22525
|
+
line: chunk
|
|
22526
|
+
});
|
|
22527
|
+
});
|
|
22408
22528
|
const handle = await startDevServer(
|
|
22409
22529
|
thread.repoPath,
|
|
22410
22530
|
thread.worktreePath,
|
|
22411
|
-
|
|
22412
|
-
this.emit({
|
|
22413
|
-
type: "run_output",
|
|
22414
|
-
threadId: thread.id,
|
|
22415
|
-
scriptName: resolvedName,
|
|
22416
|
-
line
|
|
22417
|
-
});
|
|
22418
|
-
},
|
|
22531
|
+
runOutput.push,
|
|
22419
22532
|
{ scriptName: resolvedName }
|
|
22420
22533
|
);
|
|
22421
22534
|
if (!handle) {
|
|
@@ -22461,6 +22574,7 @@ var init_orchestrator = __esm({
|
|
|
22461
22574
|
scriptName: resolvedName
|
|
22462
22575
|
});
|
|
22463
22576
|
void handle.done.then(() => {
|
|
22577
|
+
runOutput.flush();
|
|
22464
22578
|
this.processes.delete(runKey);
|
|
22465
22579
|
if (isDefault) this.processes.delete(worktreeDevProcessKey(thread.worktreePath));
|
|
22466
22580
|
const latest = mergeWorktreeActiveRuns(threadsSharingWorktree(thread.worktreePath));
|
|
@@ -22546,9 +22660,14 @@ var init_orchestrator = __esm({
|
|
|
22546
22660
|
(t) => this.processes.has(`${t.id}:setup`)
|
|
22547
22661
|
);
|
|
22548
22662
|
}
|
|
22549
|
-
|
|
22663
|
+
/**
|
|
22664
|
+
* The worktree-keyed log is canonical (`resolveWorktreeSetupLog` prefers it
|
|
22665
|
+
* whenever it has output/running/exitCode); per-chat keys only exist for
|
|
22666
|
+
* records that predate it. Writing one key halves the sync persists during
|
|
22667
|
+
* `pnpm install`.
|
|
22668
|
+
*/
|
|
22669
|
+
writeSetupLog(worktreePath, fn) {
|
|
22550
22670
|
fn(setupLogKeyForWorktree(worktreePath));
|
|
22551
|
-
fn(threadId);
|
|
22552
22671
|
}
|
|
22553
22672
|
async runSetup(threadRef, opts) {
|
|
22554
22673
|
const thread = this.requireThread(threadRef);
|
|
@@ -22563,14 +22682,18 @@ var init_orchestrator = __esm({
|
|
|
22563
22682
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22564
22683
|
kill: () => abort.abort()
|
|
22565
22684
|
});
|
|
22566
|
-
this.writeSetupLog(thread.
|
|
22685
|
+
this.writeSetupLog(thread.worktreePath, beginSetupLog);
|
|
22567
22686
|
this.emit({ type: "setup_started", threadId: thread.id });
|
|
22687
|
+
const output = createLineCoalescer((chunk) => {
|
|
22688
|
+
this.writeSetupLog(thread.worktreePath, (logKey) => appendSetupLog(logKey, chunk));
|
|
22689
|
+
this.emit({ type: "setup_output", threadId: thread.id, line: chunk });
|
|
22690
|
+
});
|
|
22568
22691
|
let finished = false;
|
|
22569
22692
|
const finish = (exitCode, source) => {
|
|
22570
22693
|
if (finished) return;
|
|
22571
22694
|
finished = true;
|
|
22695
|
+
output.flush();
|
|
22572
22696
|
this.writeSetupLog(
|
|
22573
|
-
thread.id,
|
|
22574
22697
|
thread.worktreePath,
|
|
22575
22698
|
(logKey) => finishSetupLog(logKey, exitCode, source)
|
|
22576
22699
|
);
|
|
@@ -22580,24 +22703,12 @@ var init_orchestrator = __esm({
|
|
|
22580
22703
|
const setup = await runWorkspaceSetup(
|
|
22581
22704
|
thread.repoPath,
|
|
22582
22705
|
thread.worktreePath,
|
|
22583
|
-
|
|
22584
|
-
this.writeSetupLog(
|
|
22585
|
-
thread.id,
|
|
22586
|
-
thread.worktreePath,
|
|
22587
|
-
(logKey) => appendSetupLog(logKey, line)
|
|
22588
|
-
);
|
|
22589
|
-
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
22590
|
-
},
|
|
22706
|
+
output.push,
|
|
22591
22707
|
{ signal: abort.signal }
|
|
22592
22708
|
);
|
|
22593
22709
|
if (!setup.ran) {
|
|
22594
22710
|
const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
|
|
22595
|
-
|
|
22596
|
-
thread.id,
|
|
22597
|
-
thread.worktreePath,
|
|
22598
|
-
(logKey) => appendSetupLog(logKey, line)
|
|
22599
|
-
);
|
|
22600
|
-
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
22711
|
+
output.push(line);
|
|
22601
22712
|
finish(null, null);
|
|
22602
22713
|
throw new Error(line);
|
|
22603
22714
|
}
|
|
@@ -22803,6 +22914,11 @@ var init_orchestrator = __esm({
|
|
|
22803
22914
|
lastTurnBase: this.turnBaselines.get(thread.id) ?? null
|
|
22804
22915
|
});
|
|
22805
22916
|
}
|
|
22917
|
+
async worktreeDirtyStat(threadRef) {
|
|
22918
|
+
const thread = this.requireThread(threadRef);
|
|
22919
|
+
this.assertNotGlobal(thread, "Diff");
|
|
22920
|
+
return getWorktreeDirtyStat(thread.worktreePath);
|
|
22921
|
+
}
|
|
22806
22922
|
async diffSummary(threadRef) {
|
|
22807
22923
|
const thread = this.requireThread(threadRef);
|
|
22808
22924
|
this.assertNotGlobal(thread, "Diff");
|
package/dist/mcp/run-stdio.js
CHANGED
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
syncBoardPins,
|
|
51
51
|
updateSchedule,
|
|
52
52
|
waitForDetachedJob
|
|
53
|
-
} from "../chunk-
|
|
53
|
+
} from "../chunk-D2IKXMF3.js";
|
|
54
54
|
import "../chunk-JFOPOMK7.js";
|
|
55
55
|
import "../chunk-YWI3IBP2.js";
|
|
56
56
|
import {
|
|
@@ -61,12 +61,12 @@ import {
|
|
|
61
61
|
materializeSystemCaBundle,
|
|
62
62
|
sideboardMcpProfile,
|
|
63
63
|
trustSystemCertificates
|
|
64
|
-
} from "../chunk-
|
|
64
|
+
} from "../chunk-7MTVRNP4.js";
|
|
65
65
|
import {
|
|
66
66
|
GLOBAL_WORKSPACE_ID,
|
|
67
67
|
isCloudCoordinatorThread,
|
|
68
68
|
listWorkspaces
|
|
69
|
-
} from "../chunk-
|
|
69
|
+
} from "../chunk-KFD2OXCE.js";
|
|
70
70
|
import "../chunk-3OHR73VK.js";
|
|
71
71
|
import "../chunk-Y4MIXGPA.js";
|
|
72
72
|
import "../chunk-YVE4PXCJ.js";
|
|
@@ -84,9 +84,9 @@ import {
|
|
|
84
84
|
resolveListPrsOptions,
|
|
85
85
|
resolveRepoRoot,
|
|
86
86
|
warmGithubAgentAuth
|
|
87
|
-
} from "../chunk-
|
|
87
|
+
} from "../chunk-XYKVRRC2.js";
|
|
88
88
|
import "../chunk-D6JWYJ4P.js";
|
|
89
|
-
import "../chunk-
|
|
89
|
+
import "../chunk-HY2GFZ5S.js";
|
|
90
90
|
import "../chunk-X5B3OS5I.js";
|
|
91
91
|
import "../chunk-SYFVUF2C.js";
|
|
92
92
|
import {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
LIGHT_RECONCILE_THROTTLE_MS,
|
|
4
5
|
LIVE_TURN_SPAWN_GRACE_MS,
|
|
5
6
|
Orchestrator,
|
|
6
7
|
getOrchestrator,
|
|
@@ -9,17 +10,17 @@ import {
|
|
|
9
10
|
resolveSendFollowUp,
|
|
10
11
|
startOrchestration,
|
|
11
12
|
waitForPidExit
|
|
12
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-D2IKXMF3.js";
|
|
13
14
|
import "./chunk-JFOPOMK7.js";
|
|
14
15
|
import "./chunk-YWI3IBP2.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-7MTVRNP4.js";
|
|
17
|
+
import "./chunk-KFD2OXCE.js";
|
|
17
18
|
import "./chunk-3OHR73VK.js";
|
|
18
19
|
import "./chunk-Y4MIXGPA.js";
|
|
19
20
|
import "./chunk-VKQGAWHY.js";
|
|
20
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-XYKVRRC2.js";
|
|
21
22
|
import "./chunk-D6JWYJ4P.js";
|
|
22
|
-
import "./chunk-
|
|
23
|
+
import "./chunk-HY2GFZ5S.js";
|
|
23
24
|
import "./chunk-X5B3OS5I.js";
|
|
24
25
|
import "./chunk-SYFVUF2C.js";
|
|
25
26
|
import "./chunk-FNQNJOHY.js";
|
|
@@ -29,6 +30,7 @@ import "./chunk-KGZBYWZ3.js";
|
|
|
29
30
|
import "./chunk-EQNRWDLN.js";
|
|
30
31
|
import "./chunk-FJZWM2ON.js";
|
|
31
32
|
export {
|
|
33
|
+
LIGHT_RECONCILE_THROTTLE_MS,
|
|
32
34
|
LIVE_TURN_SPAWN_GRACE_MS,
|
|
33
35
|
Orchestrator,
|
|
34
36
|
getOrchestrator,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
LIGHT_RECONCILE_THROTTLE_MS,
|
|
2
3
|
LIVE_TURN_SPAWN_GRACE_MS,
|
|
3
4
|
Orchestrator,
|
|
4
5
|
getOrchestrator,
|
|
@@ -7,11 +8,11 @@ import {
|
|
|
7
8
|
resolveSendFollowUp,
|
|
8
9
|
startOrchestration,
|
|
9
10
|
waitForPidExit
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-C32SBNA3.js";
|
|
11
12
|
import "./chunk-DJU54RYW.js";
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-DFTVZEZY.js";
|
|
14
|
+
import "./chunk-FNGXKY5W.js";
|
|
15
|
+
import "./chunk-NI243N27.js";
|
|
15
16
|
import "./chunk-6K64FJDD.js";
|
|
16
17
|
import "./chunk-QQKDGPUI.js";
|
|
17
18
|
import "./chunk-SALM35KD.js";
|
|
@@ -24,12 +25,13 @@ import "./chunk-4TR3HZFT.js";
|
|
|
24
25
|
import "./chunk-WDRMZKVB.js";
|
|
25
26
|
import "./chunk-4TYXWPAJ.js";
|
|
26
27
|
import "./chunk-JT7R45JB.js";
|
|
27
|
-
import "./chunk-
|
|
28
|
+
import "./chunk-3IMSQNTS.js";
|
|
28
29
|
import "./chunk-7J72QJOM.js";
|
|
29
30
|
import "./chunk-77WWLBCI.js";
|
|
30
31
|
import "./chunk-WFUDY6PC.js";
|
|
31
32
|
import "./chunk-UFHNSFAS.js";
|
|
32
33
|
export {
|
|
34
|
+
LIGHT_RECONCILE_THROTTLE_MS,
|
|
33
35
|
LIVE_TURN_SPAWN_GRACE_MS,
|
|
34
36
|
Orchestrator,
|
|
35
37
|
getOrchestrator,
|