@sideboard-ai/core 0.1.152 → 0.1.153
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-7BQNSUR2.js → chunk-2NRNP7QP.js} +357 -185
- package/dist/{chunk-4XNSGDXE.js → chunk-3BWVOUQG.js} +244 -1
- 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-WLV7TRMR.js → chunk-JOK4XWBG.js} +1 -1
- package/dist/{chunk-BD2ICC4D.js → chunk-JTJHOYCU.js} +1 -1
- package/dist/{chunk-6X7Z34XE.js → chunk-KMNODRWF.js} +397 -173
- 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 +1875 -765
- package/dist/index.d.cts +195 -11
- package/dist/index.d.ts +195 -11
- package/dist/index.js +298 -108
- package/dist/mcp/run-stdio.cjs +1743 -1228
- package/dist/mcp/run-stdio.js +232 -80
- package/dist/{orchestrator-NUA6SEV7.js → orchestrator-5PSHBLP6.js} +10 -12
- package/dist/{orchestrator-256DFPSX.js → orchestrator-ZSSU3FKW.js} +9 -11
- 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
|
@@ -24,18 +24,19 @@ import {
|
|
|
24
24
|
stripBrightsyNdjsonNoise,
|
|
25
25
|
sumUsageList,
|
|
26
26
|
toolDescription
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-QZEZXYVV.js";
|
|
28
28
|
import {
|
|
29
|
+
SLACK_REPLY_FORMATTING,
|
|
29
30
|
addWorkspace,
|
|
30
|
-
ensureWorkspace,
|
|
31
|
-
removeWorkspace,
|
|
32
|
-
syncWorkspacesFromThreads
|
|
33
|
-
} from "./chunk-K2ANSHUO.js";
|
|
34
|
-
import {
|
|
35
31
|
assertOrchestratorCapableAgent,
|
|
36
32
|
attachmentsFromWorktreePaths,
|
|
37
33
|
coerceOrchestratorAgent,
|
|
34
|
+
coordinatorSystemPrompt,
|
|
35
|
+
coordinatorTurnReminder,
|
|
38
36
|
createGlobalChat,
|
|
37
|
+
enrichWorkspacesWithGithub,
|
|
38
|
+
ensureGlobalCoordinatorCwd,
|
|
39
|
+
ensureWorkspace,
|
|
39
40
|
healOrchestrationSoccerTitles,
|
|
40
41
|
isCloudCoordinatorThread,
|
|
41
42
|
isGlobalRepoPath,
|
|
@@ -45,16 +46,11 @@ import {
|
|
|
45
46
|
isSlackCoordinatorThread,
|
|
46
47
|
orchestratorSessionPoisonedByBuiltins,
|
|
47
48
|
persistPendingFileAttachments,
|
|
49
|
+
removeWorkspace,
|
|
48
50
|
stageAbsolutePathsAsAttachments,
|
|
49
|
-
stageBuffersAsAttachments
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
SLACK_REPLY_FORMATTING,
|
|
53
|
-
coordinatorSystemPrompt,
|
|
54
|
-
coordinatorTurnReminder,
|
|
55
|
-
enrichWorkspacesWithGithub,
|
|
56
|
-
ensureGlobalCoordinatorCwd
|
|
57
|
-
} from "./chunk-2U6QF3PT.js";
|
|
51
|
+
stageBuffersAsAttachments,
|
|
52
|
+
syncWorkspacesFromThreads
|
|
53
|
+
} from "./chunk-2F63IMCL.js";
|
|
58
54
|
import {
|
|
59
55
|
addPrStackLayer,
|
|
60
56
|
allocateTeamName,
|
|
@@ -102,7 +98,7 @@ import {
|
|
|
102
98
|
withRepoGitLock,
|
|
103
99
|
worktreeDisplayLabelForGroup,
|
|
104
100
|
worktreeNameFromPath
|
|
105
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-LQMFCS54.js";
|
|
106
102
|
import {
|
|
107
103
|
ATTACHMENTS_DIR,
|
|
108
104
|
LEGACY_ATTACHMENTS_DIR
|
|
@@ -143,13 +139,13 @@ import {
|
|
|
143
139
|
saveAppSettings,
|
|
144
140
|
updateAdvancedSettings,
|
|
145
141
|
writeSecureJson
|
|
146
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-3BWVOUQG.js";
|
|
147
143
|
import {
|
|
148
144
|
stripNestedElectronEnv
|
|
149
145
|
} from "./chunk-4TR3HZFT.js";
|
|
150
146
|
import {
|
|
151
147
|
releaseCaffeinateHoldForThread
|
|
152
|
-
} from "./chunk-
|
|
148
|
+
} from "./chunk-AO35MGOE.js";
|
|
153
149
|
import {
|
|
154
150
|
writePrivateFile
|
|
155
151
|
} from "./chunk-JT7R45JB.js";
|
|
@@ -164,7 +160,7 @@ import {
|
|
|
164
160
|
updateThread,
|
|
165
161
|
withThreadLock,
|
|
166
162
|
writeThread
|
|
167
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-7UURXPKD.js";
|
|
168
164
|
import {
|
|
169
165
|
appDataDir,
|
|
170
166
|
findConventionSetup,
|
|
@@ -174,9 +170,10 @@ import {
|
|
|
174
170
|
sideboardReposDir,
|
|
175
171
|
sideboardWorkspacesDir,
|
|
176
172
|
threadLivePath,
|
|
173
|
+
threadsDir,
|
|
177
174
|
workspaceSettingsSourceLabel,
|
|
178
175
|
worktreesRoot
|
|
179
|
-
} from "./chunk-
|
|
176
|
+
} from "./chunk-EFVFB2AH.js";
|
|
180
177
|
import {
|
|
181
178
|
ensureWorktreeSideboardIgnored
|
|
182
179
|
} from "./chunk-QQKDGPUI.js";
|
|
@@ -460,7 +457,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
460
457
|
await continueOnReply(threadId, prompt);
|
|
461
458
|
return;
|
|
462
459
|
}
|
|
463
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
460
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-5PSHBLP6.js");
|
|
464
461
|
await getOrchestrator2().send(threadId, prompt);
|
|
465
462
|
} catch {
|
|
466
463
|
}
|
|
@@ -720,7 +717,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
720
717
|
}
|
|
721
718
|
|
|
722
719
|
// src/orchestrator/orchestrator.ts
|
|
723
|
-
import { existsSync as
|
|
720
|
+
import { existsSync as existsSync17 } from "fs";
|
|
724
721
|
|
|
725
722
|
// src/agents/spawn.ts
|
|
726
723
|
import { createInterface } from "readline";
|
|
@@ -740,9 +737,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
740
737
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
741
738
|
);
|
|
742
739
|
}
|
|
743
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
740
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-2BRRKSDN.js");
|
|
744
741
|
if (isGlobalThread2(thread)) {
|
|
745
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
742
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-7FHKCWXB.js");
|
|
746
743
|
ensureGlobalCoordinatorCwd2(
|
|
747
744
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
748
745
|
);
|
|
@@ -1997,6 +1994,8 @@ async function attachAbort(handle, signal) {
|
|
|
1997
1994
|
async function runSetupScript(repoPath, worktreePath, onLine, opts) {
|
|
1998
1995
|
const settings = loadWorkspaceSettings(worktreePath, repoPath);
|
|
1999
1996
|
if (!settings?.setup) return { ran: false, exitCode: null, source: null };
|
|
1997
|
+
const source = workspaceSettingsSourceLabel(worktreePath, repoPath);
|
|
1998
|
+
onLine?.(`[setup] ${source ?? "settings.toml"}`);
|
|
2000
1999
|
const handle = await spawnWorkspaceScript(settings.setup, {
|
|
2001
2000
|
worktreePath,
|
|
2002
2001
|
repoPath,
|
|
@@ -2007,7 +2006,7 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
|
|
|
2007
2006
|
return {
|
|
2008
2007
|
ran: true,
|
|
2009
2008
|
exitCode,
|
|
2010
|
-
source
|
|
2009
|
+
source,
|
|
2011
2010
|
kill: handle.kill
|
|
2012
2011
|
};
|
|
2013
2012
|
}
|
|
@@ -2136,9 +2135,122 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
2136
2135
|
};
|
|
2137
2136
|
}
|
|
2138
2137
|
|
|
2139
|
-
// src/
|
|
2140
|
-
import { existsSync as existsSync5,
|
|
2138
|
+
// src/store/setup-log.ts
|
|
2139
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
2141
2140
|
import { join as join6 } from "path";
|
|
2141
|
+
var EMPTY = {
|
|
2142
|
+
output: "",
|
|
2143
|
+
running: false,
|
|
2144
|
+
exitCode: null,
|
|
2145
|
+
source: null
|
|
2146
|
+
};
|
|
2147
|
+
var memory = /* @__PURE__ */ new Map();
|
|
2148
|
+
var persistTimers = /* @__PURE__ */ new Map();
|
|
2149
|
+
function setupLogPath(threadId) {
|
|
2150
|
+
return join6(threadsDir(), `${threadId}.setup.log.json`);
|
|
2151
|
+
}
|
|
2152
|
+
function emptySetupLog() {
|
|
2153
|
+
return { ...EMPTY };
|
|
2154
|
+
}
|
|
2155
|
+
function mergeSetupOutput(prev, incoming) {
|
|
2156
|
+
if (!prev) return incoming;
|
|
2157
|
+
if (!incoming) return prev;
|
|
2158
|
+
if (prev === incoming) return prev;
|
|
2159
|
+
if (prev.startsWith(incoming) || prev.endsWith(incoming)) return prev;
|
|
2160
|
+
if (incoming.startsWith(prev) || incoming.endsWith(prev)) return incoming;
|
|
2161
|
+
return incoming.length >= prev.length ? incoming : prev;
|
|
2162
|
+
}
|
|
2163
|
+
function clone(snap) {
|
|
2164
|
+
return { ...snap };
|
|
2165
|
+
}
|
|
2166
|
+
function persistNow(threadId) {
|
|
2167
|
+
const timer = persistTimers.get(threadId);
|
|
2168
|
+
if (timer) {
|
|
2169
|
+
clearTimeout(timer);
|
|
2170
|
+
persistTimers.delete(threadId);
|
|
2171
|
+
}
|
|
2172
|
+
const snap = memory.get(threadId);
|
|
2173
|
+
if (!snap) return;
|
|
2174
|
+
try {
|
|
2175
|
+
writeFileSync2(setupLogPath(threadId), `${JSON.stringify(snap)}
|
|
2176
|
+
`, "utf8");
|
|
2177
|
+
} catch {
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
function schedulePersist(threadId) {
|
|
2181
|
+
if (persistTimers.has(threadId)) return;
|
|
2182
|
+
persistTimers.set(
|
|
2183
|
+
threadId,
|
|
2184
|
+
setTimeout(() => {
|
|
2185
|
+
persistTimers.delete(threadId);
|
|
2186
|
+
persistNow(threadId);
|
|
2187
|
+
}, 100)
|
|
2188
|
+
);
|
|
2189
|
+
}
|
|
2190
|
+
function loadFromDisk(threadId) {
|
|
2191
|
+
const path = setupLogPath(threadId);
|
|
2192
|
+
if (!existsSync5(path)) return null;
|
|
2193
|
+
try {
|
|
2194
|
+
const raw = JSON.parse(readFileSync5(path, "utf8"));
|
|
2195
|
+
return {
|
|
2196
|
+
output: typeof raw.output === "string" ? raw.output : "",
|
|
2197
|
+
running: Boolean(raw.running),
|
|
2198
|
+
exitCode: typeof raw.exitCode === "number" ? raw.exitCode : null,
|
|
2199
|
+
source: typeof raw.source === "string" ? raw.source : null
|
|
2200
|
+
};
|
|
2201
|
+
} catch {
|
|
2202
|
+
return null;
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
function readSetupLog(threadId) {
|
|
2206
|
+
const cached = memory.get(threadId);
|
|
2207
|
+
if (cached) return clone(cached);
|
|
2208
|
+
const disk = loadFromDisk(threadId);
|
|
2209
|
+
if (disk) {
|
|
2210
|
+
memory.set(threadId, disk);
|
|
2211
|
+
return clone(disk);
|
|
2212
|
+
}
|
|
2213
|
+
return emptySetupLog();
|
|
2214
|
+
}
|
|
2215
|
+
function beginSetupLog(threadId) {
|
|
2216
|
+
const snap = {
|
|
2217
|
+
output: "",
|
|
2218
|
+
running: true,
|
|
2219
|
+
exitCode: null,
|
|
2220
|
+
source: null
|
|
2221
|
+
};
|
|
2222
|
+
memory.set(threadId, snap);
|
|
2223
|
+
persistNow(threadId);
|
|
2224
|
+
return clone(snap);
|
|
2225
|
+
}
|
|
2226
|
+
function appendSetupLog(threadId, line) {
|
|
2227
|
+
const current = memory.get(threadId) ?? readSetupLog(threadId);
|
|
2228
|
+
const snap = {
|
|
2229
|
+
...current,
|
|
2230
|
+
output: current.output ? `${current.output}
|
|
2231
|
+
${line}` : line,
|
|
2232
|
+
running: true
|
|
2233
|
+
};
|
|
2234
|
+
memory.set(threadId, snap);
|
|
2235
|
+
schedulePersist(threadId);
|
|
2236
|
+
return clone(snap);
|
|
2237
|
+
}
|
|
2238
|
+
function finishSetupLog(threadId, exitCode, source) {
|
|
2239
|
+
const current = memory.get(threadId) ?? readSetupLog(threadId);
|
|
2240
|
+
const snap = {
|
|
2241
|
+
...current,
|
|
2242
|
+
running: false,
|
|
2243
|
+
exitCode,
|
|
2244
|
+
source: source ?? current.source
|
|
2245
|
+
};
|
|
2246
|
+
memory.set(threadId, snap);
|
|
2247
|
+
persistNow(threadId);
|
|
2248
|
+
return clone(snap);
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2251
|
+
// src/git/orphan-cleanup.ts
|
|
2252
|
+
import { existsSync as existsSync6, readdirSync as readdirSync2, statSync } from "fs";
|
|
2253
|
+
import { join as join7 } from "path";
|
|
2142
2254
|
function isSideboardWorktreePath(path) {
|
|
2143
2255
|
return path.includes("/.sideboard/worktrees/") || path.includes("/sideboard/workspaces/");
|
|
2144
2256
|
}
|
|
@@ -2149,7 +2261,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
2149
2261
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
2150
2262
|
);
|
|
2151
2263
|
const homeRoot = sideboardWorkspacesDir();
|
|
2152
|
-
if (
|
|
2264
|
+
if (existsSync6(homeRoot)) {
|
|
2153
2265
|
try {
|
|
2154
2266
|
for (const entry of readdirSync2(homeRoot, { withFileTypes: true })) {
|
|
2155
2267
|
if (!entry.isDirectory()) continue;
|
|
@@ -2161,7 +2273,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
2161
2273
|
const orphans = [];
|
|
2162
2274
|
const seen = /* @__PURE__ */ new Set();
|
|
2163
2275
|
for (const repoPath of repos) {
|
|
2164
|
-
if (!repoPath || !
|
|
2276
|
+
if (!repoPath || !existsSync6(repoPath)) continue;
|
|
2165
2277
|
try {
|
|
2166
2278
|
const wts = await listWorktrees(repoPath);
|
|
2167
2279
|
for (const wt of wts) {
|
|
@@ -2182,12 +2294,12 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
2182
2294
|
}
|
|
2183
2295
|
try {
|
|
2184
2296
|
const root = worktreesRoot(repoPath);
|
|
2185
|
-
if (
|
|
2297
|
+
if (existsSync6(root)) {
|
|
2186
2298
|
for (const entry of readdirSync2(root, { withFileTypes: true })) {
|
|
2187
2299
|
if (!entry.isDirectory()) continue;
|
|
2188
|
-
const path =
|
|
2300
|
+
const path = join7(root, entry.name).replace(/\/$/, "");
|
|
2189
2301
|
if (known.has(path) || seen.has(path)) continue;
|
|
2190
|
-
if (!
|
|
2302
|
+
if (!existsSync6(join7(path, ".git"))) continue;
|
|
2191
2303
|
seen.add(path);
|
|
2192
2304
|
let mtimeMs = 0;
|
|
2193
2305
|
try {
|
|
@@ -2336,8 +2448,8 @@ async function applyThreadIntoMain(thread, opts) {
|
|
|
2336
2448
|
}
|
|
2337
2449
|
|
|
2338
2450
|
// src/git/clone-repo.ts
|
|
2339
|
-
import { existsSync as
|
|
2340
|
-
import { basename as basename2, join as
|
|
2451
|
+
import { existsSync as existsSync7 } from "fs";
|
|
2452
|
+
import { basename as basename2, join as join8 } from "path";
|
|
2341
2453
|
import { execa as execa4 } from "execa";
|
|
2342
2454
|
async function cloneRepoIntoSideboard(opts) {
|
|
2343
2455
|
const url = opts.url.trim();
|
|
@@ -2348,8 +2460,8 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
2348
2460
|
name = leaf || "repo";
|
|
2349
2461
|
}
|
|
2350
2462
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
2351
|
-
const dest =
|
|
2352
|
-
if (
|
|
2463
|
+
const dest = join8(sideboardReposDir(), name);
|
|
2464
|
+
if (existsSync7(dest)) {
|
|
2353
2465
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
2354
2466
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
2355
2467
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -2366,13 +2478,13 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
2366
2478
|
}
|
|
2367
2479
|
|
|
2368
2480
|
// src/store/desktop-host.ts
|
|
2369
|
-
import { readFileSync as
|
|
2370
|
-
import { join as
|
|
2481
|
+
import { readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
2482
|
+
import { join as join9 } from "path";
|
|
2371
2483
|
function desktopHostPidPath() {
|
|
2372
|
-
return
|
|
2484
|
+
return join9(appDataDir(), "desktop-host.pid");
|
|
2373
2485
|
}
|
|
2374
2486
|
function claimDesktopHost(pid = process.pid) {
|
|
2375
|
-
|
|
2487
|
+
writeFileSync3(desktopHostPidPath(), `${pid}
|
|
2376
2488
|
`, "utf8");
|
|
2377
2489
|
}
|
|
2378
2490
|
function releaseDesktopHost(pid = process.pid) {
|
|
@@ -2384,7 +2496,7 @@ function releaseDesktopHost(pid = process.pid) {
|
|
|
2384
2496
|
}
|
|
2385
2497
|
function readDesktopHostPid() {
|
|
2386
2498
|
try {
|
|
2387
|
-
const pid = Number.parseInt(
|
|
2499
|
+
const pid = Number.parseInt(readFileSync6(desktopHostPidPath(), "utf8").trim(), 10);
|
|
2388
2500
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
2389
2501
|
return pid;
|
|
2390
2502
|
} catch {
|
|
@@ -2451,7 +2563,7 @@ function notifyParentOfChildHalt(child, status, send) {
|
|
|
2451
2563
|
}
|
|
2452
2564
|
|
|
2453
2565
|
// src/threads/create.ts
|
|
2454
|
-
import { existsSync as
|
|
2566
|
+
import { existsSync as existsSync8 } from "fs";
|
|
2455
2567
|
|
|
2456
2568
|
// src/detect/detect.ts
|
|
2457
2569
|
async function detectAgents() {
|
|
@@ -2622,12 +2734,19 @@ function urlsMatch(a, b) {
|
|
|
2622
2734
|
const norm = (u) => u.trim().replace(/\/+$/, "").toLowerCase();
|
|
2623
2735
|
return Boolean(a && b && norm(a) === norm(b));
|
|
2624
2736
|
}
|
|
2737
|
+
function threadPrUrlMatchesNumber(thread, number) {
|
|
2738
|
+
if (!Number.isFinite(number) || number < 1) return false;
|
|
2739
|
+
const url = (thread.prUrl ?? "").trim();
|
|
2740
|
+
if (!url) return false;
|
|
2741
|
+
return new RegExp(`/pull/${number}(?:/|$|[?#])`, "i").test(url);
|
|
2742
|
+
}
|
|
2625
2743
|
function threadMatchesPr(thread, pr) {
|
|
2626
2744
|
const num = String(pr.number);
|
|
2627
2745
|
if (thread.sourceType === "pr" && normalizeIssueKey(thread.sourceRef ?? "") === num) {
|
|
2628
2746
|
return true;
|
|
2629
2747
|
}
|
|
2630
2748
|
if (thread.prUrl && pr.url && urlsMatch(thread.prUrl, pr.url)) return true;
|
|
2749
|
+
if (threadPrUrlMatchesNumber(thread, pr.number)) return true;
|
|
2631
2750
|
const head = pr.headRefName.trim().toLowerCase();
|
|
2632
2751
|
if (!head) return false;
|
|
2633
2752
|
const branch = (thread.branchName ?? "").trim().toLowerCase();
|
|
@@ -2680,22 +2799,65 @@ function findLiveThreadForCreate(input, threads) {
|
|
|
2680
2799
|
(t) => threadMatchesPr(t, {
|
|
2681
2800
|
number: Number.isFinite(number) ? number : -1,
|
|
2682
2801
|
title: input.title ?? "",
|
|
2683
|
-
url: "",
|
|
2684
|
-
headRefName: ""
|
|
2802
|
+
url: input.prUrl ?? "",
|
|
2803
|
+
headRefName: input.headRefName ?? ""
|
|
2685
2804
|
})
|
|
2686
2805
|
);
|
|
2687
2806
|
}
|
|
2688
2807
|
if (input.sourceType === "branch") {
|
|
2689
2808
|
if (isDefaultBranchCreateRef(input.sourceRef)) return void 0;
|
|
2690
|
-
|
|
2809
|
+
const byBranch = live.find(
|
|
2691
2810
|
(t) => threadMatchesBranch(t, {
|
|
2692
2811
|
ref: input.sourceRef,
|
|
2693
2812
|
repoPath: input.repoPath
|
|
2694
2813
|
})
|
|
2695
2814
|
);
|
|
2815
|
+
if (byBranch) return byBranch;
|
|
2816
|
+
if (input.prUrl || input.headRefName) {
|
|
2817
|
+
const number = Number(normalizeIssueKey(input.sourceRef));
|
|
2818
|
+
return live.find(
|
|
2819
|
+
(t) => threadMatchesPr(t, {
|
|
2820
|
+
number: Number.isFinite(number) ? number : -1,
|
|
2821
|
+
title: input.title ?? "",
|
|
2822
|
+
url: input.prUrl ?? "",
|
|
2823
|
+
headRefName: input.headRefName ?? input.sourceRef
|
|
2824
|
+
})
|
|
2825
|
+
);
|
|
2826
|
+
}
|
|
2827
|
+
return void 0;
|
|
2696
2828
|
}
|
|
2697
2829
|
return void 0;
|
|
2698
2830
|
}
|
|
2831
|
+
function findLiveThreadForCreateSource(source, threads, prs) {
|
|
2832
|
+
const found = findLiveThreadForCreate(
|
|
2833
|
+
{
|
|
2834
|
+
sourceType: source.kind,
|
|
2835
|
+
sourceRef: source.ref,
|
|
2836
|
+
repoPath: source.repoPath,
|
|
2837
|
+
title: source.title,
|
|
2838
|
+
prUrl: source.url,
|
|
2839
|
+
headRefName: source.headRefName
|
|
2840
|
+
},
|
|
2841
|
+
threads
|
|
2842
|
+
);
|
|
2843
|
+
if (found) return found;
|
|
2844
|
+
if (source.kind !== "branch" || !prs?.length) return void 0;
|
|
2845
|
+
if (isDefaultBranchCreateRef(source.ref)) return void 0;
|
|
2846
|
+
const head = normalizeBranchRef(source.ref);
|
|
2847
|
+
const pr = prs.find((p) => normalizeBranchRef(p.headRefName) === head);
|
|
2848
|
+
if (!pr) return void 0;
|
|
2849
|
+
return findLiveThreadForCreate(
|
|
2850
|
+
{
|
|
2851
|
+
sourceType: "pr",
|
|
2852
|
+
sourceRef: String(pr.number),
|
|
2853
|
+
repoPath: source.repoPath,
|
|
2854
|
+
title: pr.title,
|
|
2855
|
+
prUrl: pr.url,
|
|
2856
|
+
headRefName: pr.headRefName
|
|
2857
|
+
},
|
|
2858
|
+
threads
|
|
2859
|
+
);
|
|
2860
|
+
}
|
|
2699
2861
|
function boardPinIdentity(pin) {
|
|
2700
2862
|
const ref = normalizeIssueKey(pin.ref);
|
|
2701
2863
|
if (pin.kind === "ticket" && (pin.provider === "linear" || !pin.repoPath)) {
|
|
@@ -2925,42 +3087,53 @@ function assembleHomeBoard(input) {
|
|
|
2925
3087
|
}
|
|
2926
3088
|
return { columns, hidden, totals };
|
|
2927
3089
|
}
|
|
2928
|
-
var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards).
|
|
3090
|
+
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.";
|
|
2929
3091
|
|
|
2930
3092
|
// src/threads/create.ts
|
|
2931
3093
|
function persistCreateAttachments(worktreePath, attachments) {
|
|
2932
3094
|
return persistPendingFileAttachments(worktreePath, attachments ?? []);
|
|
2933
3095
|
}
|
|
3096
|
+
function liveThreadsForCreate() {
|
|
3097
|
+
return listThreads({ includeArchived: false }).map((t) => ({
|
|
3098
|
+
...t,
|
|
3099
|
+
repoPath: canonicalizeRepoPath(t.repoPath)
|
|
3100
|
+
}));
|
|
3101
|
+
}
|
|
3102
|
+
function reuseLiveThread(input, repoPath, match) {
|
|
3103
|
+
if (input.reuseExisting === false) return void 0;
|
|
3104
|
+
const existing = findLiveThreadForCreate(
|
|
3105
|
+
{
|
|
3106
|
+
sourceType: match.sourceType,
|
|
3107
|
+
sourceRef: match.sourceRef,
|
|
3108
|
+
repoPath,
|
|
3109
|
+
title: match.title ?? input.title,
|
|
3110
|
+
cowboy: input.cowboy,
|
|
3111
|
+
prUrl: match.prUrl,
|
|
3112
|
+
headRefName: match.headRefName
|
|
3113
|
+
},
|
|
3114
|
+
liveThreadsForCreate()
|
|
3115
|
+
);
|
|
3116
|
+
if (!existing) return void 0;
|
|
3117
|
+
const thread = readThread(existing.id) ?? existing;
|
|
3118
|
+
if (!input.attachments?.length) return thread;
|
|
3119
|
+
return updateThread(thread.id, {
|
|
3120
|
+
attachments: persistCreateAttachments(thread.worktreePath, [
|
|
3121
|
+
...thread.attachments,
|
|
3122
|
+
...input.attachments
|
|
3123
|
+
])
|
|
3124
|
+
});
|
|
3125
|
+
}
|
|
2934
3126
|
async function createThread(input, _onSetupLine) {
|
|
2935
3127
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
2936
|
-
if (!
|
|
3128
|
+
if (!existsSync8(repoPath)) {
|
|
2937
3129
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
2938
3130
|
}
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
title: input.title,
|
|
2946
|
-
cowboy: input.cowboy
|
|
2947
|
-
},
|
|
2948
|
-
listThreads({ includeArchived: false }).map((t) => ({
|
|
2949
|
-
...t,
|
|
2950
|
-
repoPath: canonicalizeRepoPath(t.repoPath)
|
|
2951
|
-
}))
|
|
2952
|
-
);
|
|
2953
|
-
if (existing) {
|
|
2954
|
-
const thread2 = readThread(existing.id) ?? existing;
|
|
2955
|
-
if (!input.attachments?.length) return thread2;
|
|
2956
|
-
return updateThread(thread2.id, {
|
|
2957
|
-
attachments: persistCreateAttachments(thread2.worktreePath, [
|
|
2958
|
-
...thread2.attachments,
|
|
2959
|
-
...input.attachments
|
|
2960
|
-
])
|
|
2961
|
-
});
|
|
2962
|
-
}
|
|
2963
|
-
}
|
|
3131
|
+
const reused = reuseLiveThread(input, repoPath, {
|
|
3132
|
+
sourceType: input.sourceType,
|
|
3133
|
+
sourceRef: input.sourceRef,
|
|
3134
|
+
title: input.title
|
|
3135
|
+
});
|
|
3136
|
+
if (reused) return reused;
|
|
2964
3137
|
const resolved = resolveNewThreadOptions({
|
|
2965
3138
|
agent: input.agent,
|
|
2966
3139
|
model: input.model,
|
|
@@ -2969,7 +3142,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2969
3142
|
});
|
|
2970
3143
|
await requireAgent(resolved.agent);
|
|
2971
3144
|
if (input.cowboy) {
|
|
2972
|
-
const { cowboyModeEnabled } = await import("./app-settings-
|
|
3145
|
+
const { cowboyModeEnabled } = await import("./app-settings-H3INSR67.js");
|
|
2973
3146
|
if (!cowboyModeEnabled()) {
|
|
2974
3147
|
throw new Error(
|
|
2975
3148
|
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
@@ -3027,7 +3200,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3027
3200
|
let sourceIsFork = false;
|
|
3028
3201
|
if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
|
|
3029
3202
|
if (isAbleTimeConnected() && getIssueSource() === "abletime") {
|
|
3030
|
-
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-
|
|
3203
|
+
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-H7LPGIP2.js");
|
|
3031
3204
|
const task = await ensureAbleTimeTask({
|
|
3032
3205
|
title: title?.trim() || "Untitled work",
|
|
3033
3206
|
description: input.prompt?.trim() || void 0
|
|
@@ -3037,6 +3210,12 @@ async function createThread(input, _onSetupLine) {
|
|
|
3037
3210
|
persistedSourceRef = task.identifier;
|
|
3038
3211
|
title = title?.trim() || task.title;
|
|
3039
3212
|
attachments = [...attachments, issueAttachmentForAbleTimeTask(task)];
|
|
3213
|
+
const reusedTicket = reuseLiveThread(
|
|
3214
|
+
{ ...input, sourceType: "ticket", sourceRef, title, attachments },
|
|
3215
|
+
repoPath,
|
|
3216
|
+
{ sourceType: "ticket", sourceRef, title }
|
|
3217
|
+
);
|
|
3218
|
+
if (reusedTicket) return reusedTicket;
|
|
3040
3219
|
}
|
|
3041
3220
|
}
|
|
3042
3221
|
let prUrl = null;
|
|
@@ -3046,6 +3225,14 @@ async function createThread(input, _onSetupLine) {
|
|
|
3046
3225
|
if (!Number.isFinite(num)) throw new Error(`Invalid PR number: ${input.sourceRef}`);
|
|
3047
3226
|
const pr = await getPr(repoPath, num);
|
|
3048
3227
|
if (!pr) throw new Error(`PR #${num} not found`);
|
|
3228
|
+
const reusedPr = reuseLiveThread(input, repoPath, {
|
|
3229
|
+
sourceType: "pr",
|
|
3230
|
+
sourceRef: String(pr.number),
|
|
3231
|
+
title: input.title ?? pr.title,
|
|
3232
|
+
prUrl: pr.url,
|
|
3233
|
+
headRefName: pr.headRefName
|
|
3234
|
+
});
|
|
3235
|
+
if (reusedPr) return reusedPr;
|
|
3049
3236
|
sourceIsFork = pr.isCrossRepository;
|
|
3050
3237
|
prUrl = pr.url;
|
|
3051
3238
|
const localFetchBranch = `sideboard-pr-${pr.number}`;
|
|
@@ -3058,9 +3245,19 @@ async function createThread(input, _onSetupLine) {
|
|
|
3058
3245
|
sourceRef = await resolveDefaultBranch(repoPath);
|
|
3059
3246
|
} else {
|
|
3060
3247
|
const existing = await getPrForHeadBranch(repoPath, sourceRef);
|
|
3061
|
-
if (existing
|
|
3062
|
-
|
|
3063
|
-
|
|
3248
|
+
if (existing) {
|
|
3249
|
+
const reusedPr = reuseLiveThread(input, repoPath, {
|
|
3250
|
+
sourceType: "pr",
|
|
3251
|
+
sourceRef: String(existing.number),
|
|
3252
|
+
title: input.title ?? existing.title,
|
|
3253
|
+
prUrl: existing.url,
|
|
3254
|
+
headRefName: existing.headRefName
|
|
3255
|
+
});
|
|
3256
|
+
if (reusedPr) return reusedPr;
|
|
3257
|
+
if (existing.url) {
|
|
3258
|
+
prUrl = existing.url;
|
|
3259
|
+
prTitle = existing.title;
|
|
3260
|
+
}
|
|
3064
3261
|
}
|
|
3065
3262
|
}
|
|
3066
3263
|
} else if (sourceType === "adopt") {
|
|
@@ -3100,7 +3297,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3100
3297
|
return readThread(thread.id) ?? thread;
|
|
3101
3298
|
}
|
|
3102
3299
|
async function listLinearIssues(agent, repoPath) {
|
|
3103
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
3300
|
+
const { getAdapter: getAdapter2 } = await import("./agents-YVW75KBO.js");
|
|
3104
3301
|
await requireAgent(agent, { requireLinear: true });
|
|
3105
3302
|
const adapter = getAdapter2(agent);
|
|
3106
3303
|
if (!adapter.listLinearIssues) {
|
|
@@ -3123,11 +3320,11 @@ function shouldRemoveWorktreeOnTeardown(thread) {
|
|
|
3123
3320
|
|
|
3124
3321
|
// src/store/turn-live.ts
|
|
3125
3322
|
import {
|
|
3126
|
-
existsSync as
|
|
3323
|
+
existsSync as existsSync9,
|
|
3127
3324
|
renameSync,
|
|
3128
3325
|
unlinkSync as unlinkSync2,
|
|
3129
|
-
writeFileSync as
|
|
3130
|
-
readFileSync as
|
|
3326
|
+
writeFileSync as writeFileSync4,
|
|
3327
|
+
readFileSync as readFileSync7
|
|
3131
3328
|
} from "fs";
|
|
3132
3329
|
var buffers = /* @__PURE__ */ new Map();
|
|
3133
3330
|
var FLUSH_MS = 800;
|
|
@@ -3204,7 +3401,7 @@ function writeTurnLive(threadId, progress) {
|
|
|
3204
3401
|
const path = threadLivePath(threadId);
|
|
3205
3402
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
3206
3403
|
try {
|
|
3207
|
-
|
|
3404
|
+
writeFileSync4(tmp, JSON.stringify(progress), "utf8");
|
|
3208
3405
|
renameSync(tmp, path);
|
|
3209
3406
|
} catch {
|
|
3210
3407
|
try {
|
|
@@ -3215,9 +3412,9 @@ function writeTurnLive(threadId, progress) {
|
|
|
3215
3412
|
}
|
|
3216
3413
|
function readTurnLive(threadId) {
|
|
3217
3414
|
const path = threadLivePath(threadId);
|
|
3218
|
-
if (!
|
|
3415
|
+
if (!existsSync9(path)) return null;
|
|
3219
3416
|
try {
|
|
3220
|
-
const raw = JSON.parse(
|
|
3417
|
+
const raw = JSON.parse(readFileSync7(path, "utf8"));
|
|
3221
3418
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
3222
3419
|
return raw;
|
|
3223
3420
|
} catch {
|
|
@@ -3229,7 +3426,7 @@ function clearTurnLive(threadId) {
|
|
|
3229
3426
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
3230
3427
|
buffers.delete(threadId);
|
|
3231
3428
|
const path = threadLivePath(threadId);
|
|
3232
|
-
if (!
|
|
3429
|
+
if (!existsSync9(path)) return;
|
|
3233
3430
|
try {
|
|
3234
3431
|
unlinkSync2(path);
|
|
3235
3432
|
} catch {
|
|
@@ -3413,26 +3610,26 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
|
|
|
3413
3610
|
import { execFileSync } from "child_process";
|
|
3414
3611
|
import {
|
|
3415
3612
|
copyFileSync as copyFileSync2,
|
|
3416
|
-
existsSync as
|
|
3613
|
+
existsSync as existsSync10,
|
|
3417
3614
|
mkdtempSync,
|
|
3418
3615
|
readdirSync as readdirSync3,
|
|
3419
|
-
readFileSync as
|
|
3616
|
+
readFileSync as readFileSync8,
|
|
3420
3617
|
rmSync
|
|
3421
3618
|
} from "fs";
|
|
3422
3619
|
import { tmpdir } from "os";
|
|
3423
|
-
import { join as
|
|
3620
|
+
import { join as join10 } from "path";
|
|
3424
3621
|
import { createRequire } from "module";
|
|
3425
|
-
var CONDUCTOR_APP_SUPPORT =
|
|
3622
|
+
var CONDUCTOR_APP_SUPPORT = join10(
|
|
3426
3623
|
process.env.HOME ?? "",
|
|
3427
3624
|
"Library",
|
|
3428
3625
|
"Application Support",
|
|
3429
3626
|
"com.conductor.app"
|
|
3430
3627
|
);
|
|
3431
|
-
var CONDUCTOR_DB =
|
|
3432
|
-
var CURSOR_SDK_STORE =
|
|
3628
|
+
var CONDUCTOR_DB = join10(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
3629
|
+
var CURSOR_SDK_STORE = join10(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
3433
3630
|
function thisModuleFile() {
|
|
3434
3631
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
3435
|
-
return cjsFile || process.argv[1] ||
|
|
3632
|
+
return cjsFile || process.argv[1] || join10(process.cwd(), "package.json");
|
|
3436
3633
|
}
|
|
3437
3634
|
function openReadonlySqlite(file) {
|
|
3438
3635
|
const req = createRequire(thisModuleFile());
|
|
@@ -3450,7 +3647,7 @@ function mapAgentType(raw) {
|
|
|
3450
3647
|
return null;
|
|
3451
3648
|
}
|
|
3452
3649
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
3453
|
-
if (!workspacePath || !
|
|
3650
|
+
if (!workspacePath || !existsSync10(CURSOR_SDK_STORE)) return null;
|
|
3454
3651
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
3455
3652
|
let best = null;
|
|
3456
3653
|
let hashes;
|
|
@@ -3460,11 +3657,11 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
3460
3657
|
return null;
|
|
3461
3658
|
}
|
|
3462
3659
|
for (const hash of hashes) {
|
|
3463
|
-
const agentsFile =
|
|
3464
|
-
if (!
|
|
3660
|
+
const agentsFile = join10(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
3661
|
+
if (!existsSync10(agentsFile)) continue;
|
|
3465
3662
|
let text;
|
|
3466
3663
|
try {
|
|
3467
|
-
text =
|
|
3664
|
+
text = readFileSync8(agentsFile, "utf8");
|
|
3468
3665
|
} catch {
|
|
3469
3666
|
continue;
|
|
3470
3667
|
}
|
|
@@ -3488,7 +3685,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
3488
3685
|
return best?.agentId ?? null;
|
|
3489
3686
|
}
|
|
3490
3687
|
async function adoptThread(input) {
|
|
3491
|
-
if (!
|
|
3688
|
+
if (!existsSync10(input.worktreePath)) {
|
|
3492
3689
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
3493
3690
|
}
|
|
3494
3691
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -3507,7 +3704,7 @@ async function adoptThread(input) {
|
|
|
3507
3704
|
messages: input.messages ?? []
|
|
3508
3705
|
});
|
|
3509
3706
|
writeThread(thread);
|
|
3510
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
3707
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-5UNDTN4G.js");
|
|
3511
3708
|
await ensureWorkspace2(repoPath);
|
|
3512
3709
|
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-X54WSOXM.js");
|
|
3513
3710
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
@@ -3517,16 +3714,16 @@ function conductorDbPath() {
|
|
|
3517
3714
|
return CONDUCTOR_DB;
|
|
3518
3715
|
}
|
|
3519
3716
|
function listConductorWorkspaces() {
|
|
3520
|
-
if (!
|
|
3717
|
+
if (!existsSync10(CONDUCTOR_DB)) {
|
|
3521
3718
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
3522
3719
|
}
|
|
3523
|
-
const tmp = mkdtempSync(
|
|
3524
|
-
const snapshot =
|
|
3720
|
+
const tmp = mkdtempSync(join10(tmpdir(), "sideboard-conductor-"));
|
|
3721
|
+
const snapshot = join10(tmp, "conductor.db");
|
|
3525
3722
|
try {
|
|
3526
3723
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
3527
3724
|
for (const suffix of ["-wal", "-shm"]) {
|
|
3528
3725
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
3529
|
-
if (
|
|
3726
|
+
if (existsSync10(src)) {
|
|
3530
3727
|
try {
|
|
3531
3728
|
copyFileSync2(src, `${snapshot}${suffix}`);
|
|
3532
3729
|
} catch {
|
|
@@ -3608,16 +3805,16 @@ function listConductorWorkspaces() {
|
|
|
3608
3805
|
}
|
|
3609
3806
|
}
|
|
3610
3807
|
function importConductorWorkspace(workspaceId) {
|
|
3611
|
-
if (!
|
|
3808
|
+
if (!existsSync10(CONDUCTOR_DB)) {
|
|
3612
3809
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
3613
3810
|
}
|
|
3614
|
-
const tmp = mkdtempSync(
|
|
3615
|
-
const snapshot =
|
|
3811
|
+
const tmp = mkdtempSync(join10(tmpdir(), "sideboard-conductor-"));
|
|
3812
|
+
const snapshot = join10(tmp, "conductor.db");
|
|
3616
3813
|
try {
|
|
3617
3814
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
3618
3815
|
for (const suffix of ["-wal", "-shm"]) {
|
|
3619
3816
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
3620
|
-
if (
|
|
3817
|
+
if (existsSync10(src)) {
|
|
3621
3818
|
try {
|
|
3622
3819
|
copyFileSync2(src, `${snapshot}${suffix}`);
|
|
3623
3820
|
} catch {
|
|
@@ -3637,7 +3834,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
3637
3834
|
).get(workspaceId);
|
|
3638
3835
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
3639
3836
|
const worktreePath = String(row.workspacePath);
|
|
3640
|
-
if (!
|
|
3837
|
+
if (!existsSync10(worktreePath)) {
|
|
3641
3838
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
3642
3839
|
}
|
|
3643
3840
|
let sessionId = null;
|
|
@@ -3708,7 +3905,7 @@ async function importConductorWorkspaceAsync(workspaceId) {
|
|
|
3708
3905
|
}
|
|
3709
3906
|
|
|
3710
3907
|
// src/threads/stack-layers.ts
|
|
3711
|
-
import { existsSync as
|
|
3908
|
+
import { existsSync as existsSync11 } from "fs";
|
|
3712
3909
|
function stackIdFrom(stack) {
|
|
3713
3910
|
if (stack.stackNumber != null) return `gh-stack-${stack.stackNumber}`;
|
|
3714
3911
|
const key = stack.layers.map((l) => l.branchName).join("|");
|
|
@@ -3771,7 +3968,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
3771
3968
|
let createdWorktree = false;
|
|
3772
3969
|
const trees = await listWorktrees(repoPath);
|
|
3773
3970
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
3774
|
-
if (checkedOut?.path &&
|
|
3971
|
+
if (checkedOut?.path && existsSync11(checkedOut.path)) {
|
|
3775
3972
|
if (input.reuseExistingWorktree !== false) {
|
|
3776
3973
|
worktreePath = checkedOut.path;
|
|
3777
3974
|
} else {
|
|
@@ -3913,7 +4110,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
3913
4110
|
async function createPrStack(input, onSetupLine) {
|
|
3914
4111
|
await requireAgent(input.agent);
|
|
3915
4112
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
3916
|
-
if (!
|
|
4113
|
+
if (!existsSync11(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
3917
4114
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
3918
4115
|
const status = await detectGhStack(repoPath);
|
|
3919
4116
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -3980,7 +4177,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
3980
4177
|
}
|
|
3981
4178
|
}
|
|
3982
4179
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
3983
|
-
if (!claimed.has(bootstrap.worktreePath) &&
|
|
4180
|
+
if (!claimed.has(bootstrap.worktreePath) && existsSync11(bootstrap.worktreePath)) {
|
|
3984
4181
|
try {
|
|
3985
4182
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
3986
4183
|
deleteBranch: bootstrap.branchName
|
|
@@ -4002,10 +4199,10 @@ function stackAgentDefaultsFrom(input) {
|
|
|
4002
4199
|
}
|
|
4003
4200
|
|
|
4004
4201
|
// src/diff/diff.ts
|
|
4005
|
-
import { existsSync as
|
|
4006
|
-
import { dirname as dirname3, join as
|
|
4202
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync3, readFileSync as readFileSync9, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
4203
|
+
import { dirname as dirname3, join as join11 } from "path";
|
|
4007
4204
|
async function inspectGitWorktree(worktreePath) {
|
|
4008
|
-
if (!worktreePath || !
|
|
4205
|
+
if (!worktreePath || !existsSync12(worktreePath)) return "missing_worktree";
|
|
4009
4206
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
4010
4207
|
reject: false
|
|
4011
4208
|
});
|
|
@@ -4013,7 +4210,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
4013
4210
|
return "ok";
|
|
4014
4211
|
}
|
|
4015
4212
|
async function initializeGitRepository(worktreePath) {
|
|
4016
|
-
if (!worktreePath || !
|
|
4213
|
+
if (!worktreePath || !existsSync12(worktreePath)) {
|
|
4017
4214
|
throw new Error("Worktree not found");
|
|
4018
4215
|
}
|
|
4019
4216
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -4149,11 +4346,11 @@ new file mode 100644
|
|
|
4149
4346
|
};
|
|
4150
4347
|
}
|
|
4151
4348
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
4152
|
-
const abs =
|
|
4349
|
+
const abs = join11(worktreePath, path);
|
|
4153
4350
|
try {
|
|
4154
4351
|
const st = statSync2(abs);
|
|
4155
4352
|
if (st.isFile() && st.size > maxHunk) {
|
|
4156
|
-
const buf =
|
|
4353
|
+
const buf = readFileSync9(abs).subarray(0, maxHunk);
|
|
4157
4354
|
return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
|
|
4158
4355
|
}
|
|
4159
4356
|
} catch {
|
|
@@ -4654,7 +4851,7 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
|
4654
4851
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
4655
4852
|
assertSafeRelativePath(relativePath);
|
|
4656
4853
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
4657
|
-
const abs =
|
|
4854
|
+
const abs = join11(worktreePath, relativePath);
|
|
4658
4855
|
const st = statSync2(abs);
|
|
4659
4856
|
if (!st.isFile()) {
|
|
4660
4857
|
throw new Error(`Not a file: ${relativePath}`);
|
|
@@ -4664,7 +4861,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
4664
4861
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
4665
4862
|
);
|
|
4666
4863
|
}
|
|
4667
|
-
const buf =
|
|
4864
|
+
const buf = readFileSync9(abs);
|
|
4668
4865
|
return {
|
|
4669
4866
|
path: relativePath,
|
|
4670
4867
|
contentBase64: buf.toString("base64"),
|
|
@@ -4674,12 +4871,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
4674
4871
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
4675
4872
|
assertSafeRelativePath(relativePath);
|
|
4676
4873
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
4677
|
-
const abs =
|
|
4874
|
+
const abs = join11(worktreePath, relativePath);
|
|
4678
4875
|
const st = statSync2(abs);
|
|
4679
4876
|
if (!st.isFile()) {
|
|
4680
4877
|
throw new Error(`Not a file: ${relativePath}`);
|
|
4681
4878
|
}
|
|
4682
|
-
const buf =
|
|
4879
|
+
const buf = readFileSync9(abs);
|
|
4683
4880
|
if (isImageRelativePath(relativePath)) {
|
|
4684
4881
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
4685
4882
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -4722,9 +4919,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
4722
4919
|
}
|
|
4723
4920
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
4724
4921
|
assertSafeRelativePath(relativePath);
|
|
4725
|
-
const abs =
|
|
4922
|
+
const abs = join11(worktreePath, relativePath);
|
|
4726
4923
|
mkdirSync3(dirname3(abs), { recursive: true });
|
|
4727
|
-
|
|
4924
|
+
writeFileSync5(abs, content, "utf8");
|
|
4728
4925
|
return { path: relativePath };
|
|
4729
4926
|
}
|
|
4730
4927
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -4849,9 +5046,9 @@ async function confirmLand(thread, opts) {
|
|
|
4849
5046
|
}
|
|
4850
5047
|
|
|
4851
5048
|
// src/skills/discover.ts
|
|
4852
|
-
import { existsSync as
|
|
5049
|
+
import { existsSync as existsSync13, readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
|
|
4853
5050
|
import { homedir } from "os";
|
|
4854
|
-
import { join as
|
|
5051
|
+
import { join as join12 } from "path";
|
|
4855
5052
|
|
|
4856
5053
|
// src/skills/bundled/long-running.ts
|
|
4857
5054
|
var LONG_RUNNING_SKILL_COMMAND = "long-running";
|
|
@@ -4980,7 +5177,7 @@ function parseFrontmatter(content) {
|
|
|
4980
5177
|
}
|
|
4981
5178
|
function readSkill(skillMd, source) {
|
|
4982
5179
|
try {
|
|
4983
|
-
const content =
|
|
5180
|
+
const content = readFileSync10(skillMd, "utf8");
|
|
4984
5181
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
4985
5182
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
4986
5183
|
const name = fmName || dirName;
|
|
@@ -4999,7 +5196,7 @@ function readSkill(skillMd, source) {
|
|
|
4999
5196
|
}
|
|
5000
5197
|
}
|
|
5001
5198
|
function scanSkillsDir(dir, source, out) {
|
|
5002
|
-
if (!
|
|
5199
|
+
if (!existsSync13(dir)) return;
|
|
5003
5200
|
let entries;
|
|
5004
5201
|
try {
|
|
5005
5202
|
entries = readdirSync4(dir);
|
|
@@ -5008,8 +5205,8 @@ function scanSkillsDir(dir, source, out) {
|
|
|
5008
5205
|
}
|
|
5009
5206
|
for (const entry of entries) {
|
|
5010
5207
|
if (entry.startsWith(".")) continue;
|
|
5011
|
-
const skillMd =
|
|
5012
|
-
if (!
|
|
5208
|
+
const skillMd = join12(dir, entry, "SKILL.md");
|
|
5209
|
+
if (!existsSync13(skillMd)) continue;
|
|
5013
5210
|
try {
|
|
5014
5211
|
if (!statSync3(skillMd).isFile()) continue;
|
|
5015
5212
|
} catch {
|
|
@@ -5020,7 +5217,7 @@ function scanSkillsDir(dir, source, out) {
|
|
|
5020
5217
|
}
|
|
5021
5218
|
}
|
|
5022
5219
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
5023
|
-
if (!
|
|
5220
|
+
if (!existsSync13(pluginsRoot)) return;
|
|
5024
5221
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
5025
5222
|
if (depth > 7) return;
|
|
5026
5223
|
let entries;
|
|
@@ -5030,12 +5227,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
|
|
|
5030
5227
|
return;
|
|
5031
5228
|
}
|
|
5032
5229
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
5033
|
-
const skill = readSkill(
|
|
5230
|
+
const skill = readSkill(join12(dir, "SKILL.md"), "cli");
|
|
5034
5231
|
if (skill) out.push(skill);
|
|
5035
5232
|
}
|
|
5036
5233
|
for (const entry of entries) {
|
|
5037
5234
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
5038
|
-
const full =
|
|
5235
|
+
const full = join12(dir, entry);
|
|
5039
5236
|
try {
|
|
5040
5237
|
if (!statSync3(full).isDirectory()) continue;
|
|
5041
5238
|
} catch {
|
|
@@ -5055,17 +5252,17 @@ function discoverSkills(worktreePath) {
|
|
|
5055
5252
|
const home = homedir();
|
|
5056
5253
|
const collected = [];
|
|
5057
5254
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
5058
|
-
scanSkillsDir(
|
|
5255
|
+
scanSkillsDir(join12(worktreePath, rel), "workspace", collected);
|
|
5059
5256
|
}
|
|
5060
5257
|
for (const abs of [
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5258
|
+
join12(home, ".claude/skills"),
|
|
5259
|
+
join12(home, ".cursor/skills"),
|
|
5260
|
+
join12(home, ".sideboard/skills"),
|
|
5261
|
+
join12(home, ".brightsy/skills")
|
|
5065
5262
|
]) {
|
|
5066
5263
|
scanSkillsDir(abs, "user", collected);
|
|
5067
5264
|
}
|
|
5068
|
-
scanClaudePluginSkills(
|
|
5265
|
+
scanClaudePluginSkills(join12(home, ".claude/plugins"), collected);
|
|
5069
5266
|
collected.push(...bundledSkills());
|
|
5070
5267
|
const rank = {
|
|
5071
5268
|
workspace: 0,
|
|
@@ -5091,7 +5288,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
5091
5288
|
\u2026(truncated)` : body;
|
|
5092
5289
|
}
|
|
5093
5290
|
}
|
|
5094
|
-
const raw =
|
|
5291
|
+
const raw = readFileSync10(skillPath, "utf8");
|
|
5095
5292
|
if (raw.startsWith("---")) {
|
|
5096
5293
|
const end = raw.indexOf("\n---", 3);
|
|
5097
5294
|
if (end >= 0) {
|
|
@@ -5184,26 +5381,26 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
|
|
|
5184
5381
|
}
|
|
5185
5382
|
|
|
5186
5383
|
// src/agents/instructions.ts
|
|
5187
|
-
import { existsSync as
|
|
5188
|
-
import { join as
|
|
5384
|
+
import { existsSync as existsSync15, readFileSync as readFileSync11, statSync as statSync4 } from "fs";
|
|
5385
|
+
import { join as join14 } from "path";
|
|
5189
5386
|
|
|
5190
5387
|
// src/skills/detached-job-path.ts
|
|
5191
|
-
import { existsSync as
|
|
5192
|
-
import { dirname as dirname4, join as
|
|
5388
|
+
import { existsSync as existsSync14 } from "fs";
|
|
5389
|
+
import { dirname as dirname4, join as join13 } from "path";
|
|
5193
5390
|
import { fileURLToPath } from "url";
|
|
5194
5391
|
function packagedDetachedJobPath() {
|
|
5195
5392
|
const dir = packagedMcpDir();
|
|
5196
5393
|
if (!dir) return null;
|
|
5197
|
-
const script =
|
|
5198
|
-
return
|
|
5394
|
+
const script = join13(dir, "scripts", "detached-job.js");
|
|
5395
|
+
return existsSync14(script) ? script : null;
|
|
5199
5396
|
}
|
|
5200
5397
|
function resolveDetachedJobScript() {
|
|
5201
5398
|
const packaged = packagedDetachedJobPath();
|
|
5202
5399
|
if (packaged) return packaged;
|
|
5203
5400
|
let dir = dirname4(fileURLToPath(import.meta.url));
|
|
5204
5401
|
for (let i = 0; i < 8; i++) {
|
|
5205
|
-
const candidate =
|
|
5206
|
-
if (
|
|
5402
|
+
const candidate = join13(dir, "scripts", "detached-job.js");
|
|
5403
|
+
if (existsSync14(candidate)) return candidate;
|
|
5207
5404
|
const parent = dirname4(dir);
|
|
5208
5405
|
if (parent === dir) break;
|
|
5209
5406
|
dir = parent;
|
|
@@ -5408,11 +5605,11 @@ function loadAgentInstructions(worktreePath, agent) {
|
|
|
5408
5605
|
const out = [];
|
|
5409
5606
|
for (const rel of candidates) {
|
|
5410
5607
|
if (seenPaths.has(rel)) continue;
|
|
5411
|
-
const abs =
|
|
5412
|
-
if (!
|
|
5608
|
+
const abs = join14(worktreePath, rel);
|
|
5609
|
+
if (!existsSync15(abs)) continue;
|
|
5413
5610
|
try {
|
|
5414
5611
|
if (!statSync4(abs).isFile()) continue;
|
|
5415
|
-
let content =
|
|
5612
|
+
let content = readFileSync11(abs, "utf8");
|
|
5416
5613
|
if (!content.trim()) continue;
|
|
5417
5614
|
if (content.length > MAX_CHARS_PER_FILE) {
|
|
5418
5615
|
content = `${content.slice(0, MAX_CHARS_PER_FILE)}
|
|
@@ -5732,8 +5929,8 @@ async function syncThreadBranchFromGit(threadId) {
|
|
|
5732
5929
|
|
|
5733
5930
|
// src/store/schedules.ts
|
|
5734
5931
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
5735
|
-
import { existsSync as
|
|
5736
|
-
import { join as
|
|
5932
|
+
import { existsSync as existsSync16, readFileSync as readFileSync12 } from "fs";
|
|
5933
|
+
import { join as join15 } from "path";
|
|
5737
5934
|
import { Cron } from "croner";
|
|
5738
5935
|
var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
|
|
5739
5936
|
var UNIT_MS = {
|
|
@@ -5743,7 +5940,7 @@ var UNIT_MS = {
|
|
|
5743
5940
|
d: 864e5
|
|
5744
5941
|
};
|
|
5745
5942
|
function schedulesPath() {
|
|
5746
|
-
return
|
|
5943
|
+
return join15(appDataDir(), "schedules.json");
|
|
5747
5944
|
}
|
|
5748
5945
|
function parseDurationMs(every) {
|
|
5749
5946
|
const m = every.trim().match(DURATION_RE);
|
|
@@ -5849,9 +6046,9 @@ function normalizeTask(raw) {
|
|
|
5849
6046
|
}
|
|
5850
6047
|
function readAll() {
|
|
5851
6048
|
const path = schedulesPath();
|
|
5852
|
-
if (!
|
|
6049
|
+
if (!existsSync16(path)) return [];
|
|
5853
6050
|
try {
|
|
5854
|
-
const parsed = JSON.parse(
|
|
6051
|
+
const parsed = JSON.parse(readFileSync12(path, "utf8"));
|
|
5855
6052
|
if (!Array.isArray(parsed)) return [];
|
|
5856
6053
|
return parsed.map((row) => {
|
|
5857
6054
|
try {
|
|
@@ -5977,7 +6174,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
5977
6174
|
${prompt}`;
|
|
5978
6175
|
}
|
|
5979
6176
|
async function defaultDeps() {
|
|
5980
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
6177
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-5PSHBLP6.js");
|
|
5981
6178
|
const orch = getOrchestrator2();
|
|
5982
6179
|
return {
|
|
5983
6180
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -6217,7 +6414,7 @@ var Orchestrator = class {
|
|
|
6217
6414
|
}
|
|
6218
6415
|
continue;
|
|
6219
6416
|
}
|
|
6220
|
-
if (!
|
|
6417
|
+
if (!existsSync17(thread.worktreePath)) {
|
|
6221
6418
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
6222
6419
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
6223
6420
|
continue;
|
|
@@ -6236,7 +6433,7 @@ var Orchestrator = class {
|
|
|
6236
6433
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
6237
6434
|
});
|
|
6238
6435
|
}
|
|
6239
|
-
const { autoCleanupOrphansEnabled } = await import("./app-settings-
|
|
6436
|
+
const { autoCleanupOrphansEnabled } = await import("./app-settings-H3INSR67.js");
|
|
6240
6437
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
6241
6438
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
6242
6439
|
}
|
|
@@ -6476,7 +6673,7 @@ var Orchestrator = class {
|
|
|
6476
6673
|
}
|
|
6477
6674
|
await setup;
|
|
6478
6675
|
if (skipSetup) return;
|
|
6479
|
-
const { autoRunAfterSetupEnabled } = await import("./app-settings-
|
|
6676
|
+
const { autoRunAfterSetupEnabled } = await import("./app-settings-H3INSR67.js");
|
|
6480
6677
|
if (autoRunAfterSetupEnabled()) {
|
|
6481
6678
|
try {
|
|
6482
6679
|
await this.startDev(threadId);
|
|
@@ -6784,7 +6981,7 @@ var Orchestrator = class {
|
|
|
6784
6981
|
}
|
|
6785
6982
|
const isBrightsy = fresh.agent === "brightsy";
|
|
6786
6983
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
6787
|
-
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-
|
|
6984
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-H3INSR67.js");
|
|
6788
6985
|
const gitAuthMode = getGithubGitAuthMode();
|
|
6789
6986
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
6790
6987
|
githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
|
|
@@ -6890,7 +7087,7 @@ var Orchestrator = class {
|
|
|
6890
7087
|
if (!this.stoppedTurns.has(threadId) && this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
|
|
6891
7088
|
const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
|
|
6892
7089
|
if (sessionId) {
|
|
6893
|
-
const { recoverFinishedCursorRun } = await import("./cursor-recover-
|
|
7090
|
+
const { recoverFinishedCursorRun } = await import("./cursor-recover-NDMLLNYX.js");
|
|
6894
7091
|
for (let i = 0; i < 8; i++) {
|
|
6895
7092
|
const recovered = recoverFinishedCursorRun({
|
|
6896
7093
|
agentId: sessionId,
|
|
@@ -7280,6 +7477,15 @@ var Orchestrator = class {
|
|
|
7280
7477
|
getActiveRuns(threadRef) {
|
|
7281
7478
|
return this.requireThread(threadRef).activeRuns ?? [];
|
|
7282
7479
|
}
|
|
7480
|
+
getSetupLog(threadRef) {
|
|
7481
|
+
const thread = this.getThread(threadRef);
|
|
7482
|
+
if (!thread) return readSetupLog(threadRef);
|
|
7483
|
+
const snap = readSetupLog(thread.id);
|
|
7484
|
+
if (snap.running && !this.processes.has(`${thread.id}:setup`)) {
|
|
7485
|
+
return { ...snap, running: false };
|
|
7486
|
+
}
|
|
7487
|
+
return snap;
|
|
7488
|
+
}
|
|
7283
7489
|
async runSetup(threadRef) {
|
|
7284
7490
|
const thread = this.requireThread(threadRef);
|
|
7285
7491
|
this.assertNotGlobal(thread, "Setup");
|
|
@@ -7293,20 +7499,31 @@ var Orchestrator = class {
|
|
|
7293
7499
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7294
7500
|
kill: () => abort.abort()
|
|
7295
7501
|
});
|
|
7502
|
+
beginSetupLog(thread.id);
|
|
7296
7503
|
this.emit({ type: "setup_started", threadId: thread.id });
|
|
7504
|
+
let finished = false;
|
|
7505
|
+
const finish = (exitCode, source) => {
|
|
7506
|
+
if (finished) return;
|
|
7507
|
+
finished = true;
|
|
7508
|
+
finishSetupLog(thread.id, exitCode, source);
|
|
7509
|
+
this.emit({ type: "setup_finished", threadId: thread.id, exitCode });
|
|
7510
|
+
};
|
|
7297
7511
|
try {
|
|
7298
7512
|
const setup = await runWorkspaceSetup(
|
|
7299
7513
|
thread.repoPath,
|
|
7300
7514
|
thread.worktreePath,
|
|
7301
7515
|
(line) => {
|
|
7516
|
+
appendSetupLog(thread.id, line);
|
|
7302
7517
|
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
7303
7518
|
},
|
|
7304
7519
|
{ signal: abort.signal }
|
|
7305
7520
|
);
|
|
7306
7521
|
if (!setup.ran) {
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
);
|
|
7522
|
+
const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
|
|
7523
|
+
appendSetupLog(thread.id, line);
|
|
7524
|
+
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
7525
|
+
finish(null, null);
|
|
7526
|
+
throw new Error(line);
|
|
7310
7527
|
}
|
|
7311
7528
|
if (setup.exitCode !== 0 && setup.exitCode !== null) {
|
|
7312
7529
|
const live = readThread(thread.id);
|
|
@@ -7319,8 +7536,11 @@ var Orchestrator = class {
|
|
|
7319
7536
|
});
|
|
7320
7537
|
}
|
|
7321
7538
|
}
|
|
7322
|
-
|
|
7539
|
+
finish(setup.exitCode, setup.source);
|
|
7323
7540
|
return { exitCode: setup.exitCode, source: setup.source };
|
|
7541
|
+
} catch (err) {
|
|
7542
|
+
finish(null, null);
|
|
7543
|
+
throw err;
|
|
7324
7544
|
} finally {
|
|
7325
7545
|
this.processes.delete(key);
|
|
7326
7546
|
}
|
|
@@ -7647,7 +7867,7 @@ var Orchestrator = class {
|
|
|
7647
7867
|
updateThread(thread.id, { title: meta.title });
|
|
7648
7868
|
}
|
|
7649
7869
|
}
|
|
7650
|
-
const { autoArchiveOnMergeEnabled } = await import("./app-settings-
|
|
7870
|
+
const { autoArchiveOnMergeEnabled } = await import("./app-settings-H3INSR67.js");
|
|
7651
7871
|
const latest = this.requireThread(thread.id);
|
|
7652
7872
|
if (!shouldAutoArchiveOnPrMerge({
|
|
7653
7873
|
previousPrState: prevState || null,
|
|
@@ -7964,7 +8184,7 @@ var Orchestrator = class {
|
|
|
7964
8184
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
7965
8185
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
7966
8186
|
try {
|
|
7967
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
8187
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-5UNDTN4G.js");
|
|
7968
8188
|
await ensureWorkspace2(thread.repoPath);
|
|
7969
8189
|
} catch {
|
|
7970
8190
|
}
|
|
@@ -7991,7 +8211,7 @@ var Orchestrator = class {
|
|
|
7991
8211
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
7992
8212
|
} catch {
|
|
7993
8213
|
}
|
|
7994
|
-
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-
|
|
8214
|
+
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-H3INSR67.js");
|
|
7995
8215
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
7996
8216
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
7997
8217
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -8006,19 +8226,19 @@ var Orchestrator = class {
|
|
|
8006
8226
|
throw new Error("Thread is not archived");
|
|
8007
8227
|
}
|
|
8008
8228
|
if (isGlobalThread(thread)) {
|
|
8009
|
-
const { globalAgentCwd } = await import("./paths-
|
|
8229
|
+
const { globalAgentCwd } = await import("./paths-53TLA7VQ.js");
|
|
8010
8230
|
updateThread(thread.id, { worktreePath: globalAgentCwd() });
|
|
8011
8231
|
const restored2 = setStatus(thread.id, "idle");
|
|
8012
8232
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
8013
8233
|
return restored2;
|
|
8014
8234
|
}
|
|
8015
|
-
if (!
|
|
8235
|
+
if (!existsSync17(thread.worktreePath)) {
|
|
8016
8236
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
8017
8237
|
throw new Error(
|
|
8018
8238
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
8019
8239
|
);
|
|
8020
8240
|
}
|
|
8021
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
8241
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-T4SWFSTT.js");
|
|
8022
8242
|
const slug = thread.worktreePath.split("/").pop();
|
|
8023
8243
|
const dest = thread.worktreePath;
|
|
8024
8244
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -8128,7 +8348,7 @@ async function startOrchestration(opts) {
|
|
|
8128
8348
|
sourceRef: "default",
|
|
8129
8349
|
...createOpts
|
|
8130
8350
|
}).catch(async () => {
|
|
8131
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
8351
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-T4SWFSTT.js");
|
|
8132
8352
|
const repo = await resolveRepoRoot2(repoPath);
|
|
8133
8353
|
const def = await resolveDefaultBranch2(repo);
|
|
8134
8354
|
return orch.createThread({
|
|
@@ -8138,7 +8358,7 @@ async function startOrchestration(opts) {
|
|
|
8138
8358
|
repoPath: repo
|
|
8139
8359
|
});
|
|
8140
8360
|
});
|
|
8141
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
8361
|
+
const { updateThread: upd } = await import("./thread-store-KBFBHT5G.js");
|
|
8142
8362
|
const updated = upd(thread.id, {
|
|
8143
8363
|
sourceType: "orchestration",
|
|
8144
8364
|
sourceRef: goal
|
|
@@ -8150,6 +8370,9 @@ async function startOrchestration(opts) {
|
|
|
8150
8370
|
}
|
|
8151
8371
|
|
|
8152
8372
|
export {
|
|
8373
|
+
emptySetupLog,
|
|
8374
|
+
mergeSetupOutput,
|
|
8375
|
+
readSetupLog,
|
|
8153
8376
|
schedulesPath,
|
|
8154
8377
|
parseDurationMs,
|
|
8155
8378
|
defaultScheduleName,
|
|
@@ -8284,6 +8507,7 @@ export {
|
|
|
8284
8507
|
issueNeedsWorkspacePick,
|
|
8285
8508
|
isAccountWideIssueSource,
|
|
8286
8509
|
findLiveThreadForCreate,
|
|
8510
|
+
findLiveThreadForCreateSource,
|
|
8287
8511
|
boardPinIdentity,
|
|
8288
8512
|
findBoardPin,
|
|
8289
8513
|
syncBoardPins,
|