@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
|
@@ -15,15 +15,15 @@ import {
|
|
|
15
15
|
orchestratorSessionPoisonedByBuiltins,
|
|
16
16
|
slackCoordinatorSourceRef,
|
|
17
17
|
takenTeamSlugsForOrchestration
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
18
|
+
} from "./chunk-FNGXKY5W.js";
|
|
19
|
+
import "./chunk-NI243N27.js";
|
|
20
20
|
import "./chunk-6K64FJDD.js";
|
|
21
21
|
import "./chunk-QQKDGPUI.js";
|
|
22
22
|
import "./chunk-L5CIEBLR.js";
|
|
23
23
|
import "./chunk-4TR3HZFT.js";
|
|
24
24
|
import "./chunk-WDRMZKVB.js";
|
|
25
25
|
import "./chunk-JT7R45JB.js";
|
|
26
|
-
import "./chunk-
|
|
26
|
+
import "./chunk-3IMSQNTS.js";
|
|
27
27
|
import "./chunk-7J72QJOM.js";
|
|
28
28
|
import "./chunk-77WWLBCI.js";
|
|
29
29
|
import {
|
|
@@ -17,10 +17,10 @@ import {
|
|
|
17
17
|
orchestratorSessionPoisonedByBuiltins,
|
|
18
18
|
slackCoordinatorSourceRef,
|
|
19
19
|
takenTeamSlugsForOrchestration
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import "./chunk-
|
|
20
|
+
} from "./chunk-KFD2OXCE.js";
|
|
21
|
+
import "./chunk-XYKVRRC2.js";
|
|
22
22
|
import "./chunk-D6JWYJ4P.js";
|
|
23
|
-
import "./chunk-
|
|
23
|
+
import "./chunk-HY2GFZ5S.js";
|
|
24
24
|
import "./chunk-X5B3OS5I.js";
|
|
25
25
|
import "./chunk-SYFVUF2C.js";
|
|
26
26
|
import "./chunk-FNQNJOHY.js";
|
package/dist/index.cjs
CHANGED
|
@@ -3079,6 +3079,7 @@ __export(thread_store_exports, {
|
|
|
3079
3079
|
findThreadByRef: () => findThreadByRef,
|
|
3080
3080
|
invalidateThreadListCache: () => invalidateThreadListCache,
|
|
3081
3081
|
invalidateThreadRecord: () => invalidateThreadRecord,
|
|
3082
|
+
isSelfWrittenRecord: () => isSelfWrittenRecord,
|
|
3082
3083
|
isThreadRecordFile: () => isThreadRecordFile,
|
|
3083
3084
|
listThreads: () => listThreads,
|
|
3084
3085
|
normalizeThread: () => normalizeThread,
|
|
@@ -3208,6 +3209,7 @@ function forgetThread(id) {
|
|
|
3208
3209
|
const cache2 = cacheForDir();
|
|
3209
3210
|
cache2.byId.delete(id);
|
|
3210
3211
|
cache2.mtimeMs.delete(id);
|
|
3212
|
+
selfWriteMtimes.delete(id);
|
|
3211
3213
|
}
|
|
3212
3214
|
function invalidateThreadListCache() {
|
|
3213
3215
|
listCache = null;
|
|
@@ -3237,14 +3239,21 @@ function writeThread(thread, opts) {
|
|
|
3237
3239
|
const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso() };
|
|
3238
3240
|
(0, import_node_fs9.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
|
|
3239
3241
|
(0, import_node_fs9.renameSync)(tmp, path2);
|
|
3240
|
-
|
|
3242
|
+
const mtimeMs = fileMtimeMs(path2) ?? Date.now();
|
|
3243
|
+
rememberThread(next, mtimeMs);
|
|
3244
|
+
selfWriteMtimes.set(thread.id, mtimeMs);
|
|
3245
|
+
}
|
|
3246
|
+
function isSelfWrittenRecord(id) {
|
|
3247
|
+
const ours = selfWriteMtimes.get(id);
|
|
3248
|
+
if (ours == null) return false;
|
|
3249
|
+
return fileMtimeMs(threadFilePath(id)) === ours;
|
|
3241
3250
|
}
|
|
3242
3251
|
function idPath(id) {
|
|
3243
3252
|
return id;
|
|
3244
3253
|
}
|
|
3245
3254
|
function isThreadRecordFile(nameOrPath) {
|
|
3246
3255
|
const name = (0, import_node_path11.basename)(nameOrPath);
|
|
3247
|
-
return name.endsWith(".json") && !name.endsWith(".live.json");
|
|
3256
|
+
return name.endsWith(".json") && !name.endsWith(".live.json") && !name.endsWith(".setup.log.json");
|
|
3248
3257
|
}
|
|
3249
3258
|
function listThreads(opts) {
|
|
3250
3259
|
const cache2 = cacheForDir();
|
|
@@ -3310,7 +3319,7 @@ function findThreadByRef(ref) {
|
|
|
3310
3319
|
(t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref
|
|
3311
3320
|
) ?? null;
|
|
3312
3321
|
}
|
|
3313
|
-
var import_node_crypto3, import_node_fs9, import_node_path11, import_proper_lockfile, listCache;
|
|
3322
|
+
var import_node_crypto3, import_node_fs9, import_node_path11, import_proper_lockfile, listCache, selfWriteMtimes;
|
|
3314
3323
|
var init_thread_store = __esm({
|
|
3315
3324
|
"src/store/thread-store.ts"() {
|
|
3316
3325
|
"use strict";
|
|
@@ -3322,6 +3331,7 @@ var init_thread_store = __esm({
|
|
|
3322
3331
|
init_cursor_store();
|
|
3323
3332
|
init_paths();
|
|
3324
3333
|
listCache = null;
|
|
3334
|
+
selfWriteMtimes = /* @__PURE__ */ new Map();
|
|
3325
3335
|
}
|
|
3326
3336
|
});
|
|
3327
3337
|
|
|
@@ -5756,6 +5766,29 @@ ${line}` : line;
|
|
|
5756
5766
|
const nl = cut.indexOf("\n");
|
|
5757
5767
|
return nl >= 0 && nl < cut.length - 1 ? cut.slice(nl + 1) : cut;
|
|
5758
5768
|
}
|
|
5769
|
+
function fromSnapshot(snap) {
|
|
5770
|
+
return {
|
|
5771
|
+
chunks: snap.output ? [snap.output] : [],
|
|
5772
|
+
length: snap.output.length,
|
|
5773
|
+
running: snap.running,
|
|
5774
|
+
exitCode: snap.exitCode,
|
|
5775
|
+
source: snap.source
|
|
5776
|
+
};
|
|
5777
|
+
}
|
|
5778
|
+
function materialize(mem) {
|
|
5779
|
+
let output = mem.chunks.join("\n");
|
|
5780
|
+
if (output.length > MAX_SETUP_LOG_CHARS) {
|
|
5781
|
+
output = appendSetupOutput("", output);
|
|
5782
|
+
mem.chunks = [output];
|
|
5783
|
+
mem.length = output.length;
|
|
5784
|
+
}
|
|
5785
|
+
return {
|
|
5786
|
+
output,
|
|
5787
|
+
running: mem.running,
|
|
5788
|
+
exitCode: mem.exitCode,
|
|
5789
|
+
source: mem.source
|
|
5790
|
+
};
|
|
5791
|
+
}
|
|
5759
5792
|
function setupLogPath(threadId) {
|
|
5760
5793
|
return (0, import_node_path12.join)(threadsDir(), `${threadId}.setup.log.json`);
|
|
5761
5794
|
}
|
|
@@ -5774,20 +5807,21 @@ function mergeSetupOutput(prev, incoming) {
|
|
|
5774
5807
|
if (incoming.startsWith(prev) || incoming.endsWith(prev)) return incoming;
|
|
5775
5808
|
return incoming.length >= prev.length ? incoming : prev;
|
|
5776
5809
|
}
|
|
5777
|
-
function clone(snap) {
|
|
5778
|
-
return { ...snap };
|
|
5779
|
-
}
|
|
5780
5810
|
function persistNow(threadId) {
|
|
5781
5811
|
const timer = persistTimers.get(threadId);
|
|
5782
5812
|
if (timer) {
|
|
5783
5813
|
clearTimeout(timer);
|
|
5784
5814
|
persistTimers.delete(threadId);
|
|
5785
5815
|
}
|
|
5786
|
-
const
|
|
5787
|
-
if (!
|
|
5816
|
+
const mem = memory.get(threadId);
|
|
5817
|
+
if (!mem) return;
|
|
5788
5818
|
try {
|
|
5789
|
-
(0, import_node_fs10.writeFileSync)(
|
|
5790
|
-
|
|
5819
|
+
(0, import_node_fs10.writeFileSync)(
|
|
5820
|
+
setupLogPath(threadId),
|
|
5821
|
+
`${JSON.stringify(materialize(mem))}
|
|
5822
|
+
`,
|
|
5823
|
+
"utf8"
|
|
5824
|
+
);
|
|
5791
5825
|
} catch {
|
|
5792
5826
|
}
|
|
5793
5827
|
}
|
|
@@ -5798,7 +5832,7 @@ function schedulePersist(threadId) {
|
|
|
5798
5832
|
setTimeout(() => {
|
|
5799
5833
|
persistTimers.delete(threadId);
|
|
5800
5834
|
persistNow(threadId);
|
|
5801
|
-
},
|
|
5835
|
+
}, PERSIST_DEBOUNCE_MS)
|
|
5802
5836
|
);
|
|
5803
5837
|
}
|
|
5804
5838
|
function loadFromDisk(threadId) {
|
|
@@ -5816,51 +5850,52 @@ function loadFromDisk(threadId) {
|
|
|
5816
5850
|
return null;
|
|
5817
5851
|
}
|
|
5818
5852
|
}
|
|
5853
|
+
function memFor(threadId) {
|
|
5854
|
+
const cached = memory.get(threadId);
|
|
5855
|
+
if (cached) return cached;
|
|
5856
|
+
const mem = fromSnapshot(loadFromDisk(threadId) ?? emptySetupLog());
|
|
5857
|
+
memory.set(threadId, mem);
|
|
5858
|
+
return mem;
|
|
5859
|
+
}
|
|
5819
5860
|
function readSetupLog(threadId) {
|
|
5820
5861
|
const cached = memory.get(threadId);
|
|
5821
|
-
if (cached) return
|
|
5862
|
+
if (cached) return materialize(cached);
|
|
5822
5863
|
const disk = loadFromDisk(threadId);
|
|
5823
5864
|
if (disk) {
|
|
5824
|
-
memory.set(threadId, disk);
|
|
5825
|
-
return
|
|
5865
|
+
memory.set(threadId, fromSnapshot(disk));
|
|
5866
|
+
return disk;
|
|
5826
5867
|
}
|
|
5827
5868
|
return emptySetupLog();
|
|
5828
5869
|
}
|
|
5829
5870
|
function beginSetupLog(threadId) {
|
|
5830
|
-
const
|
|
5831
|
-
|
|
5871
|
+
const mem = {
|
|
5872
|
+
chunks: [],
|
|
5873
|
+
length: 0,
|
|
5832
5874
|
running: true,
|
|
5833
5875
|
exitCode: null,
|
|
5834
5876
|
source: null
|
|
5835
5877
|
};
|
|
5836
|
-
memory.set(threadId,
|
|
5878
|
+
memory.set(threadId, mem);
|
|
5837
5879
|
persistNow(threadId);
|
|
5838
|
-
return
|
|
5880
|
+
return materialize(mem);
|
|
5839
5881
|
}
|
|
5840
5882
|
function appendSetupLog(threadId, line) {
|
|
5841
|
-
const
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
};
|
|
5847
|
-
memory.set(threadId, snap);
|
|
5883
|
+
const mem = memFor(threadId);
|
|
5884
|
+
mem.chunks.push(line);
|
|
5885
|
+
mem.length += line.length + 1;
|
|
5886
|
+
mem.running = true;
|
|
5887
|
+
if (mem.length > MAX_SETUP_LOG_CHARS * 2) materialize(mem);
|
|
5848
5888
|
schedulePersist(threadId);
|
|
5849
|
-
return clone(snap);
|
|
5850
5889
|
}
|
|
5851
5890
|
function finishSetupLog(threadId, exitCode, source) {
|
|
5852
|
-
const
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
exitCode,
|
|
5857
|
-
source: source ?? current.source
|
|
5858
|
-
};
|
|
5859
|
-
memory.set(threadId, snap);
|
|
5891
|
+
const mem = memFor(threadId);
|
|
5892
|
+
mem.running = false;
|
|
5893
|
+
mem.exitCode = exitCode;
|
|
5894
|
+
mem.source = source ?? mem.source;
|
|
5860
5895
|
persistNow(threadId);
|
|
5861
|
-
return
|
|
5896
|
+
return materialize(mem);
|
|
5862
5897
|
}
|
|
5863
|
-
var import_node_crypto4, import_node_fs10, import_node_path12, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers;
|
|
5898
|
+
var import_node_crypto4, import_node_fs10, import_node_path12, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
|
|
5864
5899
|
var init_setup_log = __esm({
|
|
5865
5900
|
"src/store/setup-log.ts"() {
|
|
5866
5901
|
"use strict";
|
|
@@ -5878,6 +5913,7 @@ var init_setup_log = __esm({
|
|
|
5878
5913
|
MAX_SETUP_LOG_CHARS = 256e3;
|
|
5879
5914
|
memory = /* @__PURE__ */ new Map();
|
|
5880
5915
|
persistTimers = /* @__PURE__ */ new Map();
|
|
5916
|
+
PERSIST_DEBOUNCE_MS = 500;
|
|
5881
5917
|
}
|
|
5882
5918
|
});
|
|
5883
5919
|
|
|
@@ -19630,6 +19666,38 @@ var init_cowboy = __esm({
|
|
|
19630
19666
|
}
|
|
19631
19667
|
});
|
|
19632
19668
|
|
|
19669
|
+
// src/util/line-coalescer.ts
|
|
19670
|
+
function createLineCoalescer(onChunk, opts) {
|
|
19671
|
+
const delayMs = opts?.delayMs ?? 50;
|
|
19672
|
+
const maxLines = opts?.maxLines ?? 200;
|
|
19673
|
+
let buffer = [];
|
|
19674
|
+
let timer = null;
|
|
19675
|
+
const flush2 = () => {
|
|
19676
|
+
if (timer) {
|
|
19677
|
+
clearTimeout(timer);
|
|
19678
|
+
timer = null;
|
|
19679
|
+
}
|
|
19680
|
+
if (buffer.length === 0) return;
|
|
19681
|
+
const chunk = buffer.join("\n");
|
|
19682
|
+
buffer = [];
|
|
19683
|
+
onChunk(chunk);
|
|
19684
|
+
};
|
|
19685
|
+
const push = (line) => {
|
|
19686
|
+
buffer.push(line);
|
|
19687
|
+
if (buffer.length >= maxLines) {
|
|
19688
|
+
flush2();
|
|
19689
|
+
return;
|
|
19690
|
+
}
|
|
19691
|
+
if (!timer) timer = setTimeout(flush2, delayMs);
|
|
19692
|
+
};
|
|
19693
|
+
return { push, flush: flush2 };
|
|
19694
|
+
}
|
|
19695
|
+
var init_line_coalescer = __esm({
|
|
19696
|
+
"src/util/line-coalescer.ts"() {
|
|
19697
|
+
"use strict";
|
|
19698
|
+
}
|
|
19699
|
+
});
|
|
19700
|
+
|
|
19633
19701
|
// src/store/turn-live.ts
|
|
19634
19702
|
function trimParts(parts) {
|
|
19635
19703
|
if (parts.length <= MAX_PARTS) return parts;
|
|
@@ -21295,6 +21363,29 @@ function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
|
21295
21363
|
(0, import_node_fs48.writeFileSync)(abs, content, "utf8");
|
|
21296
21364
|
return { path: relativePath };
|
|
21297
21365
|
}
|
|
21366
|
+
async function getWorktreeDirtyStat(worktreePath) {
|
|
21367
|
+
const status = await inspectGitWorktree(worktreePath);
|
|
21368
|
+
if (status !== "ok") {
|
|
21369
|
+
return { additions: 0, deletions: 0, dirty: false };
|
|
21370
|
+
}
|
|
21371
|
+
const head = await git(["rev-parse", "--verify", "HEAD"], worktreePath, {
|
|
21372
|
+
reject: false,
|
|
21373
|
+
timeoutMs: 4e3
|
|
21374
|
+
});
|
|
21375
|
+
if (head.exitCode !== 0) {
|
|
21376
|
+
return { additions: 0, deletions: 0, dirty: await isDirty(worktreePath) };
|
|
21377
|
+
}
|
|
21378
|
+
const [num2, dirty] = await Promise.all([
|
|
21379
|
+
gitDiff(["--numstat", "HEAD"], worktreePath, { timeoutMs: 4e3 }),
|
|
21380
|
+
isDirty(worktreePath)
|
|
21381
|
+
]);
|
|
21382
|
+
const counts = statFromNumstat(num2.stdout);
|
|
21383
|
+
return {
|
|
21384
|
+
additions: counts.additions,
|
|
21385
|
+
deletions: counts.deletions,
|
|
21386
|
+
dirty: dirty || counts.additions > 0 || counts.deletions > 0
|
|
21387
|
+
};
|
|
21388
|
+
}
|
|
21298
21389
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
21299
21390
|
const full = await getDiff(worktreePath, repoPath, {
|
|
21300
21391
|
maxHunkChars: opts?.maxHunkChars ?? 2e3,
|
|
@@ -22765,6 +22856,7 @@ var init_title = __esm({
|
|
|
22765
22856
|
// src/orchestrator/orchestrator.ts
|
|
22766
22857
|
var orchestrator_exports = {};
|
|
22767
22858
|
__export(orchestrator_exports, {
|
|
22859
|
+
LIGHT_RECONCILE_THROTTLE_MS: () => LIGHT_RECONCILE_THROTTLE_MS,
|
|
22768
22860
|
LIVE_TURN_SPAWN_GRACE_MS: () => LIVE_TURN_SPAWN_GRACE_MS,
|
|
22769
22861
|
Orchestrator: () => Orchestrator,
|
|
22770
22862
|
getOrchestrator: () => getOrchestrator,
|
|
@@ -22868,7 +22960,7 @@ async function startOrchestration(opts) {
|
|
|
22868
22960
|
}
|
|
22869
22961
|
return updated;
|
|
22870
22962
|
}
|
|
22871
|
-
var import_node_events, import_node_fs54, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
|
|
22963
|
+
var import_node_events, import_node_fs54, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
|
|
22872
22964
|
var init_orchestrator = __esm({
|
|
22873
22965
|
"src/orchestrator/orchestrator.ts"() {
|
|
22874
22966
|
"use strict";
|
|
@@ -22902,6 +22994,7 @@ var init_orchestrator = __esm({
|
|
|
22902
22994
|
init_orchestrator_capable();
|
|
22903
22995
|
init_chat_tabs();
|
|
22904
22996
|
init_enqueue_by_key();
|
|
22997
|
+
init_line_coalescer();
|
|
22905
22998
|
init_run();
|
|
22906
22999
|
init_repo_git_lock();
|
|
22907
23000
|
init_turn_live();
|
|
@@ -22935,6 +23028,7 @@ var init_orchestrator = __esm({
|
|
|
22935
23028
|
init_coordinator_prompt();
|
|
22936
23029
|
LIVE_TURN_SPAWN_GRACE_MS = 15e3;
|
|
22937
23030
|
STALE_AGENT_PID_WAIT_MS = 2500;
|
|
23031
|
+
LIGHT_RECONCILE_THROTTLE_MS = 1e4;
|
|
22938
23032
|
Orchestrator = class {
|
|
22939
23033
|
events = new import_node_events.EventEmitter();
|
|
22940
23034
|
processes = /* @__PURE__ */ new Map();
|
|
@@ -22944,6 +23038,8 @@ var init_orchestrator = __esm({
|
|
|
22944
23038
|
startingTurns = /* @__PURE__ */ new Set();
|
|
22945
23039
|
/** Last sync thread-file read for false-stop heal (throttled per thread). */
|
|
22946
23040
|
lastReconcileHealAt = /* @__PURE__ */ new Map();
|
|
23041
|
+
/** Per-repo timestamp of the last `reconcile(repo, { light: true })`. */
|
|
23042
|
+
lightReconcileAt = /* @__PURE__ */ new Map();
|
|
22947
23043
|
/**
|
|
22948
23044
|
* Threads intentionally force-stopped. Prevents runTurn from re-asserting
|
|
22949
23045
|
* `running` after spawn, and from overwriting `stopped` with idle/error when
|
|
@@ -23029,6 +23125,20 @@ var init_orchestrator = __esm({
|
|
|
23029
23125
|
async reconcile(repoPath, opts) {
|
|
23030
23126
|
const reclaimStaleTurns = opts?.reclaimStaleTurns === true;
|
|
23031
23127
|
const drainQueues = opts?.drainQueues !== false;
|
|
23128
|
+
if (opts?.light && repoPath) {
|
|
23129
|
+
const last = this.lightReconcileAt.get(repoPath) ?? 0;
|
|
23130
|
+
if (Date.now() - last < LIGHT_RECONCILE_THROTTLE_MS) return;
|
|
23131
|
+
this.lightReconcileAt.set(repoPath, Date.now());
|
|
23132
|
+
for (const thread of listThreads()) {
|
|
23133
|
+
if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
|
|
23134
|
+
if (!(0, import_node_fs54.existsSync)(thread.worktreePath)) {
|
|
23135
|
+
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
23136
|
+
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
23137
|
+
}
|
|
23138
|
+
}
|
|
23139
|
+
await this.reconcileOrphans([repoPath]);
|
|
23140
|
+
return;
|
|
23141
|
+
}
|
|
23032
23142
|
healOrchestrationSoccerTitles();
|
|
23033
23143
|
for (const thread of listThreads({ includeArchived: true })) {
|
|
23034
23144
|
if (thread.status === "archived") continue;
|
|
@@ -23061,6 +23171,21 @@ var init_orchestrator = __esm({
|
|
|
23061
23171
|
}
|
|
23062
23172
|
}
|
|
23063
23173
|
const repoPaths = (repoPath ? [repoPath] : [...new Set(listThreads({ includeArchived: true }).map((t) => t.repoPath))]).filter((p) => !isGlobalRepoPath(p));
|
|
23174
|
+
await this.reconcileOrphans(repoPaths);
|
|
23175
|
+
try {
|
|
23176
|
+
if (shouldRunHistoryCleanup()) {
|
|
23177
|
+
cleanupArchivedHistory();
|
|
23178
|
+
}
|
|
23179
|
+
} catch {
|
|
23180
|
+
}
|
|
23181
|
+
if (drainQueues) {
|
|
23182
|
+
this.adoptPersistedQueues();
|
|
23183
|
+
}
|
|
23184
|
+
this.schedulePendingQuotaResumes();
|
|
23185
|
+
armSchedules();
|
|
23186
|
+
}
|
|
23187
|
+
/** Surface (and, when enabled, clean up) worktrees git knows about but no thread owns. */
|
|
23188
|
+
async reconcileOrphans(repoPaths) {
|
|
23064
23189
|
try {
|
|
23065
23190
|
const orphans = await findOrphanWorktrees(repoPaths);
|
|
23066
23191
|
if (orphans.length) {
|
|
@@ -23075,17 +23200,6 @@ var init_orchestrator = __esm({
|
|
|
23075
23200
|
}
|
|
23076
23201
|
} catch {
|
|
23077
23202
|
}
|
|
23078
|
-
try {
|
|
23079
|
-
if (shouldRunHistoryCleanup()) {
|
|
23080
|
-
cleanupArchivedHistory();
|
|
23081
|
-
}
|
|
23082
|
-
} catch {
|
|
23083
|
-
}
|
|
23084
|
-
if (drainQueues) {
|
|
23085
|
-
this.adoptPersistedQueues();
|
|
23086
|
-
}
|
|
23087
|
-
this.schedulePendingQuotaResumes();
|
|
23088
|
-
armSchedules();
|
|
23089
23203
|
}
|
|
23090
23204
|
/**
|
|
23091
23205
|
* Adopt queues persisted by another process (MCP stdio / CLI) into this
|
|
@@ -23319,7 +23433,7 @@ var init_orchestrator = __esm({
|
|
|
23319
23433
|
return listThreads({ includeArchived });
|
|
23320
23434
|
}
|
|
23321
23435
|
getThread(idOrRef) {
|
|
23322
|
-
return
|
|
23436
|
+
return readThread(idOrRef) ?? findThreadByRef(idOrRef);
|
|
23323
23437
|
}
|
|
23324
23438
|
async createThread(input) {
|
|
23325
23439
|
const prior = new Set(
|
|
@@ -24175,17 +24289,18 @@ var init_orchestrator = __esm({
|
|
|
24175
24289
|
}
|
|
24176
24290
|
}
|
|
24177
24291
|
}
|
|
24292
|
+
const runOutput = createLineCoalescer((chunk) => {
|
|
24293
|
+
this.emit({
|
|
24294
|
+
type: "run_output",
|
|
24295
|
+
threadId: thread.id,
|
|
24296
|
+
scriptName: resolvedName,
|
|
24297
|
+
line: chunk
|
|
24298
|
+
});
|
|
24299
|
+
});
|
|
24178
24300
|
const handle = await startDevServer(
|
|
24179
24301
|
thread.repoPath,
|
|
24180
24302
|
thread.worktreePath,
|
|
24181
|
-
|
|
24182
|
-
this.emit({
|
|
24183
|
-
type: "run_output",
|
|
24184
|
-
threadId: thread.id,
|
|
24185
|
-
scriptName: resolvedName,
|
|
24186
|
-
line
|
|
24187
|
-
});
|
|
24188
|
-
},
|
|
24303
|
+
runOutput.push,
|
|
24189
24304
|
{ scriptName: resolvedName }
|
|
24190
24305
|
);
|
|
24191
24306
|
if (!handle) {
|
|
@@ -24231,6 +24346,7 @@ var init_orchestrator = __esm({
|
|
|
24231
24346
|
scriptName: resolvedName
|
|
24232
24347
|
});
|
|
24233
24348
|
void handle.done.then(() => {
|
|
24349
|
+
runOutput.flush();
|
|
24234
24350
|
this.processes.delete(runKey);
|
|
24235
24351
|
if (isDefault) this.processes.delete(worktreeDevProcessKey(thread.worktreePath));
|
|
24236
24352
|
const latest = mergeWorktreeActiveRuns(threadsSharingWorktree(thread.worktreePath));
|
|
@@ -24316,9 +24432,14 @@ var init_orchestrator = __esm({
|
|
|
24316
24432
|
(t) => this.processes.has(`${t.id}:setup`)
|
|
24317
24433
|
);
|
|
24318
24434
|
}
|
|
24319
|
-
|
|
24435
|
+
/**
|
|
24436
|
+
* The worktree-keyed log is canonical (`resolveWorktreeSetupLog` prefers it
|
|
24437
|
+
* whenever it has output/running/exitCode); per-chat keys only exist for
|
|
24438
|
+
* records that predate it. Writing one key halves the sync persists during
|
|
24439
|
+
* `pnpm install`.
|
|
24440
|
+
*/
|
|
24441
|
+
writeSetupLog(worktreePath, fn) {
|
|
24320
24442
|
fn(setupLogKeyForWorktree(worktreePath));
|
|
24321
|
-
fn(threadId);
|
|
24322
24443
|
}
|
|
24323
24444
|
async runSetup(threadRef, opts) {
|
|
24324
24445
|
const thread = this.requireThread(threadRef);
|
|
@@ -24333,14 +24454,18 @@ var init_orchestrator = __esm({
|
|
|
24333
24454
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24334
24455
|
kill: () => abort.abort()
|
|
24335
24456
|
});
|
|
24336
|
-
this.writeSetupLog(thread.
|
|
24457
|
+
this.writeSetupLog(thread.worktreePath, beginSetupLog);
|
|
24337
24458
|
this.emit({ type: "setup_started", threadId: thread.id });
|
|
24459
|
+
const output = createLineCoalescer((chunk) => {
|
|
24460
|
+
this.writeSetupLog(thread.worktreePath, (logKey) => appendSetupLog(logKey, chunk));
|
|
24461
|
+
this.emit({ type: "setup_output", threadId: thread.id, line: chunk });
|
|
24462
|
+
});
|
|
24338
24463
|
let finished = false;
|
|
24339
24464
|
const finish = (exitCode, source) => {
|
|
24340
24465
|
if (finished) return;
|
|
24341
24466
|
finished = true;
|
|
24467
|
+
output.flush();
|
|
24342
24468
|
this.writeSetupLog(
|
|
24343
|
-
thread.id,
|
|
24344
24469
|
thread.worktreePath,
|
|
24345
24470
|
(logKey) => finishSetupLog(logKey, exitCode, source)
|
|
24346
24471
|
);
|
|
@@ -24350,24 +24475,12 @@ var init_orchestrator = __esm({
|
|
|
24350
24475
|
const setup = await runWorkspaceSetup(
|
|
24351
24476
|
thread.repoPath,
|
|
24352
24477
|
thread.worktreePath,
|
|
24353
|
-
|
|
24354
|
-
this.writeSetupLog(
|
|
24355
|
-
thread.id,
|
|
24356
|
-
thread.worktreePath,
|
|
24357
|
-
(logKey) => appendSetupLog(logKey, line)
|
|
24358
|
-
);
|
|
24359
|
-
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
24360
|
-
},
|
|
24478
|
+
output.push,
|
|
24361
24479
|
{ signal: abort.signal }
|
|
24362
24480
|
);
|
|
24363
24481
|
if (!setup.ran) {
|
|
24364
24482
|
const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
|
|
24365
|
-
|
|
24366
|
-
thread.id,
|
|
24367
|
-
thread.worktreePath,
|
|
24368
|
-
(logKey) => appendSetupLog(logKey, line)
|
|
24369
|
-
);
|
|
24370
|
-
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
24483
|
+
output.push(line);
|
|
24371
24484
|
finish(null, null);
|
|
24372
24485
|
throw new Error(line);
|
|
24373
24486
|
}
|
|
@@ -24573,6 +24686,11 @@ var init_orchestrator = __esm({
|
|
|
24573
24686
|
lastTurnBase: this.turnBaselines.get(thread.id) ?? null
|
|
24574
24687
|
});
|
|
24575
24688
|
}
|
|
24689
|
+
async worktreeDirtyStat(threadRef) {
|
|
24690
|
+
const thread = this.requireThread(threadRef);
|
|
24691
|
+
this.assertNotGlobal(thread, "Diff");
|
|
24692
|
+
return getWorktreeDirtyStat(thread.worktreePath);
|
|
24693
|
+
}
|
|
24576
24694
|
async diffSummary(threadRef) {
|
|
24577
24695
|
const thread = this.requireThread(threadRef);
|
|
24578
24696
|
this.assertNotGlobal(thread, "Diff");
|
|
@@ -25332,6 +25450,7 @@ __export(index_exports, {
|
|
|
25332
25450
|
LEGACY_DETACHED_JOBS_DIR: () => LEGACY_DETACHED_JOBS_DIR,
|
|
25333
25451
|
LEGACY_PLAN_FILE_REL: () => LEGACY_PLAN_FILE_REL,
|
|
25334
25452
|
LEGACY_REVIEW_REQUEST_PATH: () => LEGACY_REVIEW_REQUEST_PATH,
|
|
25453
|
+
LIGHT_RECONCILE_THROTTLE_MS: () => LIGHT_RECONCILE_THROTTLE_MS,
|
|
25335
25454
|
LINEAR_OAUTH_CANCELLED: () => LINEAR_OAUTH_CANCELLED,
|
|
25336
25455
|
LINEAR_OAUTH_PORT: () => LINEAR_OAUTH_PORT,
|
|
25337
25456
|
LINEAR_OAUTH_REDIRECT: () => LINEAR_OAUTH_REDIRECT,
|
|
@@ -25689,6 +25808,7 @@ __export(index_exports, {
|
|
|
25689
25808
|
getRunScript: () => getRunScript,
|
|
25690
25809
|
getSchedule: () => getSchedule,
|
|
25691
25810
|
getSlackWorkspace: () => getSlackWorkspace,
|
|
25811
|
+
getWorktreeDirtyStat: () => getWorktreeDirtyStat,
|
|
25692
25812
|
gh: () => gh,
|
|
25693
25813
|
ghHeadRef: () => ghHeadRef,
|
|
25694
25814
|
ghRepoSelectArgs: () => ghRepoSelectArgs,
|
|
@@ -25766,6 +25886,7 @@ __export(index_exports, {
|
|
|
25766
25886
|
isPrNotMergeableError: () => isPrNotMergeableError,
|
|
25767
25887
|
isPresentPlanToolName: () => isPresentPlanToolName,
|
|
25768
25888
|
isPrimaryCheckoutThread: () => isPrimaryCheckoutThread,
|
|
25889
|
+
isSelfWrittenRecord: () => isSelfWrittenRecord,
|
|
25769
25890
|
isSessionQuotaLimit: () => isSessionQuotaLimit,
|
|
25770
25891
|
isSetupLastError: () => isSetupLastError,
|
|
25771
25892
|
isShellToolName: () => isShellToolName,
|
|
@@ -34118,6 +34239,7 @@ init_outbound_watch();
|
|
|
34118
34239
|
LEGACY_DETACHED_JOBS_DIR,
|
|
34119
34240
|
LEGACY_PLAN_FILE_REL,
|
|
34120
34241
|
LEGACY_REVIEW_REQUEST_PATH,
|
|
34242
|
+
LIGHT_RECONCILE_THROTTLE_MS,
|
|
34121
34243
|
LINEAR_OAUTH_CANCELLED,
|
|
34122
34244
|
LINEAR_OAUTH_PORT,
|
|
34123
34245
|
LINEAR_OAUTH_REDIRECT,
|
|
@@ -34475,6 +34597,7 @@ init_outbound_watch();
|
|
|
34475
34597
|
getRunScript,
|
|
34476
34598
|
getSchedule,
|
|
34477
34599
|
getSlackWorkspace,
|
|
34600
|
+
getWorktreeDirtyStat,
|
|
34478
34601
|
gh,
|
|
34479
34602
|
ghHeadRef,
|
|
34480
34603
|
ghRepoSelectArgs,
|
|
@@ -34552,6 +34675,7 @@ init_outbound_watch();
|
|
|
34552
34675
|
isPrNotMergeableError,
|
|
34553
34676
|
isPresentPlanToolName,
|
|
34554
34677
|
isPrimaryCheckoutThread,
|
|
34678
|
+
isSelfWrittenRecord,
|
|
34555
34679
|
isSessionQuotaLimit,
|
|
34556
34680
|
isSetupLastError,
|
|
34557
34681
|
isShellToolName,
|