@sideboard-ai/core 0.1.152 → 0.1.155
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/{abletime-223A3LY6.js → abletime-H7LPGIP2.js} +3 -3
- package/dist/{abletime-CLC5UJC2.js → abletime-JSTJLXAW.js} +3 -3
- package/dist/agents/cursor-runner.js +2 -2
- package/dist/{agents-CUKWIM34.js → agents-V24DYZI4.js} +8 -9
- package/dist/{agents-VHXCBBBD.js → agents-YVW75KBO.js} +8 -9
- package/dist/{app-settings-3CHCNIMD.js → app-settings-H3INSR67.js} +38 -4
- package/dist/{app-settings-J3JBCUOT.js → app-settings-VRQI3FIE.js} +38 -4
- package/dist/{caffeinate-hold-NBRUWYXO.js → caffeinate-hold-DBKMRZZO.js} +2 -2
- package/dist/{caffeinate-hold-X3JNPR42.js → caffeinate-hold-SK2QISPE.js} +2 -2
- package/dist/chunk-2F63IMCL.js +959 -0
- package/dist/{chunk-4XNSGDXE.js → chunk-3BWVOUQG.js} +244 -1
- package/dist/{chunk-7BQNSUR2.js → chunk-46ZTBUVJ.js} +364 -200
- package/dist/{chunk-EY6QXPPO.js → chunk-4THE3EY7.js} +6 -6
- package/dist/{chunk-TUGKX5BD.js → chunk-7UURXPKD.js} +1 -1
- package/dist/{chunk-DCOZABNT.js → chunk-AO35MGOE.js} +1 -1
- package/dist/{chunk-3JBMACYX.js → chunk-CJQLPPEJ.js} +387 -15
- package/dist/{chunk-CZD4NRDZ.js → chunk-D7EGJ3EI.js} +244 -1
- package/dist/{chunk-QZQEXME2.js → chunk-EFVFB2AH.js} +1 -1
- package/dist/{chunk-B7XK37WZ.js → chunk-FDCFXMDG.js} +1 -1
- package/dist/{chunk-6X7Z34XE.js → chunk-J2OKVOBM.js} +410 -188
- package/dist/{chunk-WLV7TRMR.js → chunk-JOK4XWBG.js} +1 -1
- package/dist/{chunk-BD2ICC4D.js → chunk-JTJHOYCU.js} +1 -1
- package/dist/{chunk-GE7M3QTE.js → chunk-LQMFCS54.js} +387 -15
- package/dist/{chunk-G7SIQFBQ.js → chunk-LZ6QMEQC.js} +1 -1
- package/dist/{chunk-EUXOHTUK.js → chunk-LZQULFIT.js} +1 -1
- package/dist/{chunk-KLBOWJ74.js → chunk-OCQPTUR7.js} +1 -1
- package/dist/{chunk-GFQ57XAX.js → chunk-QZEZXYVV.js} +13 -13
- package/dist/chunk-RNC3GR6L.js +905 -0
- package/dist/{chunk-VHX673DI.js → chunk-WLPXZFRE.js} +1 -1
- package/dist/{chunk-7F4XE6UG.js → chunk-XD2BAANL.js} +5 -5
- package/dist/{connected-teams-XO766HB4.js → connected-teams-DBWAMP7G.js} +2 -2
- package/dist/{connected-teams-I2WZZZFA.js → connected-teams-WGONUQOF.js} +2 -2
- package/dist/{coordinator-prompt-WGFRYCHE.js → coordinator-prompt-7FHKCWXB.js} +5 -5
- package/dist/{coordinator-prompt-TBX4MOFM.js → coordinator-prompt-KX2FVVYT.js} +5 -5
- package/dist/{cursor-recover-NOQYOFRF.js → cursor-recover-L5MD6MBO.js} +1 -1
- package/dist/{cursor-recover-QSLWEZNA.js → cursor-recover-NDMLLNYX.js} +2 -2
- package/dist/{global-workspace-IY5QAV5C.js → global-workspace-2BRRKSDN.js} +5 -6
- package/dist/{global-workspace-BHLUJ46D.js → global-workspace-4LHCZ2DC.js} +5 -6
- package/dist/index.cjs +1889 -777
- package/dist/index.d.cts +222 -12
- package/dist/index.d.ts +222 -12
- package/dist/index.js +304 -108
- package/dist/mcp/run-stdio.cjs +1747 -1240
- package/dist/mcp/run-stdio.js +232 -80
- package/dist/{orchestrator-256DFPSX.js → orchestrator-3FWEKDAQ.js} +9 -11
- package/dist/{orchestrator-NUA6SEV7.js → orchestrator-HC7XVGJB.js} +10 -12
- package/dist/{paths-UMEDHOS5.js → paths-53TLA7VQ.js} +1 -1
- package/dist/{paths-QCI3MTO5.js → paths-RRCLNSJB.js} +1 -1
- package/dist/{thread-store-WGASXXXR.js → thread-store-KBFBHT5G.js} +2 -2
- package/dist/{thread-store-57ZLHR3A.js → thread-store-MVQU6HPJ.js} +2 -2
- package/dist/{workspaces-4FSXVIZM.js → workspaces-5UNDTN4G.js} +5 -7
- package/dist/{workspaces-NECIQTAO.js → workspaces-MQYNZXUK.js} +5 -7
- package/dist/{worktree-HTUM35NT.js → worktree-PEWDAX5O.js} +4 -4
- package/dist/{worktree-DPIREDFR.js → worktree-T4SWFSTT.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-2U6QF3PT.js +0 -211
- package/dist/chunk-67TIJ7S5.js +0 -122
- package/dist/chunk-7TIUOYBK.js +0 -213
- package/dist/chunk-G4MTYUWS.js +0 -592
- package/dist/chunk-K2ANSHUO.js +0 -120
- package/dist/chunk-SN6CMKF6.js +0 -538
|
@@ -33,18 +33,27 @@ import {
|
|
|
33
33
|
summarizeTurnStderr,
|
|
34
34
|
toolDescription,
|
|
35
35
|
turnFailChatText
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-4THE3EY7.js";
|
|
37
37
|
import {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
extractPresentedPlan,
|
|
39
|
+
readPlanFile,
|
|
40
|
+
writePlanFile
|
|
41
|
+
} from "./chunk-2SDMENAL.js";
|
|
42
|
+
import {
|
|
43
|
+
releaseCaffeinateHoldForThread
|
|
44
|
+
} from "./chunk-OCQPTUR7.js";
|
|
43
45
|
import {
|
|
46
|
+
SLACK_REPLY_FORMATTING,
|
|
47
|
+
addWorkspace,
|
|
44
48
|
assertOrchestratorCapableAgent,
|
|
45
49
|
attachmentsFromWorktreePaths,
|
|
46
50
|
coerceOrchestratorAgent,
|
|
51
|
+
coordinatorSystemPrompt,
|
|
52
|
+
coordinatorTurnReminder,
|
|
47
53
|
createGlobalChat,
|
|
54
|
+
enrichWorkspacesWithGithub,
|
|
55
|
+
ensureGlobalCoordinatorCwd,
|
|
56
|
+
ensureWorkspace,
|
|
48
57
|
healOrchestrationSoccerTitles,
|
|
49
58
|
isCloudCoordinatorThread,
|
|
50
59
|
isGlobalRepoPath,
|
|
@@ -54,24 +63,11 @@ import {
|
|
|
54
63
|
isSlackCoordinatorThread,
|
|
55
64
|
orchestratorSessionPoisonedByBuiltins,
|
|
56
65
|
persistPendingFileAttachments,
|
|
66
|
+
removeWorkspace,
|
|
57
67
|
stageAbsolutePathsAsAttachments,
|
|
58
|
-
stageBuffersAsAttachments
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
extractPresentedPlan,
|
|
62
|
-
readPlanFile,
|
|
63
|
-
writePlanFile
|
|
64
|
-
} from "./chunk-2SDMENAL.js";
|
|
65
|
-
import {
|
|
66
|
-
releaseCaffeinateHoldForThread
|
|
67
|
-
} from "./chunk-KLBOWJ74.js";
|
|
68
|
-
import {
|
|
69
|
-
SLACK_REPLY_FORMATTING,
|
|
70
|
-
coordinatorSystemPrompt,
|
|
71
|
-
coordinatorTurnReminder,
|
|
72
|
-
enrichWorkspacesWithGithub,
|
|
73
|
-
ensureGlobalCoordinatorCwd
|
|
74
|
-
} from "./chunk-7TIUOYBK.js";
|
|
68
|
+
stageBuffersAsAttachments,
|
|
69
|
+
syncWorkspacesFromThreads
|
|
70
|
+
} from "./chunk-RNC3GR6L.js";
|
|
75
71
|
import {
|
|
76
72
|
addPrStackLayer,
|
|
77
73
|
allocateTeamName,
|
|
@@ -119,7 +115,7 @@ import {
|
|
|
119
115
|
withRepoGitLock,
|
|
120
116
|
worktreeDisplayLabelForGroup,
|
|
121
117
|
worktreeNameFromPath
|
|
122
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-CJQLPPEJ.js";
|
|
123
119
|
import {
|
|
124
120
|
ATTACHMENTS_DIR,
|
|
125
121
|
LEGACY_ATTACHMENTS_DIR
|
|
@@ -135,7 +131,7 @@ import {
|
|
|
135
131
|
updateThread,
|
|
136
132
|
withThreadLock,
|
|
137
133
|
writeThread
|
|
138
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-LZQULFIT.js";
|
|
139
135
|
import {
|
|
140
136
|
ensureWorktreeSideboardIgnored
|
|
141
137
|
} from "./chunk-SYFVUF2C.js";
|
|
@@ -162,7 +158,7 @@ import {
|
|
|
162
158
|
stripNestedElectronEnv,
|
|
163
159
|
updateAdvancedSettings,
|
|
164
160
|
writeSecureJson
|
|
165
|
-
} from "./chunk-
|
|
161
|
+
} from "./chunk-D7EGJ3EI.js";
|
|
166
162
|
import {
|
|
167
163
|
writePrivateFile
|
|
168
164
|
} from "./chunk-NSTQ6QKD.js";
|
|
@@ -175,9 +171,10 @@ import {
|
|
|
175
171
|
sideboardReposDir,
|
|
176
172
|
sideboardWorkspacesDir,
|
|
177
173
|
threadLivePath,
|
|
174
|
+
threadsDir,
|
|
178
175
|
workspaceSettingsSourceLabel,
|
|
179
176
|
worktreesRoot
|
|
180
|
-
} from "./chunk-
|
|
177
|
+
} from "./chunk-JTJHOYCU.js";
|
|
181
178
|
|
|
182
179
|
// src/orchestrator/orchestrator.ts
|
|
183
180
|
import { EventEmitter } from "events";
|
|
@@ -395,7 +392,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
395
392
|
await continueOnReply(threadId, prompt);
|
|
396
393
|
return;
|
|
397
394
|
}
|
|
398
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
395
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-3FWEKDAQ.js");
|
|
399
396
|
await getOrchestrator2().send(threadId, prompt);
|
|
400
397
|
} catch {
|
|
401
398
|
}
|
|
@@ -655,7 +652,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
655
652
|
}
|
|
656
653
|
|
|
657
654
|
// src/orchestrator/orchestrator.ts
|
|
658
|
-
import { existsSync as
|
|
655
|
+
import { existsSync as existsSync17 } from "fs";
|
|
659
656
|
|
|
660
657
|
// src/agents/spawn.ts
|
|
661
658
|
import { createInterface } from "readline";
|
|
@@ -736,9 +733,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
736
733
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
737
734
|
);
|
|
738
735
|
}
|
|
739
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
736
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-4LHCZ2DC.js");
|
|
740
737
|
if (isGlobalThread2(thread)) {
|
|
741
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
738
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-KX2FVVYT.js");
|
|
742
739
|
ensureGlobalCoordinatorCwd2(
|
|
743
740
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
744
741
|
);
|
|
@@ -1940,6 +1937,8 @@ async function attachAbort(handle, signal) {
|
|
|
1940
1937
|
async function runSetupScript(repoPath, worktreePath, onLine, opts) {
|
|
1941
1938
|
const settings = loadWorkspaceSettings(worktreePath, repoPath);
|
|
1942
1939
|
if (!settings?.setup) return { ran: false, exitCode: null, source: null };
|
|
1940
|
+
const source = workspaceSettingsSourceLabel(worktreePath, repoPath);
|
|
1941
|
+
onLine?.(`[setup] ${source ?? "settings.toml"}`);
|
|
1943
1942
|
const handle = await spawnWorkspaceScript(settings.setup, {
|
|
1944
1943
|
worktreePath,
|
|
1945
1944
|
repoPath,
|
|
@@ -1950,7 +1949,7 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
|
|
|
1950
1949
|
return {
|
|
1951
1950
|
ran: true,
|
|
1952
1951
|
exitCode,
|
|
1953
|
-
source
|
|
1952
|
+
source,
|
|
1954
1953
|
kill: handle.kill
|
|
1955
1954
|
};
|
|
1956
1955
|
}
|
|
@@ -2079,9 +2078,114 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
2079
2078
|
};
|
|
2080
2079
|
}
|
|
2081
2080
|
|
|
2082
|
-
// src/
|
|
2083
|
-
import { existsSync as existsSync5,
|
|
2081
|
+
// src/store/setup-log.ts
|
|
2082
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
2084
2083
|
import { join as join6 } from "path";
|
|
2084
|
+
var EMPTY = {
|
|
2085
|
+
output: "",
|
|
2086
|
+
running: false,
|
|
2087
|
+
exitCode: null,
|
|
2088
|
+
source: null
|
|
2089
|
+
};
|
|
2090
|
+
var memory = /* @__PURE__ */ new Map();
|
|
2091
|
+
var persistTimers = /* @__PURE__ */ new Map();
|
|
2092
|
+
function setupLogPath(threadId) {
|
|
2093
|
+
return join6(threadsDir(), `${threadId}.setup.log.json`);
|
|
2094
|
+
}
|
|
2095
|
+
function emptySetupLog() {
|
|
2096
|
+
return { ...EMPTY };
|
|
2097
|
+
}
|
|
2098
|
+
function clone(snap) {
|
|
2099
|
+
return { ...snap };
|
|
2100
|
+
}
|
|
2101
|
+
function persistNow(threadId) {
|
|
2102
|
+
const timer = persistTimers.get(threadId);
|
|
2103
|
+
if (timer) {
|
|
2104
|
+
clearTimeout(timer);
|
|
2105
|
+
persistTimers.delete(threadId);
|
|
2106
|
+
}
|
|
2107
|
+
const snap = memory.get(threadId);
|
|
2108
|
+
if (!snap) return;
|
|
2109
|
+
try {
|
|
2110
|
+
writeFileSync2(setupLogPath(threadId), `${JSON.stringify(snap)}
|
|
2111
|
+
`, "utf8");
|
|
2112
|
+
} catch {
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
function schedulePersist(threadId) {
|
|
2116
|
+
if (persistTimers.has(threadId)) return;
|
|
2117
|
+
persistTimers.set(
|
|
2118
|
+
threadId,
|
|
2119
|
+
setTimeout(() => {
|
|
2120
|
+
persistTimers.delete(threadId);
|
|
2121
|
+
persistNow(threadId);
|
|
2122
|
+
}, 100)
|
|
2123
|
+
);
|
|
2124
|
+
}
|
|
2125
|
+
function loadFromDisk(threadId) {
|
|
2126
|
+
const path = setupLogPath(threadId);
|
|
2127
|
+
if (!existsSync5(path)) return null;
|
|
2128
|
+
try {
|
|
2129
|
+
const raw = JSON.parse(readFileSync5(path, "utf8"));
|
|
2130
|
+
return {
|
|
2131
|
+
output: typeof raw.output === "string" ? raw.output : "",
|
|
2132
|
+
running: Boolean(raw.running),
|
|
2133
|
+
exitCode: typeof raw.exitCode === "number" ? raw.exitCode : null,
|
|
2134
|
+
source: typeof raw.source === "string" ? raw.source : null
|
|
2135
|
+
};
|
|
2136
|
+
} catch {
|
|
2137
|
+
return null;
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
function readSetupLog(threadId) {
|
|
2141
|
+
const cached = memory.get(threadId);
|
|
2142
|
+
if (cached) return clone(cached);
|
|
2143
|
+
const disk = loadFromDisk(threadId);
|
|
2144
|
+
if (disk) {
|
|
2145
|
+
memory.set(threadId, disk);
|
|
2146
|
+
return clone(disk);
|
|
2147
|
+
}
|
|
2148
|
+
return emptySetupLog();
|
|
2149
|
+
}
|
|
2150
|
+
function beginSetupLog(threadId) {
|
|
2151
|
+
const snap = {
|
|
2152
|
+
output: "",
|
|
2153
|
+
running: true,
|
|
2154
|
+
exitCode: null,
|
|
2155
|
+
source: null
|
|
2156
|
+
};
|
|
2157
|
+
memory.set(threadId, snap);
|
|
2158
|
+
persistNow(threadId);
|
|
2159
|
+
return clone(snap);
|
|
2160
|
+
}
|
|
2161
|
+
function appendSetupLog(threadId, line) {
|
|
2162
|
+
const current = memory.get(threadId) ?? readSetupLog(threadId);
|
|
2163
|
+
const snap = {
|
|
2164
|
+
...current,
|
|
2165
|
+
output: current.output ? `${current.output}
|
|
2166
|
+
${line}` : line,
|
|
2167
|
+
running: true
|
|
2168
|
+
};
|
|
2169
|
+
memory.set(threadId, snap);
|
|
2170
|
+
schedulePersist(threadId);
|
|
2171
|
+
return clone(snap);
|
|
2172
|
+
}
|
|
2173
|
+
function finishSetupLog(threadId, exitCode, source) {
|
|
2174
|
+
const current = memory.get(threadId) ?? readSetupLog(threadId);
|
|
2175
|
+
const snap = {
|
|
2176
|
+
...current,
|
|
2177
|
+
running: false,
|
|
2178
|
+
exitCode,
|
|
2179
|
+
source: source ?? current.source
|
|
2180
|
+
};
|
|
2181
|
+
memory.set(threadId, snap);
|
|
2182
|
+
persistNow(threadId);
|
|
2183
|
+
return clone(snap);
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
// src/git/orphan-cleanup.ts
|
|
2187
|
+
import { existsSync as existsSync6, readdirSync as readdirSync2, statSync } from "fs";
|
|
2188
|
+
import { join as join7 } from "path";
|
|
2085
2189
|
function isSideboardWorktreePath(path) {
|
|
2086
2190
|
return path.includes("/.sideboard/worktrees/") || path.includes("/sideboard/workspaces/");
|
|
2087
2191
|
}
|
|
@@ -2092,7 +2196,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
2092
2196
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
2093
2197
|
);
|
|
2094
2198
|
const homeRoot = sideboardWorkspacesDir();
|
|
2095
|
-
if (
|
|
2199
|
+
if (existsSync6(homeRoot)) {
|
|
2096
2200
|
try {
|
|
2097
2201
|
for (const entry of readdirSync2(homeRoot, { withFileTypes: true })) {
|
|
2098
2202
|
if (!entry.isDirectory()) continue;
|
|
@@ -2104,7 +2208,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
2104
2208
|
const orphans = [];
|
|
2105
2209
|
const seen = /* @__PURE__ */ new Set();
|
|
2106
2210
|
for (const repoPath of repos) {
|
|
2107
|
-
if (!repoPath || !
|
|
2211
|
+
if (!repoPath || !existsSync6(repoPath)) continue;
|
|
2108
2212
|
try {
|
|
2109
2213
|
const wts = await listWorktrees(repoPath);
|
|
2110
2214
|
for (const wt of wts) {
|
|
@@ -2125,12 +2229,12 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
2125
2229
|
}
|
|
2126
2230
|
try {
|
|
2127
2231
|
const root = worktreesRoot(repoPath);
|
|
2128
|
-
if (
|
|
2232
|
+
if (existsSync6(root)) {
|
|
2129
2233
|
for (const entry of readdirSync2(root, { withFileTypes: true })) {
|
|
2130
2234
|
if (!entry.isDirectory()) continue;
|
|
2131
|
-
const path =
|
|
2235
|
+
const path = join7(root, entry.name).replace(/\/$/, "");
|
|
2132
2236
|
if (known.has(path) || seen.has(path)) continue;
|
|
2133
|
-
if (!
|
|
2237
|
+
if (!existsSync6(join7(path, ".git"))) continue;
|
|
2134
2238
|
seen.add(path);
|
|
2135
2239
|
let mtimeMs = 0;
|
|
2136
2240
|
try {
|
|
@@ -2270,8 +2374,8 @@ async function applyThreadIntoMain(thread, opts) {
|
|
|
2270
2374
|
}
|
|
2271
2375
|
|
|
2272
2376
|
// src/git/clone-repo.ts
|
|
2273
|
-
import { existsSync as
|
|
2274
|
-
import { basename as basename2, join as
|
|
2377
|
+
import { existsSync as existsSync7 } from "fs";
|
|
2378
|
+
import { basename as basename2, join as join8 } from "path";
|
|
2275
2379
|
import { execa as execa4 } from "execa";
|
|
2276
2380
|
async function cloneRepoIntoSideboard(opts) {
|
|
2277
2381
|
const url = opts.url.trim();
|
|
@@ -2282,8 +2386,8 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
2282
2386
|
name = leaf || "repo";
|
|
2283
2387
|
}
|
|
2284
2388
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
2285
|
-
const dest =
|
|
2286
|
-
if (
|
|
2389
|
+
const dest = join8(sideboardReposDir(), name);
|
|
2390
|
+
if (existsSync7(dest)) {
|
|
2287
2391
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
2288
2392
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
2289
2393
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -2300,14 +2404,14 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
2300
2404
|
}
|
|
2301
2405
|
|
|
2302
2406
|
// src/store/desktop-host.ts
|
|
2303
|
-
import { readFileSync as
|
|
2304
|
-
import { join as
|
|
2407
|
+
import { readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
2408
|
+
import { join as join9 } from "path";
|
|
2305
2409
|
function desktopHostPidPath() {
|
|
2306
|
-
return
|
|
2410
|
+
return join9(appDataDir(), "desktop-host.pid");
|
|
2307
2411
|
}
|
|
2308
2412
|
function readDesktopHostPid() {
|
|
2309
2413
|
try {
|
|
2310
|
-
const pid = Number.parseInt(
|
|
2414
|
+
const pid = Number.parseInt(readFileSync6(desktopHostPidPath(), "utf8").trim(), 10);
|
|
2311
2415
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
2312
2416
|
return pid;
|
|
2313
2417
|
} catch {
|
|
@@ -2374,7 +2478,7 @@ function notifyParentOfChildHalt(child, status, send) {
|
|
|
2374
2478
|
}
|
|
2375
2479
|
|
|
2376
2480
|
// src/threads/create.ts
|
|
2377
|
-
import { existsSync as
|
|
2481
|
+
import { existsSync as existsSync8 } from "fs";
|
|
2378
2482
|
|
|
2379
2483
|
// src/detect/detect.ts
|
|
2380
2484
|
var REQUIRE_AGENT_TIMEOUT_MS = 8e3;
|
|
@@ -2540,12 +2644,19 @@ function urlsMatch(a, b) {
|
|
|
2540
2644
|
const norm = (u) => u.trim().replace(/\/+$/, "").toLowerCase();
|
|
2541
2645
|
return Boolean(a && b && norm(a) === norm(b));
|
|
2542
2646
|
}
|
|
2647
|
+
function threadPrUrlMatchesNumber(thread, number) {
|
|
2648
|
+
if (!Number.isFinite(number) || number < 1) return false;
|
|
2649
|
+
const url = (thread.prUrl ?? "").trim();
|
|
2650
|
+
if (!url) return false;
|
|
2651
|
+
return new RegExp(`/pull/${number}(?:/|$|[?#])`, "i").test(url);
|
|
2652
|
+
}
|
|
2543
2653
|
function threadMatchesPr(thread, pr) {
|
|
2544
2654
|
const num = String(pr.number);
|
|
2545
2655
|
if (thread.sourceType === "pr" && normalizeIssueKey(thread.sourceRef ?? "") === num) {
|
|
2546
2656
|
return true;
|
|
2547
2657
|
}
|
|
2548
2658
|
if (thread.prUrl && pr.url && urlsMatch(thread.prUrl, pr.url)) return true;
|
|
2659
|
+
if (threadPrUrlMatchesNumber(thread, pr.number)) return true;
|
|
2549
2660
|
const head = pr.headRefName.trim().toLowerCase();
|
|
2550
2661
|
if (!head) return false;
|
|
2551
2662
|
const branch = (thread.branchName ?? "").trim().toLowerCase();
|
|
@@ -2598,19 +2709,32 @@ function findLiveThreadForCreate(input, threads) {
|
|
|
2598
2709
|
(t) => threadMatchesPr(t, {
|
|
2599
2710
|
number: Number.isFinite(number) ? number : -1,
|
|
2600
2711
|
title: input.title ?? "",
|
|
2601
|
-
url: "",
|
|
2602
|
-
headRefName: ""
|
|
2712
|
+
url: input.prUrl ?? "",
|
|
2713
|
+
headRefName: input.headRefName ?? ""
|
|
2603
2714
|
})
|
|
2604
2715
|
);
|
|
2605
2716
|
}
|
|
2606
2717
|
if (input.sourceType === "branch") {
|
|
2607
2718
|
if (isDefaultBranchCreateRef(input.sourceRef)) return void 0;
|
|
2608
|
-
|
|
2719
|
+
const byBranch = live.find(
|
|
2609
2720
|
(t) => threadMatchesBranch(t, {
|
|
2610
2721
|
ref: input.sourceRef,
|
|
2611
2722
|
repoPath: input.repoPath
|
|
2612
2723
|
})
|
|
2613
2724
|
);
|
|
2725
|
+
if (byBranch) return byBranch;
|
|
2726
|
+
if (input.prUrl || input.headRefName) {
|
|
2727
|
+
const number = Number(normalizeIssueKey(input.sourceRef));
|
|
2728
|
+
return live.find(
|
|
2729
|
+
(t) => threadMatchesPr(t, {
|
|
2730
|
+
number: Number.isFinite(number) ? number : -1,
|
|
2731
|
+
title: input.title ?? "",
|
|
2732
|
+
url: input.prUrl ?? "",
|
|
2733
|
+
headRefName: input.headRefName ?? input.sourceRef
|
|
2734
|
+
})
|
|
2735
|
+
);
|
|
2736
|
+
}
|
|
2737
|
+
return void 0;
|
|
2614
2738
|
}
|
|
2615
2739
|
return void 0;
|
|
2616
2740
|
}
|
|
@@ -2836,42 +2960,53 @@ function assembleHomeBoard(input) {
|
|
|
2836
2960
|
}
|
|
2837
2961
|
return { columns, hidden, totals };
|
|
2838
2962
|
}
|
|
2839
|
-
var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards).
|
|
2963
|
+
var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards). Do not create a second worktree for a ticket, PR, or named branch that already has a live checkout \u2014 create_thread / start_board_card return that thread (alreadyStarted). Creating from the default branch still opens a new isolated worktree. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats stay in the sidebar. Do not invent status.";
|
|
2840
2964
|
|
|
2841
2965
|
// src/threads/create.ts
|
|
2842
2966
|
function persistCreateAttachments(worktreePath, attachments) {
|
|
2843
2967
|
return persistPendingFileAttachments(worktreePath, attachments ?? []);
|
|
2844
2968
|
}
|
|
2969
|
+
function liveThreadsForCreate() {
|
|
2970
|
+
return listThreads({ includeArchived: false }).map((t) => ({
|
|
2971
|
+
...t,
|
|
2972
|
+
repoPath: canonicalizeRepoPath(t.repoPath)
|
|
2973
|
+
}));
|
|
2974
|
+
}
|
|
2975
|
+
function reuseLiveThread(input, repoPath, match) {
|
|
2976
|
+
if (input.reuseExisting === false) return void 0;
|
|
2977
|
+
const existing = findLiveThreadForCreate(
|
|
2978
|
+
{
|
|
2979
|
+
sourceType: match.sourceType,
|
|
2980
|
+
sourceRef: match.sourceRef,
|
|
2981
|
+
repoPath,
|
|
2982
|
+
title: match.title ?? input.title,
|
|
2983
|
+
cowboy: input.cowboy,
|
|
2984
|
+
prUrl: match.prUrl,
|
|
2985
|
+
headRefName: match.headRefName
|
|
2986
|
+
},
|
|
2987
|
+
liveThreadsForCreate()
|
|
2988
|
+
);
|
|
2989
|
+
if (!existing) return void 0;
|
|
2990
|
+
const thread = readThread(existing.id) ?? existing;
|
|
2991
|
+
if (!input.attachments?.length) return thread;
|
|
2992
|
+
return updateThread(thread.id, {
|
|
2993
|
+
attachments: persistCreateAttachments(thread.worktreePath, [
|
|
2994
|
+
...thread.attachments,
|
|
2995
|
+
...input.attachments
|
|
2996
|
+
])
|
|
2997
|
+
});
|
|
2998
|
+
}
|
|
2845
2999
|
async function createThread(input, _onSetupLine) {
|
|
2846
3000
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
2847
|
-
if (!
|
|
3001
|
+
if (!existsSync8(repoPath)) {
|
|
2848
3002
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
2849
3003
|
}
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
title: input.title,
|
|
2857
|
-
cowboy: input.cowboy
|
|
2858
|
-
},
|
|
2859
|
-
listThreads({ includeArchived: false }).map((t) => ({
|
|
2860
|
-
...t,
|
|
2861
|
-
repoPath: canonicalizeRepoPath(t.repoPath)
|
|
2862
|
-
}))
|
|
2863
|
-
);
|
|
2864
|
-
if (existing) {
|
|
2865
|
-
const thread2 = readThread(existing.id) ?? existing;
|
|
2866
|
-
if (!input.attachments?.length) return thread2;
|
|
2867
|
-
return updateThread(thread2.id, {
|
|
2868
|
-
attachments: persistCreateAttachments(thread2.worktreePath, [
|
|
2869
|
-
...thread2.attachments,
|
|
2870
|
-
...input.attachments
|
|
2871
|
-
])
|
|
2872
|
-
});
|
|
2873
|
-
}
|
|
2874
|
-
}
|
|
3004
|
+
const reused = reuseLiveThread(input, repoPath, {
|
|
3005
|
+
sourceType: input.sourceType,
|
|
3006
|
+
sourceRef: input.sourceRef,
|
|
3007
|
+
title: input.title
|
|
3008
|
+
});
|
|
3009
|
+
if (reused) return reused;
|
|
2875
3010
|
const resolved = resolveNewThreadOptions({
|
|
2876
3011
|
agent: input.agent,
|
|
2877
3012
|
model: input.model,
|
|
@@ -2880,7 +3015,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2880
3015
|
});
|
|
2881
3016
|
await requireAgent(resolved.agent);
|
|
2882
3017
|
if (input.cowboy) {
|
|
2883
|
-
const { cowboyModeEnabled } = await import("./app-settings-
|
|
3018
|
+
const { cowboyModeEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
2884
3019
|
if (!cowboyModeEnabled()) {
|
|
2885
3020
|
throw new Error(
|
|
2886
3021
|
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
@@ -2938,7 +3073,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2938
3073
|
let sourceIsFork = false;
|
|
2939
3074
|
if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
|
|
2940
3075
|
if (isAbleTimeConnected() && getIssueSource() === "abletime") {
|
|
2941
|
-
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-
|
|
3076
|
+
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-JSTJLXAW.js");
|
|
2942
3077
|
const task = await ensureAbleTimeTask({
|
|
2943
3078
|
title: title?.trim() || "Untitled work",
|
|
2944
3079
|
description: input.prompt?.trim() || void 0
|
|
@@ -2948,6 +3083,12 @@ async function createThread(input, _onSetupLine) {
|
|
|
2948
3083
|
persistedSourceRef = task.identifier;
|
|
2949
3084
|
title = title?.trim() || task.title;
|
|
2950
3085
|
attachments = [...attachments, issueAttachmentForAbleTimeTask(task)];
|
|
3086
|
+
const reusedTicket = reuseLiveThread(
|
|
3087
|
+
{ ...input, sourceType: "ticket", sourceRef, title, attachments },
|
|
3088
|
+
repoPath,
|
|
3089
|
+
{ sourceType: "ticket", sourceRef, title }
|
|
3090
|
+
);
|
|
3091
|
+
if (reusedTicket) return reusedTicket;
|
|
2951
3092
|
}
|
|
2952
3093
|
}
|
|
2953
3094
|
let prUrl = null;
|
|
@@ -2957,6 +3098,14 @@ async function createThread(input, _onSetupLine) {
|
|
|
2957
3098
|
if (!Number.isFinite(num)) throw new Error(`Invalid PR number: ${input.sourceRef}`);
|
|
2958
3099
|
const pr = await getPr(repoPath, num);
|
|
2959
3100
|
if (!pr) throw new Error(`PR #${num} not found`);
|
|
3101
|
+
const reusedPr = reuseLiveThread(input, repoPath, {
|
|
3102
|
+
sourceType: "pr",
|
|
3103
|
+
sourceRef: String(pr.number),
|
|
3104
|
+
title: input.title ?? pr.title,
|
|
3105
|
+
prUrl: pr.url,
|
|
3106
|
+
headRefName: pr.headRefName
|
|
3107
|
+
});
|
|
3108
|
+
if (reusedPr) return reusedPr;
|
|
2960
3109
|
sourceIsFork = pr.isCrossRepository;
|
|
2961
3110
|
prUrl = pr.url;
|
|
2962
3111
|
const localFetchBranch = `sideboard-pr-${pr.number}`;
|
|
@@ -2969,9 +3118,19 @@ async function createThread(input, _onSetupLine) {
|
|
|
2969
3118
|
sourceRef = await resolveDefaultBranch(repoPath);
|
|
2970
3119
|
} else {
|
|
2971
3120
|
const existing = await getPrForHeadBranch(repoPath, sourceRef);
|
|
2972
|
-
if (existing
|
|
2973
|
-
|
|
2974
|
-
|
|
3121
|
+
if (existing) {
|
|
3122
|
+
const reusedPr = reuseLiveThread(input, repoPath, {
|
|
3123
|
+
sourceType: "pr",
|
|
3124
|
+
sourceRef: String(existing.number),
|
|
3125
|
+
title: input.title ?? existing.title,
|
|
3126
|
+
prUrl: existing.url,
|
|
3127
|
+
headRefName: existing.headRefName
|
|
3128
|
+
});
|
|
3129
|
+
if (reusedPr) return reusedPr;
|
|
3130
|
+
if (existing.url) {
|
|
3131
|
+
prUrl = existing.url;
|
|
3132
|
+
prTitle = existing.title;
|
|
3133
|
+
}
|
|
2975
3134
|
}
|
|
2976
3135
|
}
|
|
2977
3136
|
} else if (sourceType === "adopt") {
|
|
@@ -3010,15 +3169,6 @@ async function createThread(input, _onSetupLine) {
|
|
|
3010
3169
|
await ensureWorkspace(repoPath);
|
|
3011
3170
|
return readThread(thread.id) ?? thread;
|
|
3012
3171
|
}
|
|
3013
|
-
async function listLinearIssues(agent, repoPath) {
|
|
3014
|
-
const { getAdapter: getAdapter2 } = await import("./agents-CUKWIM34.js");
|
|
3015
|
-
await requireAgent(agent, { requireLinear: true });
|
|
3016
|
-
const adapter = getAdapter2(agent);
|
|
3017
|
-
if (!adapter.listLinearIssues) {
|
|
3018
|
-
throw new Error(`${agent} does not support Linear issue listing`);
|
|
3019
|
-
}
|
|
3020
|
-
return adapter.listLinearIssues(repoPath);
|
|
3021
|
-
}
|
|
3022
3172
|
|
|
3023
3173
|
// src/threads/cowboy.ts
|
|
3024
3174
|
function isCowboyThread(thread) {
|
|
@@ -3034,11 +3184,11 @@ function shouldRemoveWorktreeOnTeardown(thread) {
|
|
|
3034
3184
|
|
|
3035
3185
|
// src/store/turn-live.ts
|
|
3036
3186
|
import {
|
|
3037
|
-
existsSync as
|
|
3187
|
+
existsSync as existsSync9,
|
|
3038
3188
|
renameSync,
|
|
3039
3189
|
unlinkSync as unlinkSync2,
|
|
3040
|
-
writeFileSync as
|
|
3041
|
-
readFileSync as
|
|
3190
|
+
writeFileSync as writeFileSync4,
|
|
3191
|
+
readFileSync as readFileSync7
|
|
3042
3192
|
} from "fs";
|
|
3043
3193
|
var buffers = /* @__PURE__ */ new Map();
|
|
3044
3194
|
var FLUSH_MS = 800;
|
|
@@ -3115,7 +3265,7 @@ function writeTurnLive(threadId, progress) {
|
|
|
3115
3265
|
const path = threadLivePath(threadId);
|
|
3116
3266
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
3117
3267
|
try {
|
|
3118
|
-
|
|
3268
|
+
writeFileSync4(tmp, JSON.stringify(progress), "utf8");
|
|
3119
3269
|
renameSync(tmp, path);
|
|
3120
3270
|
} catch {
|
|
3121
3271
|
try {
|
|
@@ -3126,9 +3276,9 @@ function writeTurnLive(threadId, progress) {
|
|
|
3126
3276
|
}
|
|
3127
3277
|
function readTurnLive(threadId) {
|
|
3128
3278
|
const path = threadLivePath(threadId);
|
|
3129
|
-
if (!
|
|
3279
|
+
if (!existsSync9(path)) return null;
|
|
3130
3280
|
try {
|
|
3131
|
-
const raw = JSON.parse(
|
|
3281
|
+
const raw = JSON.parse(readFileSync7(path, "utf8"));
|
|
3132
3282
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
3133
3283
|
return raw;
|
|
3134
3284
|
} catch {
|
|
@@ -3140,7 +3290,7 @@ function clearTurnLive(threadId) {
|
|
|
3140
3290
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
3141
3291
|
buffers.delete(threadId);
|
|
3142
3292
|
const path = threadLivePath(threadId);
|
|
3143
|
-
if (!
|
|
3293
|
+
if (!existsSync9(path)) return;
|
|
3144
3294
|
try {
|
|
3145
3295
|
unlinkSync2(path);
|
|
3146
3296
|
} catch {
|
|
@@ -3165,7 +3315,8 @@ function shouldReadThreadToHealReconcile(eventType, lastCheckAt, now) {
|
|
|
3165
3315
|
// src/orchestrator/setup-last-error.ts
|
|
3166
3316
|
function shouldStampSetupLastError(opts) {
|
|
3167
3317
|
if (opts.turnInFlight) return false;
|
|
3168
|
-
if (opts.status === "running") return false;
|
|
3318
|
+
if (opts.status === "running" || opts.status === "queued") return false;
|
|
3319
|
+
if (opts.hasQueuedPrompt) return false;
|
|
3169
3320
|
return true;
|
|
3170
3321
|
}
|
|
3171
3322
|
function isStaleLastErrorDuringTurn(err) {
|
|
@@ -3324,26 +3475,26 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
|
|
|
3324
3475
|
import { execFileSync } from "child_process";
|
|
3325
3476
|
import {
|
|
3326
3477
|
copyFileSync as copyFileSync2,
|
|
3327
|
-
existsSync as
|
|
3478
|
+
existsSync as existsSync10,
|
|
3328
3479
|
mkdtempSync,
|
|
3329
3480
|
readdirSync as readdirSync3,
|
|
3330
|
-
readFileSync as
|
|
3481
|
+
readFileSync as readFileSync8,
|
|
3331
3482
|
rmSync
|
|
3332
3483
|
} from "fs";
|
|
3333
3484
|
import { tmpdir } from "os";
|
|
3334
|
-
import { join as
|
|
3485
|
+
import { join as join10 } from "path";
|
|
3335
3486
|
import { createRequire } from "module";
|
|
3336
|
-
var CONDUCTOR_APP_SUPPORT =
|
|
3487
|
+
var CONDUCTOR_APP_SUPPORT = join10(
|
|
3337
3488
|
process.env.HOME ?? "",
|
|
3338
3489
|
"Library",
|
|
3339
3490
|
"Application Support",
|
|
3340
3491
|
"com.conductor.app"
|
|
3341
3492
|
);
|
|
3342
|
-
var CONDUCTOR_DB =
|
|
3343
|
-
var CURSOR_SDK_STORE =
|
|
3493
|
+
var CONDUCTOR_DB = join10(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
3494
|
+
var CURSOR_SDK_STORE = join10(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
3344
3495
|
function thisModuleFile() {
|
|
3345
3496
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
3346
|
-
return cjsFile || process.argv[1] ||
|
|
3497
|
+
return cjsFile || process.argv[1] || join10(process.cwd(), "package.json");
|
|
3347
3498
|
}
|
|
3348
3499
|
function openReadonlySqlite(file) {
|
|
3349
3500
|
const req = createRequire(thisModuleFile());
|
|
@@ -3361,7 +3512,7 @@ function mapAgentType(raw) {
|
|
|
3361
3512
|
return null;
|
|
3362
3513
|
}
|
|
3363
3514
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
3364
|
-
if (!workspacePath || !
|
|
3515
|
+
if (!workspacePath || !existsSync10(CURSOR_SDK_STORE)) return null;
|
|
3365
3516
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
3366
3517
|
let best = null;
|
|
3367
3518
|
let hashes;
|
|
@@ -3371,11 +3522,11 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
3371
3522
|
return null;
|
|
3372
3523
|
}
|
|
3373
3524
|
for (const hash of hashes) {
|
|
3374
|
-
const agentsFile =
|
|
3375
|
-
if (!
|
|
3525
|
+
const agentsFile = join10(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
3526
|
+
if (!existsSync10(agentsFile)) continue;
|
|
3376
3527
|
let text;
|
|
3377
3528
|
try {
|
|
3378
|
-
text =
|
|
3529
|
+
text = readFileSync8(agentsFile, "utf8");
|
|
3379
3530
|
} catch {
|
|
3380
3531
|
continue;
|
|
3381
3532
|
}
|
|
@@ -3399,7 +3550,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
3399
3550
|
return best?.agentId ?? null;
|
|
3400
3551
|
}
|
|
3401
3552
|
async function adoptThread(input) {
|
|
3402
|
-
if (!
|
|
3553
|
+
if (!existsSync10(input.worktreePath)) {
|
|
3403
3554
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
3404
3555
|
}
|
|
3405
3556
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -3418,23 +3569,23 @@ async function adoptThread(input) {
|
|
|
3418
3569
|
messages: input.messages ?? []
|
|
3419
3570
|
});
|
|
3420
3571
|
writeThread(thread);
|
|
3421
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
3572
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-MQYNZXUK.js");
|
|
3422
3573
|
await ensureWorkspace2(repoPath);
|
|
3423
3574
|
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
|
|
3424
3575
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
3425
3576
|
return thread;
|
|
3426
3577
|
}
|
|
3427
3578
|
function listConductorWorkspaces() {
|
|
3428
|
-
if (!
|
|
3579
|
+
if (!existsSync10(CONDUCTOR_DB)) {
|
|
3429
3580
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
3430
3581
|
}
|
|
3431
|
-
const tmp = mkdtempSync(
|
|
3432
|
-
const snapshot =
|
|
3582
|
+
const tmp = mkdtempSync(join10(tmpdir(), "sideboard-conductor-"));
|
|
3583
|
+
const snapshot = join10(tmp, "conductor.db");
|
|
3433
3584
|
try {
|
|
3434
3585
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
3435
3586
|
for (const suffix of ["-wal", "-shm"]) {
|
|
3436
3587
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
3437
|
-
if (
|
|
3588
|
+
if (existsSync10(src)) {
|
|
3438
3589
|
try {
|
|
3439
3590
|
copyFileSync2(src, `${snapshot}${suffix}`);
|
|
3440
3591
|
} catch {
|
|
@@ -3516,16 +3667,16 @@ function listConductorWorkspaces() {
|
|
|
3516
3667
|
}
|
|
3517
3668
|
}
|
|
3518
3669
|
function importConductorWorkspace(workspaceId) {
|
|
3519
|
-
if (!
|
|
3670
|
+
if (!existsSync10(CONDUCTOR_DB)) {
|
|
3520
3671
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
3521
3672
|
}
|
|
3522
|
-
const tmp = mkdtempSync(
|
|
3523
|
-
const snapshot =
|
|
3673
|
+
const tmp = mkdtempSync(join10(tmpdir(), "sideboard-conductor-"));
|
|
3674
|
+
const snapshot = join10(tmp, "conductor.db");
|
|
3524
3675
|
try {
|
|
3525
3676
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
3526
3677
|
for (const suffix of ["-wal", "-shm"]) {
|
|
3527
3678
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
3528
|
-
if (
|
|
3679
|
+
if (existsSync10(src)) {
|
|
3529
3680
|
try {
|
|
3530
3681
|
copyFileSync2(src, `${snapshot}${suffix}`);
|
|
3531
3682
|
} catch {
|
|
@@ -3545,7 +3696,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
3545
3696
|
).get(workspaceId);
|
|
3546
3697
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
3547
3698
|
const worktreePath = String(row.workspacePath);
|
|
3548
|
-
if (!
|
|
3699
|
+
if (!existsSync10(worktreePath)) {
|
|
3549
3700
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
3550
3701
|
}
|
|
3551
3702
|
let sessionId = null;
|
|
@@ -3616,7 +3767,7 @@ async function importConductorWorkspaceAsync(workspaceId) {
|
|
|
3616
3767
|
}
|
|
3617
3768
|
|
|
3618
3769
|
// src/threads/stack-layers.ts
|
|
3619
|
-
import { existsSync as
|
|
3770
|
+
import { existsSync as existsSync11 } from "fs";
|
|
3620
3771
|
function stackIdFrom(stack) {
|
|
3621
3772
|
if (stack.stackNumber != null) return `gh-stack-${stack.stackNumber}`;
|
|
3622
3773
|
const key = stack.layers.map((l) => l.branchName).join("|");
|
|
@@ -3679,7 +3830,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
3679
3830
|
let createdWorktree = false;
|
|
3680
3831
|
const trees = await listWorktrees(repoPath);
|
|
3681
3832
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
3682
|
-
if (checkedOut?.path &&
|
|
3833
|
+
if (checkedOut?.path && existsSync11(checkedOut.path)) {
|
|
3683
3834
|
if (input.reuseExistingWorktree !== false) {
|
|
3684
3835
|
worktreePath = checkedOut.path;
|
|
3685
3836
|
} else {
|
|
@@ -3821,7 +3972,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
3821
3972
|
async function createPrStack(input, onSetupLine) {
|
|
3822
3973
|
await requireAgent(input.agent);
|
|
3823
3974
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
3824
|
-
if (!
|
|
3975
|
+
if (!existsSync11(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
3825
3976
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
3826
3977
|
const status = await detectGhStack(repoPath);
|
|
3827
3978
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -3888,7 +4039,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
3888
4039
|
}
|
|
3889
4040
|
}
|
|
3890
4041
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
3891
|
-
if (!claimed.has(bootstrap.worktreePath) &&
|
|
4042
|
+
if (!claimed.has(bootstrap.worktreePath) && existsSync11(bootstrap.worktreePath)) {
|
|
3892
4043
|
try {
|
|
3893
4044
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
3894
4045
|
deleteBranch: bootstrap.branchName
|
|
@@ -3900,10 +4051,10 @@ async function createPrStack(input, onSetupLine) {
|
|
|
3900
4051
|
}
|
|
3901
4052
|
|
|
3902
4053
|
// src/diff/diff.ts
|
|
3903
|
-
import { existsSync as
|
|
3904
|
-
import { dirname as dirname3, join as
|
|
4054
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync3, readFileSync as readFileSync9, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
4055
|
+
import { dirname as dirname3, join as join11 } from "path";
|
|
3905
4056
|
async function inspectGitWorktree(worktreePath) {
|
|
3906
|
-
if (!worktreePath || !
|
|
4057
|
+
if (!worktreePath || !existsSync12(worktreePath)) return "missing_worktree";
|
|
3907
4058
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
3908
4059
|
reject: false
|
|
3909
4060
|
});
|
|
@@ -3911,7 +4062,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
3911
4062
|
return "ok";
|
|
3912
4063
|
}
|
|
3913
4064
|
async function initializeGitRepository(worktreePath) {
|
|
3914
|
-
if (!worktreePath || !
|
|
4065
|
+
if (!worktreePath || !existsSync12(worktreePath)) {
|
|
3915
4066
|
throw new Error("Worktree not found");
|
|
3916
4067
|
}
|
|
3917
4068
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -4047,11 +4198,11 @@ new file mode 100644
|
|
|
4047
4198
|
};
|
|
4048
4199
|
}
|
|
4049
4200
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
4050
|
-
const abs =
|
|
4201
|
+
const abs = join11(worktreePath, path);
|
|
4051
4202
|
try {
|
|
4052
4203
|
const st = statSync2(abs);
|
|
4053
4204
|
if (st.isFile() && st.size > maxHunk) {
|
|
4054
|
-
const buf =
|
|
4205
|
+
const buf = readFileSync9(abs).subarray(0, maxHunk);
|
|
4055
4206
|
return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
|
|
4056
4207
|
}
|
|
4057
4208
|
} catch {
|
|
@@ -4552,7 +4703,7 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
|
4552
4703
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
4553
4704
|
assertSafeRelativePath(relativePath);
|
|
4554
4705
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
4555
|
-
const abs =
|
|
4706
|
+
const abs = join11(worktreePath, relativePath);
|
|
4556
4707
|
const st = statSync2(abs);
|
|
4557
4708
|
if (!st.isFile()) {
|
|
4558
4709
|
throw new Error(`Not a file: ${relativePath}`);
|
|
@@ -4562,7 +4713,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
4562
4713
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
4563
4714
|
);
|
|
4564
4715
|
}
|
|
4565
|
-
const buf =
|
|
4716
|
+
const buf = readFileSync9(abs);
|
|
4566
4717
|
return {
|
|
4567
4718
|
path: relativePath,
|
|
4568
4719
|
contentBase64: buf.toString("base64"),
|
|
@@ -4572,12 +4723,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
4572
4723
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
4573
4724
|
assertSafeRelativePath(relativePath);
|
|
4574
4725
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
4575
|
-
const abs =
|
|
4726
|
+
const abs = join11(worktreePath, relativePath);
|
|
4576
4727
|
const st = statSync2(abs);
|
|
4577
4728
|
if (!st.isFile()) {
|
|
4578
4729
|
throw new Error(`Not a file: ${relativePath}`);
|
|
4579
4730
|
}
|
|
4580
|
-
const buf =
|
|
4731
|
+
const buf = readFileSync9(abs);
|
|
4581
4732
|
if (isImageRelativePath(relativePath)) {
|
|
4582
4733
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
4583
4734
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -4620,9 +4771,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
4620
4771
|
}
|
|
4621
4772
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
4622
4773
|
assertSafeRelativePath(relativePath);
|
|
4623
|
-
const abs =
|
|
4774
|
+
const abs = join11(worktreePath, relativePath);
|
|
4624
4775
|
mkdirSync3(dirname3(abs), { recursive: true });
|
|
4625
|
-
|
|
4776
|
+
writeFileSync5(abs, content, "utf8");
|
|
4626
4777
|
return { path: relativePath };
|
|
4627
4778
|
}
|
|
4628
4779
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -4747,9 +4898,9 @@ async function confirmLand(thread, opts) {
|
|
|
4747
4898
|
}
|
|
4748
4899
|
|
|
4749
4900
|
// src/skills/discover.ts
|
|
4750
|
-
import { existsSync as
|
|
4901
|
+
import { existsSync as existsSync13, readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
|
|
4751
4902
|
import { homedir } from "os";
|
|
4752
|
-
import { join as
|
|
4903
|
+
import { join as join12 } from "path";
|
|
4753
4904
|
|
|
4754
4905
|
// src/skills/bundled/long-running.ts
|
|
4755
4906
|
var LONG_RUNNING_SKILL_COMMAND = "long-running";
|
|
@@ -4878,7 +5029,7 @@ function parseFrontmatter(content) {
|
|
|
4878
5029
|
}
|
|
4879
5030
|
function readSkill(skillMd, source) {
|
|
4880
5031
|
try {
|
|
4881
|
-
const content =
|
|
5032
|
+
const content = readFileSync10(skillMd, "utf8");
|
|
4882
5033
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
4883
5034
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
4884
5035
|
const name = fmName || dirName;
|
|
@@ -4897,7 +5048,7 @@ function readSkill(skillMd, source) {
|
|
|
4897
5048
|
}
|
|
4898
5049
|
}
|
|
4899
5050
|
function scanSkillsDir(dir, source, out) {
|
|
4900
|
-
if (!
|
|
5051
|
+
if (!existsSync13(dir)) return;
|
|
4901
5052
|
let entries;
|
|
4902
5053
|
try {
|
|
4903
5054
|
entries = readdirSync4(dir);
|
|
@@ -4906,8 +5057,8 @@ function scanSkillsDir(dir, source, out) {
|
|
|
4906
5057
|
}
|
|
4907
5058
|
for (const entry of entries) {
|
|
4908
5059
|
if (entry.startsWith(".")) continue;
|
|
4909
|
-
const skillMd =
|
|
4910
|
-
if (!
|
|
5060
|
+
const skillMd = join12(dir, entry, "SKILL.md");
|
|
5061
|
+
if (!existsSync13(skillMd)) continue;
|
|
4911
5062
|
try {
|
|
4912
5063
|
if (!statSync3(skillMd).isFile()) continue;
|
|
4913
5064
|
} catch {
|
|
@@ -4918,7 +5069,7 @@ function scanSkillsDir(dir, source, out) {
|
|
|
4918
5069
|
}
|
|
4919
5070
|
}
|
|
4920
5071
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
4921
|
-
if (!
|
|
5072
|
+
if (!existsSync13(pluginsRoot)) return;
|
|
4922
5073
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
4923
5074
|
if (depth > 7) return;
|
|
4924
5075
|
let entries;
|
|
@@ -4928,12 +5079,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
|
|
|
4928
5079
|
return;
|
|
4929
5080
|
}
|
|
4930
5081
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
4931
|
-
const skill = readSkill(
|
|
5082
|
+
const skill = readSkill(join12(dir, "SKILL.md"), "cli");
|
|
4932
5083
|
if (skill) out.push(skill);
|
|
4933
5084
|
}
|
|
4934
5085
|
for (const entry of entries) {
|
|
4935
5086
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
4936
|
-
const full =
|
|
5087
|
+
const full = join12(dir, entry);
|
|
4937
5088
|
try {
|
|
4938
5089
|
if (!statSync3(full).isDirectory()) continue;
|
|
4939
5090
|
} catch {
|
|
@@ -4953,17 +5104,17 @@ function discoverSkills(worktreePath) {
|
|
|
4953
5104
|
const home = homedir();
|
|
4954
5105
|
const collected = [];
|
|
4955
5106
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
4956
|
-
scanSkillsDir(
|
|
5107
|
+
scanSkillsDir(join12(worktreePath, rel), "workspace", collected);
|
|
4957
5108
|
}
|
|
4958
5109
|
for (const abs of [
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
5110
|
+
join12(home, ".claude/skills"),
|
|
5111
|
+
join12(home, ".cursor/skills"),
|
|
5112
|
+
join12(home, ".sideboard/skills"),
|
|
5113
|
+
join12(home, ".brightsy/skills")
|
|
4963
5114
|
]) {
|
|
4964
5115
|
scanSkillsDir(abs, "user", collected);
|
|
4965
5116
|
}
|
|
4966
|
-
scanClaudePluginSkills(
|
|
5117
|
+
scanClaudePluginSkills(join12(home, ".claude/plugins"), collected);
|
|
4967
5118
|
collected.push(...bundledSkills());
|
|
4968
5119
|
const rank = {
|
|
4969
5120
|
workspace: 0,
|
|
@@ -4989,7 +5140,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
4989
5140
|
\u2026(truncated)` : body;
|
|
4990
5141
|
}
|
|
4991
5142
|
}
|
|
4992
|
-
const raw =
|
|
5143
|
+
const raw = readFileSync10(skillPath, "utf8");
|
|
4993
5144
|
if (raw.startsWith("---")) {
|
|
4994
5145
|
const end = raw.indexOf("\n---", 3);
|
|
4995
5146
|
if (end >= 0) {
|
|
@@ -5082,26 +5233,26 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
|
|
|
5082
5233
|
}
|
|
5083
5234
|
|
|
5084
5235
|
// src/agents/instructions.ts
|
|
5085
|
-
import { existsSync as
|
|
5086
|
-
import { join as
|
|
5236
|
+
import { existsSync as existsSync15, readFileSync as readFileSync11, statSync as statSync4 } from "fs";
|
|
5237
|
+
import { join as join14 } from "path";
|
|
5087
5238
|
|
|
5088
5239
|
// src/skills/detached-job-path.ts
|
|
5089
|
-
import { existsSync as
|
|
5090
|
-
import { dirname as dirname4, join as
|
|
5240
|
+
import { existsSync as existsSync14 } from "fs";
|
|
5241
|
+
import { dirname as dirname4, join as join13 } from "path";
|
|
5091
5242
|
import { fileURLToPath } from "url";
|
|
5092
5243
|
function packagedDetachedJobPath() {
|
|
5093
5244
|
const dir = packagedMcpDir();
|
|
5094
5245
|
if (!dir) return null;
|
|
5095
|
-
const script =
|
|
5096
|
-
return
|
|
5246
|
+
const script = join13(dir, "scripts", "detached-job.js");
|
|
5247
|
+
return existsSync14(script) ? script : null;
|
|
5097
5248
|
}
|
|
5098
5249
|
function resolveDetachedJobScript() {
|
|
5099
5250
|
const packaged = packagedDetachedJobPath();
|
|
5100
5251
|
if (packaged) return packaged;
|
|
5101
5252
|
let dir = dirname4(fileURLToPath(import.meta.url));
|
|
5102
5253
|
for (let i = 0; i < 8; i++) {
|
|
5103
|
-
const candidate =
|
|
5104
|
-
if (
|
|
5254
|
+
const candidate = join13(dir, "scripts", "detached-job.js");
|
|
5255
|
+
if (existsSync14(candidate)) return candidate;
|
|
5105
5256
|
const parent = dirname4(dir);
|
|
5106
5257
|
if (parent === dir) break;
|
|
5107
5258
|
dir = parent;
|
|
@@ -5403,8 +5554,8 @@ async function syncThreadBranchFromGit(threadId) {
|
|
|
5403
5554
|
|
|
5404
5555
|
// src/store/schedules.ts
|
|
5405
5556
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
5406
|
-
import { existsSync as
|
|
5407
|
-
import { join as
|
|
5557
|
+
import { existsSync as existsSync16, readFileSync as readFileSync12 } from "fs";
|
|
5558
|
+
import { join as join15 } from "path";
|
|
5408
5559
|
import { Cron } from "croner";
|
|
5409
5560
|
var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
|
|
5410
5561
|
var UNIT_MS = {
|
|
@@ -5414,7 +5565,7 @@ var UNIT_MS = {
|
|
|
5414
5565
|
d: 864e5
|
|
5415
5566
|
};
|
|
5416
5567
|
function schedulesPath() {
|
|
5417
|
-
return
|
|
5568
|
+
return join15(appDataDir(), "schedules.json");
|
|
5418
5569
|
}
|
|
5419
5570
|
function parseDurationMs(every) {
|
|
5420
5571
|
const m = every.trim().match(DURATION_RE);
|
|
@@ -5514,9 +5665,9 @@ function normalizeTask(raw) {
|
|
|
5514
5665
|
}
|
|
5515
5666
|
function readAll() {
|
|
5516
5667
|
const path = schedulesPath();
|
|
5517
|
-
if (!
|
|
5668
|
+
if (!existsSync16(path)) return [];
|
|
5518
5669
|
try {
|
|
5519
|
-
const parsed = JSON.parse(
|
|
5670
|
+
const parsed = JSON.parse(readFileSync12(path, "utf8"));
|
|
5520
5671
|
if (!Array.isArray(parsed)) return [];
|
|
5521
5672
|
return parsed.map((row) => {
|
|
5522
5673
|
try {
|
|
@@ -5639,7 +5790,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
5639
5790
|
${prompt}`;
|
|
5640
5791
|
}
|
|
5641
5792
|
async function defaultDeps() {
|
|
5642
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
5793
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-3FWEKDAQ.js");
|
|
5643
5794
|
const orch = getOrchestrator2();
|
|
5644
5795
|
return {
|
|
5645
5796
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -5879,7 +6030,7 @@ var Orchestrator = class {
|
|
|
5879
6030
|
}
|
|
5880
6031
|
continue;
|
|
5881
6032
|
}
|
|
5882
|
-
if (!
|
|
6033
|
+
if (!existsSync17(thread.worktreePath)) {
|
|
5883
6034
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
5884
6035
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
5885
6036
|
continue;
|
|
@@ -5898,7 +6049,7 @@ var Orchestrator = class {
|
|
|
5898
6049
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
5899
6050
|
});
|
|
5900
6051
|
}
|
|
5901
|
-
const { autoCleanupOrphansEnabled } = await import("./app-settings-
|
|
6052
|
+
const { autoCleanupOrphansEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
5902
6053
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
5903
6054
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
5904
6055
|
}
|
|
@@ -6138,7 +6289,7 @@ var Orchestrator = class {
|
|
|
6138
6289
|
}
|
|
6139
6290
|
await setup;
|
|
6140
6291
|
if (skipSetup) return;
|
|
6141
|
-
const { autoRunAfterSetupEnabled } = await import("./app-settings-
|
|
6292
|
+
const { autoRunAfterSetupEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
6142
6293
|
if (autoRunAfterSetupEnabled()) {
|
|
6143
6294
|
try {
|
|
6144
6295
|
await this.startDev(threadId);
|
|
@@ -6149,21 +6300,11 @@ var Orchestrator = class {
|
|
|
6149
6300
|
/** Run workspace setup after a new worktree is created (no-op if none configured). */
|
|
6150
6301
|
async runSetupAfterCreate(threadId) {
|
|
6151
6302
|
try {
|
|
6152
|
-
await this.runSetup(threadId);
|
|
6303
|
+
await this.runSetup(threadId, { stampLastError: false });
|
|
6153
6304
|
} catch (err) {
|
|
6154
6305
|
const message = err instanceof Error ? err.message : String(err);
|
|
6155
6306
|
if (/no setup script/i.test(message)) return;
|
|
6156
6307
|
if (/already running/i.test(message)) return;
|
|
6157
|
-
const live = readThread(threadId);
|
|
6158
|
-
if (!shouldStampSetupLastError({
|
|
6159
|
-
turnInFlight: this.activeTurns.has(threadId) || this.startingTurns.has(threadId),
|
|
6160
|
-
status: live?.status
|
|
6161
|
-
})) {
|
|
6162
|
-
return;
|
|
6163
|
-
}
|
|
6164
|
-
updateThread(threadId, {
|
|
6165
|
-
lastError: `Setup failed: ${message}`
|
|
6166
|
-
});
|
|
6167
6308
|
}
|
|
6168
6309
|
}
|
|
6169
6310
|
listWorkspaces() {
|
|
@@ -6446,7 +6587,7 @@ var Orchestrator = class {
|
|
|
6446
6587
|
}
|
|
6447
6588
|
const isBrightsy = fresh.agent === "brightsy";
|
|
6448
6589
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
6449
|
-
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-
|
|
6590
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-VRQI3FIE.js");
|
|
6450
6591
|
const gitAuthMode = getGithubGitAuthMode();
|
|
6451
6592
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
6452
6593
|
githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
|
|
@@ -6552,7 +6693,7 @@ var Orchestrator = class {
|
|
|
6552
6693
|
if (!this.stoppedTurns.has(threadId) && this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
|
|
6553
6694
|
const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
|
|
6554
6695
|
if (sessionId) {
|
|
6555
|
-
const { recoverFinishedCursorRun } = await import("./cursor-recover-
|
|
6696
|
+
const { recoverFinishedCursorRun } = await import("./cursor-recover-L5MD6MBO.js");
|
|
6556
6697
|
for (let i = 0; i < 8; i++) {
|
|
6557
6698
|
const recovered = recoverFinishedCursorRun({
|
|
6558
6699
|
agentId: sessionId,
|
|
@@ -6942,7 +7083,16 @@ var Orchestrator = class {
|
|
|
6942
7083
|
getActiveRuns(threadRef) {
|
|
6943
7084
|
return this.requireThread(threadRef).activeRuns ?? [];
|
|
6944
7085
|
}
|
|
6945
|
-
|
|
7086
|
+
getSetupLog(threadRef) {
|
|
7087
|
+
const thread = this.getThread(threadRef);
|
|
7088
|
+
if (!thread) return readSetupLog(threadRef);
|
|
7089
|
+
const snap = readSetupLog(thread.id);
|
|
7090
|
+
if (snap.running && !this.processes.has(`${thread.id}:setup`)) {
|
|
7091
|
+
return { ...snap, running: false };
|
|
7092
|
+
}
|
|
7093
|
+
return snap;
|
|
7094
|
+
}
|
|
7095
|
+
async runSetup(threadRef, opts) {
|
|
6946
7096
|
const thread = this.requireThread(threadRef);
|
|
6947
7097
|
this.assertNotGlobal(thread, "Setup");
|
|
6948
7098
|
const key = `${thread.id}:setup`;
|
|
@@ -6955,34 +7105,49 @@ var Orchestrator = class {
|
|
|
6955
7105
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6956
7106
|
kill: () => abort.abort()
|
|
6957
7107
|
});
|
|
7108
|
+
beginSetupLog(thread.id);
|
|
6958
7109
|
this.emit({ type: "setup_started", threadId: thread.id });
|
|
7110
|
+
let finished = false;
|
|
7111
|
+
const finish = (exitCode, source) => {
|
|
7112
|
+
if (finished) return;
|
|
7113
|
+
finished = true;
|
|
7114
|
+
finishSetupLog(thread.id, exitCode, source);
|
|
7115
|
+
this.emit({ type: "setup_finished", threadId: thread.id, exitCode });
|
|
7116
|
+
};
|
|
6959
7117
|
try {
|
|
6960
7118
|
const setup = await runWorkspaceSetup(
|
|
6961
7119
|
thread.repoPath,
|
|
6962
7120
|
thread.worktreePath,
|
|
6963
7121
|
(line) => {
|
|
7122
|
+
appendSetupLog(thread.id, line);
|
|
6964
7123
|
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
6965
7124
|
},
|
|
6966
7125
|
{ signal: abort.signal }
|
|
6967
7126
|
);
|
|
6968
7127
|
if (!setup.ran) {
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
);
|
|
7128
|
+
const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
|
|
7129
|
+
appendSetupLog(thread.id, line);
|
|
7130
|
+
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
7131
|
+
finish(null, null);
|
|
7132
|
+
throw new Error(line);
|
|
6972
7133
|
}
|
|
6973
7134
|
if (setup.exitCode !== 0 && setup.exitCode !== null) {
|
|
6974
7135
|
const live = readThread(thread.id);
|
|
6975
|
-
if (shouldStampSetupLastError({
|
|
7136
|
+
if ((opts?.stampLastError ?? true) && shouldStampSetupLastError({
|
|
6976
7137
|
turnInFlight: this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id),
|
|
6977
|
-
status: live?.status
|
|
7138
|
+
status: live?.status,
|
|
7139
|
+
hasQueuedPrompt: Boolean(live?.queue?.length)
|
|
6978
7140
|
})) {
|
|
6979
7141
|
updateThread(thread.id, {
|
|
6980
7142
|
lastError: `Setup exited ${setup.exitCode}`
|
|
6981
7143
|
});
|
|
6982
7144
|
}
|
|
6983
7145
|
}
|
|
6984
|
-
|
|
7146
|
+
finish(setup.exitCode, setup.source);
|
|
6985
7147
|
return { exitCode: setup.exitCode, source: setup.source };
|
|
7148
|
+
} catch (err) {
|
|
7149
|
+
finish(null, null);
|
|
7150
|
+
throw err;
|
|
6986
7151
|
} finally {
|
|
6987
7152
|
this.processes.delete(key);
|
|
6988
7153
|
}
|
|
@@ -7309,7 +7474,7 @@ var Orchestrator = class {
|
|
|
7309
7474
|
updateThread(thread.id, { title: meta.title });
|
|
7310
7475
|
}
|
|
7311
7476
|
}
|
|
7312
|
-
const { autoArchiveOnMergeEnabled } = await import("./app-settings-
|
|
7477
|
+
const { autoArchiveOnMergeEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
7313
7478
|
const latest = this.requireThread(thread.id);
|
|
7314
7479
|
if (!shouldAutoArchiveOnPrMerge({
|
|
7315
7480
|
previousPrState: prevState || null,
|
|
@@ -7626,7 +7791,7 @@ var Orchestrator = class {
|
|
|
7626
7791
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
7627
7792
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
7628
7793
|
try {
|
|
7629
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
7794
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-MQYNZXUK.js");
|
|
7630
7795
|
await ensureWorkspace2(thread.repoPath);
|
|
7631
7796
|
} catch {
|
|
7632
7797
|
}
|
|
@@ -7653,7 +7818,7 @@ var Orchestrator = class {
|
|
|
7653
7818
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
7654
7819
|
} catch {
|
|
7655
7820
|
}
|
|
7656
|
-
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-
|
|
7821
|
+
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
7657
7822
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
7658
7823
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
7659
7824
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -7668,19 +7833,19 @@ var Orchestrator = class {
|
|
|
7668
7833
|
throw new Error("Thread is not archived");
|
|
7669
7834
|
}
|
|
7670
7835
|
if (isGlobalThread(thread)) {
|
|
7671
|
-
const { globalAgentCwd } = await import("./paths-
|
|
7836
|
+
const { globalAgentCwd } = await import("./paths-RRCLNSJB.js");
|
|
7672
7837
|
updateThread(thread.id, { worktreePath: globalAgentCwd() });
|
|
7673
7838
|
const restored2 = setStatus(thread.id, "idle");
|
|
7674
7839
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
7675
7840
|
return restored2;
|
|
7676
7841
|
}
|
|
7677
|
-
if (!
|
|
7842
|
+
if (!existsSync17(thread.worktreePath)) {
|
|
7678
7843
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
7679
7844
|
throw new Error(
|
|
7680
7845
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
7681
7846
|
);
|
|
7682
7847
|
}
|
|
7683
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
7848
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-PEWDAX5O.js");
|
|
7684
7849
|
const slug = thread.worktreePath.split("/").pop();
|
|
7685
7850
|
const dest = thread.worktreePath;
|
|
7686
7851
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -7790,7 +7955,7 @@ async function startOrchestration(opts) {
|
|
|
7790
7955
|
sourceRef: "default",
|
|
7791
7956
|
...createOpts
|
|
7792
7957
|
}).catch(async () => {
|
|
7793
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
7958
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-PEWDAX5O.js");
|
|
7794
7959
|
const repo = await resolveRepoRoot2(repoPath);
|
|
7795
7960
|
const def = await resolveDefaultBranch2(repo);
|
|
7796
7961
|
return orch.createThread({
|
|
@@ -7800,7 +7965,7 @@ async function startOrchestration(opts) {
|
|
|
7800
7965
|
repoPath: repo
|
|
7801
7966
|
});
|
|
7802
7967
|
});
|
|
7803
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
7968
|
+
const { updateThread: upd } = await import("./thread-store-MVQU6HPJ.js");
|
|
7804
7969
|
const updated = upd(thread.id, {
|
|
7805
7970
|
sourceType: "orchestration",
|
|
7806
7971
|
sourceRef: goal
|
|
@@ -7833,7 +7998,6 @@ export {
|
|
|
7833
7998
|
findBoardPr,
|
|
7834
7999
|
assembleHomeBoard,
|
|
7835
8000
|
HOME_BOARD_AGENT_HINT,
|
|
7836
|
-
listLinearIssues,
|
|
7837
8001
|
readTurnLive,
|
|
7838
8002
|
resolveScheduleThreadId,
|
|
7839
8003
|
listSchedules,
|