@sideboard-ai/core 0.1.212 → 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-DINKOGEU.js → chunk-C32SBNA3.js} +187 -84
- package/dist/{chunk-MS6HGW2H.js → chunk-D2IKXMF3.js} +185 -83
- 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 +199 -75
- package/dist/index.d.cts +59 -3
- package/dist/index.d.ts +59 -3
- package/dist/index.js +11 -5
- package/dist/mcp/run-stdio.cjs +193 -75
- package/dist/mcp/run-stdio.js +5 -5
- package/dist/{orchestrator-DW4HDWLA.js → orchestrator-MI7A5DQZ.js} +7 -5
- package/dist/{orchestrator-333M3JAU.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
|
@@ -44,9 +44,9 @@ import {
|
|
|
44
44
|
resolveLoginCommand,
|
|
45
45
|
resolveQuotaFallbackAgent,
|
|
46
46
|
whichOnPath
|
|
47
|
-
} from "./chunk-
|
|
48
|
-
import "./chunk-
|
|
49
|
-
import "./chunk-
|
|
47
|
+
} from "./chunk-DFTVZEZY.js";
|
|
48
|
+
import "./chunk-FNGXKY5W.js";
|
|
49
|
+
import "./chunk-NI243N27.js";
|
|
50
50
|
import "./chunk-6K64FJDD.js";
|
|
51
51
|
import "./chunk-QQKDGPUI.js";
|
|
52
52
|
import "./chunk-SALM35KD.js";
|
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
import "./chunk-4TR3HZFT.js";
|
|
68
68
|
import "./chunk-WDRMZKVB.js";
|
|
69
69
|
import "./chunk-JT7R45JB.js";
|
|
70
|
-
import "./chunk-
|
|
70
|
+
import "./chunk-3IMSQNTS.js";
|
|
71
71
|
import "./chunk-7J72QJOM.js";
|
|
72
72
|
import "./chunk-77WWLBCI.js";
|
|
73
73
|
import "./chunk-WFUDY6PC.js";
|
|
@@ -50,14 +50,14 @@ import {
|
|
|
50
50
|
resolveQuotaFallbackAgent,
|
|
51
51
|
turnCostUsdFromCursorUsage,
|
|
52
52
|
whichOnPath
|
|
53
|
-
} from "./chunk-
|
|
54
|
-
import "./chunk-
|
|
53
|
+
} from "./chunk-7MTVRNP4.js";
|
|
54
|
+
import "./chunk-KFD2OXCE.js";
|
|
55
55
|
import "./chunk-3OHR73VK.js";
|
|
56
56
|
import "./chunk-Y4MIXGPA.js";
|
|
57
57
|
import "./chunk-VKQGAWHY.js";
|
|
58
|
-
import "./chunk-
|
|
58
|
+
import "./chunk-XYKVRRC2.js";
|
|
59
59
|
import "./chunk-D6JWYJ4P.js";
|
|
60
|
-
import "./chunk-
|
|
60
|
+
import "./chunk-HY2GFZ5S.js";
|
|
61
61
|
import "./chunk-X5B3OS5I.js";
|
|
62
62
|
import "./chunk-SYFVUF2C.js";
|
|
63
63
|
import {
|
|
@@ -144,6 +144,7 @@ function forgetThread(id) {
|
|
|
144
144
|
const cache = cacheForDir();
|
|
145
145
|
cache.byId.delete(id);
|
|
146
146
|
cache.mtimeMs.delete(id);
|
|
147
|
+
selfWriteMtimes.delete(id);
|
|
147
148
|
}
|
|
148
149
|
function invalidateThreadListCache() {
|
|
149
150
|
listCache = null;
|
|
@@ -167,20 +168,28 @@ function readThread(id) {
|
|
|
167
168
|
rememberThread(thread, mtimeMs);
|
|
168
169
|
return thread;
|
|
169
170
|
}
|
|
171
|
+
var selfWriteMtimes = /* @__PURE__ */ new Map();
|
|
170
172
|
function writeThread(thread, opts) {
|
|
171
173
|
const path = threadFilePath(idPath(thread.id));
|
|
172
174
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
173
175
|
const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso() };
|
|
174
176
|
writeFileSync(tmp, JSON.stringify(next, null, 2), "utf8");
|
|
175
177
|
renameSync(tmp, path);
|
|
176
|
-
|
|
178
|
+
const mtimeMs = fileMtimeMs(path) ?? Date.now();
|
|
179
|
+
rememberThread(next, mtimeMs);
|
|
180
|
+
selfWriteMtimes.set(thread.id, mtimeMs);
|
|
181
|
+
}
|
|
182
|
+
function isSelfWrittenRecord(id) {
|
|
183
|
+
const ours = selfWriteMtimes.get(id);
|
|
184
|
+
if (ours == null) return false;
|
|
185
|
+
return fileMtimeMs(threadFilePath(id)) === ours;
|
|
177
186
|
}
|
|
178
187
|
function idPath(id) {
|
|
179
188
|
return id;
|
|
180
189
|
}
|
|
181
190
|
function isThreadRecordFile(nameOrPath) {
|
|
182
191
|
const name = basename(nameOrPath);
|
|
183
|
-
return name.endsWith(".json") && !name.endsWith(".live.json");
|
|
192
|
+
return name.endsWith(".json") && !name.endsWith(".live.json") && !name.endsWith(".setup.log.json");
|
|
184
193
|
}
|
|
185
194
|
function listThreads(opts) {
|
|
186
195
|
const cache = cacheForDir();
|
|
@@ -256,6 +265,7 @@ export {
|
|
|
256
265
|
invalidateThreadRecord,
|
|
257
266
|
readThread,
|
|
258
267
|
writeThread,
|
|
268
|
+
isSelfWrittenRecord,
|
|
259
269
|
isThreadRecordFile,
|
|
260
270
|
listThreads,
|
|
261
271
|
deleteThreadRecord,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
isOrchestratorThread
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KFD2OXCE.js";
|
|
6
6
|
import {
|
|
7
7
|
applyConnectedTeamToCli,
|
|
8
8
|
brightsyMcpServerName,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
mergeAgentGitAuthEnv,
|
|
21
21
|
resolveAgentGitAuthEnv,
|
|
22
22
|
resolveCodexGitWritableRoots
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-XYKVRRC2.js";
|
|
24
24
|
import {
|
|
25
25
|
enrichPathWithNpmGlobalBin,
|
|
26
26
|
isConductorBundledCli,
|
|
@@ -2414,7 +2414,7 @@ var claudeAdapter = {
|
|
|
2414
2414
|
);
|
|
2415
2415
|
}
|
|
2416
2416
|
const mode = permissionMode(thread);
|
|
2417
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
2417
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-KT3FRHZL.js");
|
|
2418
2418
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
2419
2419
|
const injectedServers = await buildInjectedMcpServers({
|
|
2420
2420
|
includeSideboard: true,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
resolveQuotaFallbackAgent,
|
|
25
25
|
stripBrightsyNdjsonNoise,
|
|
26
26
|
toolDescription
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-DFTVZEZY.js";
|
|
28
28
|
import {
|
|
29
29
|
SLACK_REPLY_FORMATTING,
|
|
30
30
|
addWorkspace,
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
stageAbsolutePathsAsAttachments,
|
|
48
48
|
stageBuffersAsAttachments,
|
|
49
49
|
syncWorkspacesFromThreads
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-FNGXKY5W.js";
|
|
51
51
|
import {
|
|
52
52
|
addPrStackLayer,
|
|
53
53
|
allocateTeamName,
|
|
@@ -97,7 +97,7 @@ import {
|
|
|
97
97
|
worktreeDisplayLabelForGroup,
|
|
98
98
|
worktreeNameFromPath,
|
|
99
99
|
worktreeSlugForTicket
|
|
100
|
-
} from "./chunk-
|
|
100
|
+
} from "./chunk-NI243N27.js";
|
|
101
101
|
import {
|
|
102
102
|
ATTACHMENTS_DIR,
|
|
103
103
|
DETACHED_JOBS_DIR,
|
|
@@ -189,7 +189,7 @@ import {
|
|
|
189
189
|
updateThread,
|
|
190
190
|
withThreadLock,
|
|
191
191
|
writeThread
|
|
192
|
-
} from "./chunk-
|
|
192
|
+
} from "./chunk-3IMSQNTS.js";
|
|
193
193
|
import {
|
|
194
194
|
appDataDir,
|
|
195
195
|
findConventionSetup,
|
|
@@ -483,7 +483,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
483
483
|
await continueOnReply(threadId, prompt);
|
|
484
484
|
return;
|
|
485
485
|
}
|
|
486
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
486
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-WVZPTHBV.js");
|
|
487
487
|
await getOrchestrator2().send(threadId, prompt);
|
|
488
488
|
} catch {
|
|
489
489
|
}
|
|
@@ -817,9 +817,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
817
817
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
818
818
|
);
|
|
819
819
|
}
|
|
820
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
820
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-6P236KKG.js");
|
|
821
821
|
if (isGlobalThread2(thread)) {
|
|
822
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
822
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-FQX6ALAI.js");
|
|
823
823
|
ensureGlobalCoordinatorCwd2(
|
|
824
824
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
825
825
|
);
|
|
@@ -2377,6 +2377,29 @@ ${line}` : line;
|
|
|
2377
2377
|
}
|
|
2378
2378
|
var memory = /* @__PURE__ */ new Map();
|
|
2379
2379
|
var persistTimers = /* @__PURE__ */ new Map();
|
|
2380
|
+
function fromSnapshot(snap) {
|
|
2381
|
+
return {
|
|
2382
|
+
chunks: snap.output ? [snap.output] : [],
|
|
2383
|
+
length: snap.output.length,
|
|
2384
|
+
running: snap.running,
|
|
2385
|
+
exitCode: snap.exitCode,
|
|
2386
|
+
source: snap.source
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2389
|
+
function materialize(mem) {
|
|
2390
|
+
let output = mem.chunks.join("\n");
|
|
2391
|
+
if (output.length > MAX_SETUP_LOG_CHARS) {
|
|
2392
|
+
output = appendSetupOutput("", output);
|
|
2393
|
+
mem.chunks = [output];
|
|
2394
|
+
mem.length = output.length;
|
|
2395
|
+
}
|
|
2396
|
+
return {
|
|
2397
|
+
output,
|
|
2398
|
+
running: mem.running,
|
|
2399
|
+
exitCode: mem.exitCode,
|
|
2400
|
+
source: mem.source
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2380
2403
|
function setupLogPath(threadId) {
|
|
2381
2404
|
return join7(threadsDir(), `${threadId}.setup.log.json`);
|
|
2382
2405
|
}
|
|
@@ -2395,20 +2418,22 @@ function mergeSetupOutput(prev, incoming) {
|
|
|
2395
2418
|
if (incoming.startsWith(prev) || incoming.endsWith(prev)) return incoming;
|
|
2396
2419
|
return incoming.length >= prev.length ? incoming : prev;
|
|
2397
2420
|
}
|
|
2398
|
-
|
|
2399
|
-
return { ...snap };
|
|
2400
|
-
}
|
|
2421
|
+
var PERSIST_DEBOUNCE_MS = 500;
|
|
2401
2422
|
function persistNow(threadId) {
|
|
2402
2423
|
const timer = persistTimers.get(threadId);
|
|
2403
2424
|
if (timer) {
|
|
2404
2425
|
clearTimeout(timer);
|
|
2405
2426
|
persistTimers.delete(threadId);
|
|
2406
2427
|
}
|
|
2407
|
-
const
|
|
2408
|
-
if (!
|
|
2428
|
+
const mem = memory.get(threadId);
|
|
2429
|
+
if (!mem) return;
|
|
2409
2430
|
try {
|
|
2410
|
-
writeFileSync2(
|
|
2411
|
-
|
|
2431
|
+
writeFileSync2(
|
|
2432
|
+
setupLogPath(threadId),
|
|
2433
|
+
`${JSON.stringify(materialize(mem))}
|
|
2434
|
+
`,
|
|
2435
|
+
"utf8"
|
|
2436
|
+
);
|
|
2412
2437
|
} catch {
|
|
2413
2438
|
}
|
|
2414
2439
|
}
|
|
@@ -2419,7 +2444,7 @@ function schedulePersist(threadId) {
|
|
|
2419
2444
|
setTimeout(() => {
|
|
2420
2445
|
persistTimers.delete(threadId);
|
|
2421
2446
|
persistNow(threadId);
|
|
2422
|
-
},
|
|
2447
|
+
}, PERSIST_DEBOUNCE_MS)
|
|
2423
2448
|
);
|
|
2424
2449
|
}
|
|
2425
2450
|
function loadFromDisk(threadId) {
|
|
@@ -2437,49 +2462,50 @@ function loadFromDisk(threadId) {
|
|
|
2437
2462
|
return null;
|
|
2438
2463
|
}
|
|
2439
2464
|
}
|
|
2465
|
+
function memFor(threadId) {
|
|
2466
|
+
const cached = memory.get(threadId);
|
|
2467
|
+
if (cached) return cached;
|
|
2468
|
+
const mem = fromSnapshot(loadFromDisk(threadId) ?? emptySetupLog());
|
|
2469
|
+
memory.set(threadId, mem);
|
|
2470
|
+
return mem;
|
|
2471
|
+
}
|
|
2440
2472
|
function readSetupLog(threadId) {
|
|
2441
2473
|
const cached = memory.get(threadId);
|
|
2442
|
-
if (cached) return
|
|
2474
|
+
if (cached) return materialize(cached);
|
|
2443
2475
|
const disk = loadFromDisk(threadId);
|
|
2444
2476
|
if (disk) {
|
|
2445
|
-
memory.set(threadId, disk);
|
|
2446
|
-
return
|
|
2477
|
+
memory.set(threadId, fromSnapshot(disk));
|
|
2478
|
+
return disk;
|
|
2447
2479
|
}
|
|
2448
2480
|
return emptySetupLog();
|
|
2449
2481
|
}
|
|
2450
2482
|
function beginSetupLog(threadId) {
|
|
2451
|
-
const
|
|
2452
|
-
|
|
2483
|
+
const mem = {
|
|
2484
|
+
chunks: [],
|
|
2485
|
+
length: 0,
|
|
2453
2486
|
running: true,
|
|
2454
2487
|
exitCode: null,
|
|
2455
2488
|
source: null
|
|
2456
2489
|
};
|
|
2457
|
-
memory.set(threadId,
|
|
2490
|
+
memory.set(threadId, mem);
|
|
2458
2491
|
persistNow(threadId);
|
|
2459
|
-
return
|
|
2492
|
+
return materialize(mem);
|
|
2460
2493
|
}
|
|
2461
2494
|
function appendSetupLog(threadId, line) {
|
|
2462
|
-
const
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
};
|
|
2468
|
-
memory.set(threadId, snap);
|
|
2495
|
+
const mem = memFor(threadId);
|
|
2496
|
+
mem.chunks.push(line);
|
|
2497
|
+
mem.length += line.length + 1;
|
|
2498
|
+
mem.running = true;
|
|
2499
|
+
if (mem.length > MAX_SETUP_LOG_CHARS * 2) materialize(mem);
|
|
2469
2500
|
schedulePersist(threadId);
|
|
2470
|
-
return clone(snap);
|
|
2471
2501
|
}
|
|
2472
2502
|
function finishSetupLog(threadId, exitCode, source) {
|
|
2473
|
-
const
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
exitCode,
|
|
2478
|
-
source: source ?? current.source
|
|
2479
|
-
};
|
|
2480
|
-
memory.set(threadId, snap);
|
|
2503
|
+
const mem = memFor(threadId);
|
|
2504
|
+
mem.running = false;
|
|
2505
|
+
mem.exitCode = exitCode;
|
|
2506
|
+
mem.source = source ?? mem.source;
|
|
2481
2507
|
persistNow(threadId);
|
|
2482
|
-
return
|
|
2508
|
+
return materialize(mem);
|
|
2483
2509
|
}
|
|
2484
2510
|
|
|
2485
2511
|
// src/git/orphan-cleanup.ts
|
|
@@ -4039,7 +4065,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
4039
4065
|
return readThread(thread.id) ?? thread;
|
|
4040
4066
|
}
|
|
4041
4067
|
async function listLinearIssues(agent, repoPath) {
|
|
4042
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
4068
|
+
const { getAdapter: getAdapter2 } = await import("./agents-HETHRRZJ.js");
|
|
4043
4069
|
await requireAgent(agent, { requireLinear: true });
|
|
4044
4070
|
const adapter = getAdapter2(agent);
|
|
4045
4071
|
if (!adapter.listLinearIssues) {
|
|
@@ -4071,6 +4097,33 @@ function shouldRemoveWorktreeOnTeardown(thread) {
|
|
|
4071
4097
|
return !isCowboyThread(thread) && !isPrimaryCheckoutThread(thread);
|
|
4072
4098
|
}
|
|
4073
4099
|
|
|
4100
|
+
// src/util/line-coalescer.ts
|
|
4101
|
+
function createLineCoalescer(onChunk, opts) {
|
|
4102
|
+
const delayMs = opts?.delayMs ?? 50;
|
|
4103
|
+
const maxLines = opts?.maxLines ?? 200;
|
|
4104
|
+
let buffer = [];
|
|
4105
|
+
let timer = null;
|
|
4106
|
+
const flush2 = () => {
|
|
4107
|
+
if (timer) {
|
|
4108
|
+
clearTimeout(timer);
|
|
4109
|
+
timer = null;
|
|
4110
|
+
}
|
|
4111
|
+
if (buffer.length === 0) return;
|
|
4112
|
+
const chunk = buffer.join("\n");
|
|
4113
|
+
buffer = [];
|
|
4114
|
+
onChunk(chunk);
|
|
4115
|
+
};
|
|
4116
|
+
const push = (line) => {
|
|
4117
|
+
buffer.push(line);
|
|
4118
|
+
if (buffer.length >= maxLines) {
|
|
4119
|
+
flush2();
|
|
4120
|
+
return;
|
|
4121
|
+
}
|
|
4122
|
+
if (!timer) timer = setTimeout(flush2, delayMs);
|
|
4123
|
+
};
|
|
4124
|
+
return { push, flush: flush2 };
|
|
4125
|
+
}
|
|
4126
|
+
|
|
4074
4127
|
// src/store/turn-live.ts
|
|
4075
4128
|
import {
|
|
4076
4129
|
existsSync as existsSync11,
|
|
@@ -4485,7 +4538,7 @@ async function adoptThread(input) {
|
|
|
4485
4538
|
messages: input.messages ?? []
|
|
4486
4539
|
});
|
|
4487
4540
|
writeThread(thread);
|
|
4488
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
4541
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-R5LJCJRB.js");
|
|
4489
4542
|
await ensureWorkspace2(repoPath);
|
|
4490
4543
|
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-X54WSOXM.js");
|
|
4491
4544
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
@@ -5705,6 +5758,29 @@ function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
|
5705
5758
|
writeFileSync6(abs, content, "utf8");
|
|
5706
5759
|
return { path: relativePath };
|
|
5707
5760
|
}
|
|
5761
|
+
async function getWorktreeDirtyStat(worktreePath) {
|
|
5762
|
+
const status = await inspectGitWorktree(worktreePath);
|
|
5763
|
+
if (status !== "ok") {
|
|
5764
|
+
return { additions: 0, deletions: 0, dirty: false };
|
|
5765
|
+
}
|
|
5766
|
+
const head = await git(["rev-parse", "--verify", "HEAD"], worktreePath, {
|
|
5767
|
+
reject: false,
|
|
5768
|
+
timeoutMs: 4e3
|
|
5769
|
+
});
|
|
5770
|
+
if (head.exitCode !== 0) {
|
|
5771
|
+
return { additions: 0, deletions: 0, dirty: await isDirty(worktreePath) };
|
|
5772
|
+
}
|
|
5773
|
+
const [num, dirty] = await Promise.all([
|
|
5774
|
+
gitDiff(["--numstat", "HEAD"], worktreePath, { timeoutMs: 4e3 }),
|
|
5775
|
+
isDirty(worktreePath)
|
|
5776
|
+
]);
|
|
5777
|
+
const counts = statFromNumstat(num.stdout);
|
|
5778
|
+
return {
|
|
5779
|
+
additions: counts.additions,
|
|
5780
|
+
deletions: counts.deletions,
|
|
5781
|
+
dirty: dirty || counts.additions > 0 || counts.deletions > 0
|
|
5782
|
+
};
|
|
5783
|
+
}
|
|
5708
5784
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
5709
5785
|
const full = await getDiff(worktreePath, repoPath, {
|
|
5710
5786
|
maxHunkChars: opts?.maxHunkChars ?? 2e3,
|
|
@@ -7121,7 +7197,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
7121
7197
|
${prompt}`;
|
|
7122
7198
|
}
|
|
7123
7199
|
async function defaultDeps() {
|
|
7124
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
7200
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-WVZPTHBV.js");
|
|
7125
7201
|
const orch = getOrchestrator2();
|
|
7126
7202
|
return {
|
|
7127
7203
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -7252,6 +7328,7 @@ function resolveOrchChildFollowUp(requested) {
|
|
|
7252
7328
|
return followUpBehavior();
|
|
7253
7329
|
}
|
|
7254
7330
|
var STALE_AGENT_PID_WAIT_MS = 2500;
|
|
7331
|
+
var LIGHT_RECONCILE_THROTTLE_MS = 1e4;
|
|
7255
7332
|
function writeLiveStatus(threadId, status, lastError) {
|
|
7256
7333
|
const latest = readThread(threadId);
|
|
7257
7334
|
if (!latest || latest.status === "archived") return latest;
|
|
@@ -7266,6 +7343,8 @@ var Orchestrator = class {
|
|
|
7266
7343
|
startingTurns = /* @__PURE__ */ new Set();
|
|
7267
7344
|
/** Last sync thread-file read for false-stop heal (throttled per thread). */
|
|
7268
7345
|
lastReconcileHealAt = /* @__PURE__ */ new Map();
|
|
7346
|
+
/** Per-repo timestamp of the last `reconcile(repo, { light: true })`. */
|
|
7347
|
+
lightReconcileAt = /* @__PURE__ */ new Map();
|
|
7269
7348
|
/**
|
|
7270
7349
|
* Threads intentionally force-stopped. Prevents runTurn from re-asserting
|
|
7271
7350
|
* `running` after spawn, and from overwriting `stopped` with idle/error when
|
|
@@ -7351,6 +7430,20 @@ var Orchestrator = class {
|
|
|
7351
7430
|
async reconcile(repoPath, opts) {
|
|
7352
7431
|
const reclaimStaleTurns = opts?.reclaimStaleTurns === true;
|
|
7353
7432
|
const drainQueues = opts?.drainQueues !== false;
|
|
7433
|
+
if (opts?.light && repoPath) {
|
|
7434
|
+
const last = this.lightReconcileAt.get(repoPath) ?? 0;
|
|
7435
|
+
if (Date.now() - last < LIGHT_RECONCILE_THROTTLE_MS) return;
|
|
7436
|
+
this.lightReconcileAt.set(repoPath, Date.now());
|
|
7437
|
+
for (const thread of listThreads()) {
|
|
7438
|
+
if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
|
|
7439
|
+
if (!existsSync19(thread.worktreePath)) {
|
|
7440
|
+
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
7441
|
+
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
7442
|
+
}
|
|
7443
|
+
}
|
|
7444
|
+
await this.reconcileOrphans([repoPath]);
|
|
7445
|
+
return;
|
|
7446
|
+
}
|
|
7354
7447
|
healOrchestrationSoccerTitles();
|
|
7355
7448
|
for (const thread of listThreads({ includeArchived: true })) {
|
|
7356
7449
|
if (thread.status === "archived") continue;
|
|
@@ -7383,6 +7476,21 @@ var Orchestrator = class {
|
|
|
7383
7476
|
}
|
|
7384
7477
|
}
|
|
7385
7478
|
const repoPaths = (repoPath ? [repoPath] : [...new Set(listThreads({ includeArchived: true }).map((t) => t.repoPath))]).filter((p) => !isGlobalRepoPath(p));
|
|
7479
|
+
await this.reconcileOrphans(repoPaths);
|
|
7480
|
+
try {
|
|
7481
|
+
if (shouldRunHistoryCleanup()) {
|
|
7482
|
+
cleanupArchivedHistory();
|
|
7483
|
+
}
|
|
7484
|
+
} catch {
|
|
7485
|
+
}
|
|
7486
|
+
if (drainQueues) {
|
|
7487
|
+
this.adoptPersistedQueues();
|
|
7488
|
+
}
|
|
7489
|
+
this.schedulePendingQuotaResumes();
|
|
7490
|
+
armSchedules();
|
|
7491
|
+
}
|
|
7492
|
+
/** Surface (and, when enabled, clean up) worktrees git knows about but no thread owns. */
|
|
7493
|
+
async reconcileOrphans(repoPaths) {
|
|
7386
7494
|
try {
|
|
7387
7495
|
const orphans = await findOrphanWorktrees(repoPaths);
|
|
7388
7496
|
if (orphans.length) {
|
|
@@ -7397,17 +7505,6 @@ var Orchestrator = class {
|
|
|
7397
7505
|
}
|
|
7398
7506
|
} catch {
|
|
7399
7507
|
}
|
|
7400
|
-
try {
|
|
7401
|
-
if (shouldRunHistoryCleanup()) {
|
|
7402
|
-
cleanupArchivedHistory();
|
|
7403
|
-
}
|
|
7404
|
-
} catch {
|
|
7405
|
-
}
|
|
7406
|
-
if (drainQueues) {
|
|
7407
|
-
this.adoptPersistedQueues();
|
|
7408
|
-
}
|
|
7409
|
-
this.schedulePendingQuotaResumes();
|
|
7410
|
-
armSchedules();
|
|
7411
7508
|
}
|
|
7412
7509
|
/**
|
|
7413
7510
|
* Adopt queues persisted by another process (MCP stdio / CLI) into this
|
|
@@ -7641,7 +7738,7 @@ var Orchestrator = class {
|
|
|
7641
7738
|
return listThreads({ includeArchived });
|
|
7642
7739
|
}
|
|
7643
7740
|
getThread(idOrRef) {
|
|
7644
|
-
return
|
|
7741
|
+
return readThread(idOrRef) ?? findThreadByRef(idOrRef);
|
|
7645
7742
|
}
|
|
7646
7743
|
async createThread(input) {
|
|
7647
7744
|
const prior = new Set(
|
|
@@ -8497,17 +8594,18 @@ var Orchestrator = class {
|
|
|
8497
8594
|
}
|
|
8498
8595
|
}
|
|
8499
8596
|
}
|
|
8597
|
+
const runOutput = createLineCoalescer((chunk) => {
|
|
8598
|
+
this.emit({
|
|
8599
|
+
type: "run_output",
|
|
8600
|
+
threadId: thread.id,
|
|
8601
|
+
scriptName: resolvedName,
|
|
8602
|
+
line: chunk
|
|
8603
|
+
});
|
|
8604
|
+
});
|
|
8500
8605
|
const handle = await startDevServer(
|
|
8501
8606
|
thread.repoPath,
|
|
8502
8607
|
thread.worktreePath,
|
|
8503
|
-
|
|
8504
|
-
this.emit({
|
|
8505
|
-
type: "run_output",
|
|
8506
|
-
threadId: thread.id,
|
|
8507
|
-
scriptName: resolvedName,
|
|
8508
|
-
line
|
|
8509
|
-
});
|
|
8510
|
-
},
|
|
8608
|
+
runOutput.push,
|
|
8511
8609
|
{ scriptName: resolvedName }
|
|
8512
8610
|
);
|
|
8513
8611
|
if (!handle) {
|
|
@@ -8553,6 +8651,7 @@ var Orchestrator = class {
|
|
|
8553
8651
|
scriptName: resolvedName
|
|
8554
8652
|
});
|
|
8555
8653
|
void handle.done.then(() => {
|
|
8654
|
+
runOutput.flush();
|
|
8556
8655
|
this.processes.delete(runKey);
|
|
8557
8656
|
if (isDefault) this.processes.delete(worktreeDevProcessKey(thread.worktreePath));
|
|
8558
8657
|
const latest = mergeWorktreeActiveRuns(threadsSharingWorktree(thread.worktreePath));
|
|
@@ -8638,9 +8737,14 @@ var Orchestrator = class {
|
|
|
8638
8737
|
(t) => this.processes.has(`${t.id}:setup`)
|
|
8639
8738
|
);
|
|
8640
8739
|
}
|
|
8641
|
-
|
|
8740
|
+
/**
|
|
8741
|
+
* The worktree-keyed log is canonical (`resolveWorktreeSetupLog` prefers it
|
|
8742
|
+
* whenever it has output/running/exitCode); per-chat keys only exist for
|
|
8743
|
+
* records that predate it. Writing one key halves the sync persists during
|
|
8744
|
+
* `pnpm install`.
|
|
8745
|
+
*/
|
|
8746
|
+
writeSetupLog(worktreePath, fn) {
|
|
8642
8747
|
fn(setupLogKeyForWorktree(worktreePath));
|
|
8643
|
-
fn(threadId);
|
|
8644
8748
|
}
|
|
8645
8749
|
async runSetup(threadRef, opts) {
|
|
8646
8750
|
const thread = this.requireThread(threadRef);
|
|
@@ -8655,14 +8759,18 @@ var Orchestrator = class {
|
|
|
8655
8759
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8656
8760
|
kill: () => abort.abort()
|
|
8657
8761
|
});
|
|
8658
|
-
this.writeSetupLog(thread.
|
|
8762
|
+
this.writeSetupLog(thread.worktreePath, beginSetupLog);
|
|
8659
8763
|
this.emit({ type: "setup_started", threadId: thread.id });
|
|
8764
|
+
const output = createLineCoalescer((chunk) => {
|
|
8765
|
+
this.writeSetupLog(thread.worktreePath, (logKey) => appendSetupLog(logKey, chunk));
|
|
8766
|
+
this.emit({ type: "setup_output", threadId: thread.id, line: chunk });
|
|
8767
|
+
});
|
|
8660
8768
|
let finished = false;
|
|
8661
8769
|
const finish = (exitCode, source) => {
|
|
8662
8770
|
if (finished) return;
|
|
8663
8771
|
finished = true;
|
|
8772
|
+
output.flush();
|
|
8664
8773
|
this.writeSetupLog(
|
|
8665
|
-
thread.id,
|
|
8666
8774
|
thread.worktreePath,
|
|
8667
8775
|
(logKey) => finishSetupLog(logKey, exitCode, source)
|
|
8668
8776
|
);
|
|
@@ -8672,24 +8780,12 @@ var Orchestrator = class {
|
|
|
8672
8780
|
const setup = await runWorkspaceSetup(
|
|
8673
8781
|
thread.repoPath,
|
|
8674
8782
|
thread.worktreePath,
|
|
8675
|
-
|
|
8676
|
-
this.writeSetupLog(
|
|
8677
|
-
thread.id,
|
|
8678
|
-
thread.worktreePath,
|
|
8679
|
-
(logKey) => appendSetupLog(logKey, line)
|
|
8680
|
-
);
|
|
8681
|
-
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
8682
|
-
},
|
|
8783
|
+
output.push,
|
|
8683
8784
|
{ signal: abort.signal }
|
|
8684
8785
|
);
|
|
8685
8786
|
if (!setup.ran) {
|
|
8686
8787
|
const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
|
|
8687
|
-
|
|
8688
|
-
thread.id,
|
|
8689
|
-
thread.worktreePath,
|
|
8690
|
-
(logKey) => appendSetupLog(logKey, line)
|
|
8691
|
-
);
|
|
8692
|
-
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
8788
|
+
output.push(line);
|
|
8693
8789
|
finish(null, null);
|
|
8694
8790
|
throw new Error(line);
|
|
8695
8791
|
}
|
|
@@ -8895,6 +8991,11 @@ var Orchestrator = class {
|
|
|
8895
8991
|
lastTurnBase: this.turnBaselines.get(thread.id) ?? null
|
|
8896
8992
|
});
|
|
8897
8993
|
}
|
|
8994
|
+
async worktreeDirtyStat(threadRef) {
|
|
8995
|
+
const thread = this.requireThread(threadRef);
|
|
8996
|
+
this.assertNotGlobal(thread, "Diff");
|
|
8997
|
+
return getWorktreeDirtyStat(thread.worktreePath);
|
|
8998
|
+
}
|
|
8898
8999
|
async diffSummary(threadRef) {
|
|
8899
9000
|
const thread = this.requireThread(threadRef);
|
|
8900
9001
|
this.assertNotGlobal(thread, "Diff");
|
|
@@ -9343,7 +9444,7 @@ var Orchestrator = class {
|
|
|
9343
9444
|
this.enforceHistoryRetention();
|
|
9344
9445
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
9345
9446
|
try {
|
|
9346
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
9447
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-R5LJCJRB.js");
|
|
9347
9448
|
await ensureWorkspace2(thread.repoPath);
|
|
9348
9449
|
} catch {
|
|
9349
9450
|
}
|
|
@@ -9397,7 +9498,7 @@ var Orchestrator = class {
|
|
|
9397
9498
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
9398
9499
|
);
|
|
9399
9500
|
}
|
|
9400
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
9501
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-MDMTCAHX.js");
|
|
9401
9502
|
const slug = thread.worktreePath.split("/").pop();
|
|
9402
9503
|
const dest = thread.worktreePath;
|
|
9403
9504
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -9507,7 +9608,7 @@ async function startOrchestration(opts) {
|
|
|
9507
9608
|
sourceRef: "default",
|
|
9508
9609
|
...createOpts
|
|
9509
9610
|
}).catch(async () => {
|
|
9510
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
9611
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-MDMTCAHX.js");
|
|
9511
9612
|
const repo = await resolveRepoRoot2(repoPath);
|
|
9512
9613
|
const def = await resolveDefaultBranch2(repo);
|
|
9513
9614
|
return orch.createThread({
|
|
@@ -9517,7 +9618,7 @@ async function startOrchestration(opts) {
|
|
|
9517
9618
|
repoPath: repo
|
|
9518
9619
|
});
|
|
9519
9620
|
});
|
|
9520
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
9621
|
+
const { updateThread: upd } = await import("./thread-store-N6WQIWZ4.js");
|
|
9521
9622
|
const updated = upd(thread.id, {
|
|
9522
9623
|
sourceType: "orchestration",
|
|
9523
9624
|
sourceRef: goal
|
|
@@ -9723,6 +9824,7 @@ export {
|
|
|
9723
9824
|
readWorktreeFileForUpload,
|
|
9724
9825
|
readWorktreeFile,
|
|
9725
9826
|
writeWorktreeFile,
|
|
9827
|
+
getWorktreeDirtyStat,
|
|
9726
9828
|
getDiffSummary,
|
|
9727
9829
|
previewLand,
|
|
9728
9830
|
confirmLand,
|
|
@@ -9776,6 +9878,7 @@ export {
|
|
|
9776
9878
|
waitForPidExit,
|
|
9777
9879
|
resolveSendFollowUp,
|
|
9778
9880
|
resolveOrchChildFollowUp,
|
|
9881
|
+
LIGHT_RECONCILE_THROTTLE_MS,
|
|
9779
9882
|
Orchestrator,
|
|
9780
9883
|
getOrchestrator,
|
|
9781
9884
|
startOrchestration,
|