@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
|
@@ -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-ZSSU3FKW.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 {
|
|
@@ -3324,26 +3474,26 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
|
|
|
3324
3474
|
import { execFileSync } from "child_process";
|
|
3325
3475
|
import {
|
|
3326
3476
|
copyFileSync as copyFileSync2,
|
|
3327
|
-
existsSync as
|
|
3477
|
+
existsSync as existsSync10,
|
|
3328
3478
|
mkdtempSync,
|
|
3329
3479
|
readdirSync as readdirSync3,
|
|
3330
|
-
readFileSync as
|
|
3480
|
+
readFileSync as readFileSync8,
|
|
3331
3481
|
rmSync
|
|
3332
3482
|
} from "fs";
|
|
3333
3483
|
import { tmpdir } from "os";
|
|
3334
|
-
import { join as
|
|
3484
|
+
import { join as join10 } from "path";
|
|
3335
3485
|
import { createRequire } from "module";
|
|
3336
|
-
var CONDUCTOR_APP_SUPPORT =
|
|
3486
|
+
var CONDUCTOR_APP_SUPPORT = join10(
|
|
3337
3487
|
process.env.HOME ?? "",
|
|
3338
3488
|
"Library",
|
|
3339
3489
|
"Application Support",
|
|
3340
3490
|
"com.conductor.app"
|
|
3341
3491
|
);
|
|
3342
|
-
var CONDUCTOR_DB =
|
|
3343
|
-
var CURSOR_SDK_STORE =
|
|
3492
|
+
var CONDUCTOR_DB = join10(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
3493
|
+
var CURSOR_SDK_STORE = join10(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
3344
3494
|
function thisModuleFile() {
|
|
3345
3495
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
3346
|
-
return cjsFile || process.argv[1] ||
|
|
3496
|
+
return cjsFile || process.argv[1] || join10(process.cwd(), "package.json");
|
|
3347
3497
|
}
|
|
3348
3498
|
function openReadonlySqlite(file) {
|
|
3349
3499
|
const req = createRequire(thisModuleFile());
|
|
@@ -3361,7 +3511,7 @@ function mapAgentType(raw) {
|
|
|
3361
3511
|
return null;
|
|
3362
3512
|
}
|
|
3363
3513
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
3364
|
-
if (!workspacePath || !
|
|
3514
|
+
if (!workspacePath || !existsSync10(CURSOR_SDK_STORE)) return null;
|
|
3365
3515
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
3366
3516
|
let best = null;
|
|
3367
3517
|
let hashes;
|
|
@@ -3371,11 +3521,11 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
3371
3521
|
return null;
|
|
3372
3522
|
}
|
|
3373
3523
|
for (const hash of hashes) {
|
|
3374
|
-
const agentsFile =
|
|
3375
|
-
if (!
|
|
3524
|
+
const agentsFile = join10(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
3525
|
+
if (!existsSync10(agentsFile)) continue;
|
|
3376
3526
|
let text;
|
|
3377
3527
|
try {
|
|
3378
|
-
text =
|
|
3528
|
+
text = readFileSync8(agentsFile, "utf8");
|
|
3379
3529
|
} catch {
|
|
3380
3530
|
continue;
|
|
3381
3531
|
}
|
|
@@ -3399,7 +3549,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
3399
3549
|
return best?.agentId ?? null;
|
|
3400
3550
|
}
|
|
3401
3551
|
async function adoptThread(input) {
|
|
3402
|
-
if (!
|
|
3552
|
+
if (!existsSync10(input.worktreePath)) {
|
|
3403
3553
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
3404
3554
|
}
|
|
3405
3555
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -3418,23 +3568,23 @@ async function adoptThread(input) {
|
|
|
3418
3568
|
messages: input.messages ?? []
|
|
3419
3569
|
});
|
|
3420
3570
|
writeThread(thread);
|
|
3421
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
3571
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-MQYNZXUK.js");
|
|
3422
3572
|
await ensureWorkspace2(repoPath);
|
|
3423
3573
|
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
|
|
3424
3574
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
3425
3575
|
return thread;
|
|
3426
3576
|
}
|
|
3427
3577
|
function listConductorWorkspaces() {
|
|
3428
|
-
if (!
|
|
3578
|
+
if (!existsSync10(CONDUCTOR_DB)) {
|
|
3429
3579
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
3430
3580
|
}
|
|
3431
|
-
const tmp = mkdtempSync(
|
|
3432
|
-
const snapshot =
|
|
3581
|
+
const tmp = mkdtempSync(join10(tmpdir(), "sideboard-conductor-"));
|
|
3582
|
+
const snapshot = join10(tmp, "conductor.db");
|
|
3433
3583
|
try {
|
|
3434
3584
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
3435
3585
|
for (const suffix of ["-wal", "-shm"]) {
|
|
3436
3586
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
3437
|
-
if (
|
|
3587
|
+
if (existsSync10(src)) {
|
|
3438
3588
|
try {
|
|
3439
3589
|
copyFileSync2(src, `${snapshot}${suffix}`);
|
|
3440
3590
|
} catch {
|
|
@@ -3516,16 +3666,16 @@ function listConductorWorkspaces() {
|
|
|
3516
3666
|
}
|
|
3517
3667
|
}
|
|
3518
3668
|
function importConductorWorkspace(workspaceId) {
|
|
3519
|
-
if (!
|
|
3669
|
+
if (!existsSync10(CONDUCTOR_DB)) {
|
|
3520
3670
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
3521
3671
|
}
|
|
3522
|
-
const tmp = mkdtempSync(
|
|
3523
|
-
const snapshot =
|
|
3672
|
+
const tmp = mkdtempSync(join10(tmpdir(), "sideboard-conductor-"));
|
|
3673
|
+
const snapshot = join10(tmp, "conductor.db");
|
|
3524
3674
|
try {
|
|
3525
3675
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
3526
3676
|
for (const suffix of ["-wal", "-shm"]) {
|
|
3527
3677
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
3528
|
-
if (
|
|
3678
|
+
if (existsSync10(src)) {
|
|
3529
3679
|
try {
|
|
3530
3680
|
copyFileSync2(src, `${snapshot}${suffix}`);
|
|
3531
3681
|
} catch {
|
|
@@ -3545,7 +3695,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
3545
3695
|
).get(workspaceId);
|
|
3546
3696
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
3547
3697
|
const worktreePath = String(row.workspacePath);
|
|
3548
|
-
if (!
|
|
3698
|
+
if (!existsSync10(worktreePath)) {
|
|
3549
3699
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
3550
3700
|
}
|
|
3551
3701
|
let sessionId = null;
|
|
@@ -3616,7 +3766,7 @@ async function importConductorWorkspaceAsync(workspaceId) {
|
|
|
3616
3766
|
}
|
|
3617
3767
|
|
|
3618
3768
|
// src/threads/stack-layers.ts
|
|
3619
|
-
import { existsSync as
|
|
3769
|
+
import { existsSync as existsSync11 } from "fs";
|
|
3620
3770
|
function stackIdFrom(stack) {
|
|
3621
3771
|
if (stack.stackNumber != null) return `gh-stack-${stack.stackNumber}`;
|
|
3622
3772
|
const key = stack.layers.map((l) => l.branchName).join("|");
|
|
@@ -3679,7 +3829,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
3679
3829
|
let createdWorktree = false;
|
|
3680
3830
|
const trees = await listWorktrees(repoPath);
|
|
3681
3831
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
3682
|
-
if (checkedOut?.path &&
|
|
3832
|
+
if (checkedOut?.path && existsSync11(checkedOut.path)) {
|
|
3683
3833
|
if (input.reuseExistingWorktree !== false) {
|
|
3684
3834
|
worktreePath = checkedOut.path;
|
|
3685
3835
|
} else {
|
|
@@ -3821,7 +3971,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
3821
3971
|
async function createPrStack(input, onSetupLine) {
|
|
3822
3972
|
await requireAgent(input.agent);
|
|
3823
3973
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
3824
|
-
if (!
|
|
3974
|
+
if (!existsSync11(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
3825
3975
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
3826
3976
|
const status = await detectGhStack(repoPath);
|
|
3827
3977
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -3888,7 +4038,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
3888
4038
|
}
|
|
3889
4039
|
}
|
|
3890
4040
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
3891
|
-
if (!claimed.has(bootstrap.worktreePath) &&
|
|
4041
|
+
if (!claimed.has(bootstrap.worktreePath) && existsSync11(bootstrap.worktreePath)) {
|
|
3892
4042
|
try {
|
|
3893
4043
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
3894
4044
|
deleteBranch: bootstrap.branchName
|
|
@@ -3900,10 +4050,10 @@ async function createPrStack(input, onSetupLine) {
|
|
|
3900
4050
|
}
|
|
3901
4051
|
|
|
3902
4052
|
// src/diff/diff.ts
|
|
3903
|
-
import { existsSync as
|
|
3904
|
-
import { dirname as dirname3, join as
|
|
4053
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync3, readFileSync as readFileSync9, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
4054
|
+
import { dirname as dirname3, join as join11 } from "path";
|
|
3905
4055
|
async function inspectGitWorktree(worktreePath) {
|
|
3906
|
-
if (!worktreePath || !
|
|
4056
|
+
if (!worktreePath || !existsSync12(worktreePath)) return "missing_worktree";
|
|
3907
4057
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
3908
4058
|
reject: false
|
|
3909
4059
|
});
|
|
@@ -3911,7 +4061,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
3911
4061
|
return "ok";
|
|
3912
4062
|
}
|
|
3913
4063
|
async function initializeGitRepository(worktreePath) {
|
|
3914
|
-
if (!worktreePath || !
|
|
4064
|
+
if (!worktreePath || !existsSync12(worktreePath)) {
|
|
3915
4065
|
throw new Error("Worktree not found");
|
|
3916
4066
|
}
|
|
3917
4067
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -4047,11 +4197,11 @@ new file mode 100644
|
|
|
4047
4197
|
};
|
|
4048
4198
|
}
|
|
4049
4199
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
4050
|
-
const abs =
|
|
4200
|
+
const abs = join11(worktreePath, path);
|
|
4051
4201
|
try {
|
|
4052
4202
|
const st = statSync2(abs);
|
|
4053
4203
|
if (st.isFile() && st.size > maxHunk) {
|
|
4054
|
-
const buf =
|
|
4204
|
+
const buf = readFileSync9(abs).subarray(0, maxHunk);
|
|
4055
4205
|
return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
|
|
4056
4206
|
}
|
|
4057
4207
|
} catch {
|
|
@@ -4552,7 +4702,7 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
|
4552
4702
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
4553
4703
|
assertSafeRelativePath(relativePath);
|
|
4554
4704
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
4555
|
-
const abs =
|
|
4705
|
+
const abs = join11(worktreePath, relativePath);
|
|
4556
4706
|
const st = statSync2(abs);
|
|
4557
4707
|
if (!st.isFile()) {
|
|
4558
4708
|
throw new Error(`Not a file: ${relativePath}`);
|
|
@@ -4562,7 +4712,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
4562
4712
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
4563
4713
|
);
|
|
4564
4714
|
}
|
|
4565
|
-
const buf =
|
|
4715
|
+
const buf = readFileSync9(abs);
|
|
4566
4716
|
return {
|
|
4567
4717
|
path: relativePath,
|
|
4568
4718
|
contentBase64: buf.toString("base64"),
|
|
@@ -4572,12 +4722,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
4572
4722
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
4573
4723
|
assertSafeRelativePath(relativePath);
|
|
4574
4724
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
4575
|
-
const abs =
|
|
4725
|
+
const abs = join11(worktreePath, relativePath);
|
|
4576
4726
|
const st = statSync2(abs);
|
|
4577
4727
|
if (!st.isFile()) {
|
|
4578
4728
|
throw new Error(`Not a file: ${relativePath}`);
|
|
4579
4729
|
}
|
|
4580
|
-
const buf =
|
|
4730
|
+
const buf = readFileSync9(abs);
|
|
4581
4731
|
if (isImageRelativePath(relativePath)) {
|
|
4582
4732
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
4583
4733
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -4620,9 +4770,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
4620
4770
|
}
|
|
4621
4771
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
4622
4772
|
assertSafeRelativePath(relativePath);
|
|
4623
|
-
const abs =
|
|
4773
|
+
const abs = join11(worktreePath, relativePath);
|
|
4624
4774
|
mkdirSync3(dirname3(abs), { recursive: true });
|
|
4625
|
-
|
|
4775
|
+
writeFileSync5(abs, content, "utf8");
|
|
4626
4776
|
return { path: relativePath };
|
|
4627
4777
|
}
|
|
4628
4778
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -4747,9 +4897,9 @@ async function confirmLand(thread, opts) {
|
|
|
4747
4897
|
}
|
|
4748
4898
|
|
|
4749
4899
|
// src/skills/discover.ts
|
|
4750
|
-
import { existsSync as
|
|
4900
|
+
import { existsSync as existsSync13, readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
|
|
4751
4901
|
import { homedir } from "os";
|
|
4752
|
-
import { join as
|
|
4902
|
+
import { join as join12 } from "path";
|
|
4753
4903
|
|
|
4754
4904
|
// src/skills/bundled/long-running.ts
|
|
4755
4905
|
var LONG_RUNNING_SKILL_COMMAND = "long-running";
|
|
@@ -4878,7 +5028,7 @@ function parseFrontmatter(content) {
|
|
|
4878
5028
|
}
|
|
4879
5029
|
function readSkill(skillMd, source) {
|
|
4880
5030
|
try {
|
|
4881
|
-
const content =
|
|
5031
|
+
const content = readFileSync10(skillMd, "utf8");
|
|
4882
5032
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
4883
5033
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
4884
5034
|
const name = fmName || dirName;
|
|
@@ -4897,7 +5047,7 @@ function readSkill(skillMd, source) {
|
|
|
4897
5047
|
}
|
|
4898
5048
|
}
|
|
4899
5049
|
function scanSkillsDir(dir, source, out) {
|
|
4900
|
-
if (!
|
|
5050
|
+
if (!existsSync13(dir)) return;
|
|
4901
5051
|
let entries;
|
|
4902
5052
|
try {
|
|
4903
5053
|
entries = readdirSync4(dir);
|
|
@@ -4906,8 +5056,8 @@ function scanSkillsDir(dir, source, out) {
|
|
|
4906
5056
|
}
|
|
4907
5057
|
for (const entry of entries) {
|
|
4908
5058
|
if (entry.startsWith(".")) continue;
|
|
4909
|
-
const skillMd =
|
|
4910
|
-
if (!
|
|
5059
|
+
const skillMd = join12(dir, entry, "SKILL.md");
|
|
5060
|
+
if (!existsSync13(skillMd)) continue;
|
|
4911
5061
|
try {
|
|
4912
5062
|
if (!statSync3(skillMd).isFile()) continue;
|
|
4913
5063
|
} catch {
|
|
@@ -4918,7 +5068,7 @@ function scanSkillsDir(dir, source, out) {
|
|
|
4918
5068
|
}
|
|
4919
5069
|
}
|
|
4920
5070
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
4921
|
-
if (!
|
|
5071
|
+
if (!existsSync13(pluginsRoot)) return;
|
|
4922
5072
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
4923
5073
|
if (depth > 7) return;
|
|
4924
5074
|
let entries;
|
|
@@ -4928,12 +5078,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
|
|
|
4928
5078
|
return;
|
|
4929
5079
|
}
|
|
4930
5080
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
4931
|
-
const skill = readSkill(
|
|
5081
|
+
const skill = readSkill(join12(dir, "SKILL.md"), "cli");
|
|
4932
5082
|
if (skill) out.push(skill);
|
|
4933
5083
|
}
|
|
4934
5084
|
for (const entry of entries) {
|
|
4935
5085
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
4936
|
-
const full =
|
|
5086
|
+
const full = join12(dir, entry);
|
|
4937
5087
|
try {
|
|
4938
5088
|
if (!statSync3(full).isDirectory()) continue;
|
|
4939
5089
|
} catch {
|
|
@@ -4953,17 +5103,17 @@ function discoverSkills(worktreePath) {
|
|
|
4953
5103
|
const home = homedir();
|
|
4954
5104
|
const collected = [];
|
|
4955
5105
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
4956
|
-
scanSkillsDir(
|
|
5106
|
+
scanSkillsDir(join12(worktreePath, rel), "workspace", collected);
|
|
4957
5107
|
}
|
|
4958
5108
|
for (const abs of [
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
5109
|
+
join12(home, ".claude/skills"),
|
|
5110
|
+
join12(home, ".cursor/skills"),
|
|
5111
|
+
join12(home, ".sideboard/skills"),
|
|
5112
|
+
join12(home, ".brightsy/skills")
|
|
4963
5113
|
]) {
|
|
4964
5114
|
scanSkillsDir(abs, "user", collected);
|
|
4965
5115
|
}
|
|
4966
|
-
scanClaudePluginSkills(
|
|
5116
|
+
scanClaudePluginSkills(join12(home, ".claude/plugins"), collected);
|
|
4967
5117
|
collected.push(...bundledSkills());
|
|
4968
5118
|
const rank = {
|
|
4969
5119
|
workspace: 0,
|
|
@@ -4989,7 +5139,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
4989
5139
|
\u2026(truncated)` : body;
|
|
4990
5140
|
}
|
|
4991
5141
|
}
|
|
4992
|
-
const raw =
|
|
5142
|
+
const raw = readFileSync10(skillPath, "utf8");
|
|
4993
5143
|
if (raw.startsWith("---")) {
|
|
4994
5144
|
const end = raw.indexOf("\n---", 3);
|
|
4995
5145
|
if (end >= 0) {
|
|
@@ -5082,26 +5232,26 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
|
|
|
5082
5232
|
}
|
|
5083
5233
|
|
|
5084
5234
|
// src/agents/instructions.ts
|
|
5085
|
-
import { existsSync as
|
|
5086
|
-
import { join as
|
|
5235
|
+
import { existsSync as existsSync15, readFileSync as readFileSync11, statSync as statSync4 } from "fs";
|
|
5236
|
+
import { join as join14 } from "path";
|
|
5087
5237
|
|
|
5088
5238
|
// src/skills/detached-job-path.ts
|
|
5089
|
-
import { existsSync as
|
|
5090
|
-
import { dirname as dirname4, join as
|
|
5239
|
+
import { existsSync as existsSync14 } from "fs";
|
|
5240
|
+
import { dirname as dirname4, join as join13 } from "path";
|
|
5091
5241
|
import { fileURLToPath } from "url";
|
|
5092
5242
|
function packagedDetachedJobPath() {
|
|
5093
5243
|
const dir = packagedMcpDir();
|
|
5094
5244
|
if (!dir) return null;
|
|
5095
|
-
const script =
|
|
5096
|
-
return
|
|
5245
|
+
const script = join13(dir, "scripts", "detached-job.js");
|
|
5246
|
+
return existsSync14(script) ? script : null;
|
|
5097
5247
|
}
|
|
5098
5248
|
function resolveDetachedJobScript() {
|
|
5099
5249
|
const packaged = packagedDetachedJobPath();
|
|
5100
5250
|
if (packaged) return packaged;
|
|
5101
5251
|
let dir = dirname4(fileURLToPath(import.meta.url));
|
|
5102
5252
|
for (let i = 0; i < 8; i++) {
|
|
5103
|
-
const candidate =
|
|
5104
|
-
if (
|
|
5253
|
+
const candidate = join13(dir, "scripts", "detached-job.js");
|
|
5254
|
+
if (existsSync14(candidate)) return candidate;
|
|
5105
5255
|
const parent = dirname4(dir);
|
|
5106
5256
|
if (parent === dir) break;
|
|
5107
5257
|
dir = parent;
|
|
@@ -5403,8 +5553,8 @@ async function syncThreadBranchFromGit(threadId) {
|
|
|
5403
5553
|
|
|
5404
5554
|
// src/store/schedules.ts
|
|
5405
5555
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
5406
|
-
import { existsSync as
|
|
5407
|
-
import { join as
|
|
5556
|
+
import { existsSync as existsSync16, readFileSync as readFileSync12 } from "fs";
|
|
5557
|
+
import { join as join15 } from "path";
|
|
5408
5558
|
import { Cron } from "croner";
|
|
5409
5559
|
var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
|
|
5410
5560
|
var UNIT_MS = {
|
|
@@ -5414,7 +5564,7 @@ var UNIT_MS = {
|
|
|
5414
5564
|
d: 864e5
|
|
5415
5565
|
};
|
|
5416
5566
|
function schedulesPath() {
|
|
5417
|
-
return
|
|
5567
|
+
return join15(appDataDir(), "schedules.json");
|
|
5418
5568
|
}
|
|
5419
5569
|
function parseDurationMs(every) {
|
|
5420
5570
|
const m = every.trim().match(DURATION_RE);
|
|
@@ -5514,9 +5664,9 @@ function normalizeTask(raw) {
|
|
|
5514
5664
|
}
|
|
5515
5665
|
function readAll() {
|
|
5516
5666
|
const path = schedulesPath();
|
|
5517
|
-
if (!
|
|
5667
|
+
if (!existsSync16(path)) return [];
|
|
5518
5668
|
try {
|
|
5519
|
-
const parsed = JSON.parse(
|
|
5669
|
+
const parsed = JSON.parse(readFileSync12(path, "utf8"));
|
|
5520
5670
|
if (!Array.isArray(parsed)) return [];
|
|
5521
5671
|
return parsed.map((row) => {
|
|
5522
5672
|
try {
|
|
@@ -5639,7 +5789,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
5639
5789
|
${prompt}`;
|
|
5640
5790
|
}
|
|
5641
5791
|
async function defaultDeps() {
|
|
5642
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
5792
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-ZSSU3FKW.js");
|
|
5643
5793
|
const orch = getOrchestrator2();
|
|
5644
5794
|
return {
|
|
5645
5795
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -5879,7 +6029,7 @@ var Orchestrator = class {
|
|
|
5879
6029
|
}
|
|
5880
6030
|
continue;
|
|
5881
6031
|
}
|
|
5882
|
-
if (!
|
|
6032
|
+
if (!existsSync17(thread.worktreePath)) {
|
|
5883
6033
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
5884
6034
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
5885
6035
|
continue;
|
|
@@ -5898,7 +6048,7 @@ var Orchestrator = class {
|
|
|
5898
6048
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
5899
6049
|
});
|
|
5900
6050
|
}
|
|
5901
|
-
const { autoCleanupOrphansEnabled } = await import("./app-settings-
|
|
6051
|
+
const { autoCleanupOrphansEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
5902
6052
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
5903
6053
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
5904
6054
|
}
|
|
@@ -6138,7 +6288,7 @@ var Orchestrator = class {
|
|
|
6138
6288
|
}
|
|
6139
6289
|
await setup;
|
|
6140
6290
|
if (skipSetup) return;
|
|
6141
|
-
const { autoRunAfterSetupEnabled } = await import("./app-settings-
|
|
6291
|
+
const { autoRunAfterSetupEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
6142
6292
|
if (autoRunAfterSetupEnabled()) {
|
|
6143
6293
|
try {
|
|
6144
6294
|
await this.startDev(threadId);
|
|
@@ -6446,7 +6596,7 @@ var Orchestrator = class {
|
|
|
6446
6596
|
}
|
|
6447
6597
|
const isBrightsy = fresh.agent === "brightsy";
|
|
6448
6598
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
6449
|
-
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-
|
|
6599
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-VRQI3FIE.js");
|
|
6450
6600
|
const gitAuthMode = getGithubGitAuthMode();
|
|
6451
6601
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
6452
6602
|
githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
|
|
@@ -6552,7 +6702,7 @@ var Orchestrator = class {
|
|
|
6552
6702
|
if (!this.stoppedTurns.has(threadId) && this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
|
|
6553
6703
|
const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
|
|
6554
6704
|
if (sessionId) {
|
|
6555
|
-
const { recoverFinishedCursorRun } = await import("./cursor-recover-
|
|
6705
|
+
const { recoverFinishedCursorRun } = await import("./cursor-recover-L5MD6MBO.js");
|
|
6556
6706
|
for (let i = 0; i < 8; i++) {
|
|
6557
6707
|
const recovered = recoverFinishedCursorRun({
|
|
6558
6708
|
agentId: sessionId,
|
|
@@ -6942,6 +7092,15 @@ var Orchestrator = class {
|
|
|
6942
7092
|
getActiveRuns(threadRef) {
|
|
6943
7093
|
return this.requireThread(threadRef).activeRuns ?? [];
|
|
6944
7094
|
}
|
|
7095
|
+
getSetupLog(threadRef) {
|
|
7096
|
+
const thread = this.getThread(threadRef);
|
|
7097
|
+
if (!thread) return readSetupLog(threadRef);
|
|
7098
|
+
const snap = readSetupLog(thread.id);
|
|
7099
|
+
if (snap.running && !this.processes.has(`${thread.id}:setup`)) {
|
|
7100
|
+
return { ...snap, running: false };
|
|
7101
|
+
}
|
|
7102
|
+
return snap;
|
|
7103
|
+
}
|
|
6945
7104
|
async runSetup(threadRef) {
|
|
6946
7105
|
const thread = this.requireThread(threadRef);
|
|
6947
7106
|
this.assertNotGlobal(thread, "Setup");
|
|
@@ -6955,20 +7114,31 @@ var Orchestrator = class {
|
|
|
6955
7114
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6956
7115
|
kill: () => abort.abort()
|
|
6957
7116
|
});
|
|
7117
|
+
beginSetupLog(thread.id);
|
|
6958
7118
|
this.emit({ type: "setup_started", threadId: thread.id });
|
|
7119
|
+
let finished = false;
|
|
7120
|
+
const finish = (exitCode, source) => {
|
|
7121
|
+
if (finished) return;
|
|
7122
|
+
finished = true;
|
|
7123
|
+
finishSetupLog(thread.id, exitCode, source);
|
|
7124
|
+
this.emit({ type: "setup_finished", threadId: thread.id, exitCode });
|
|
7125
|
+
};
|
|
6959
7126
|
try {
|
|
6960
7127
|
const setup = await runWorkspaceSetup(
|
|
6961
7128
|
thread.repoPath,
|
|
6962
7129
|
thread.worktreePath,
|
|
6963
7130
|
(line) => {
|
|
7131
|
+
appendSetupLog(thread.id, line);
|
|
6964
7132
|
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
6965
7133
|
},
|
|
6966
7134
|
{ signal: abort.signal }
|
|
6967
7135
|
);
|
|
6968
7136
|
if (!setup.ran) {
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
);
|
|
7137
|
+
const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
|
|
7138
|
+
appendSetupLog(thread.id, line);
|
|
7139
|
+
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
7140
|
+
finish(null, null);
|
|
7141
|
+
throw new Error(line);
|
|
6972
7142
|
}
|
|
6973
7143
|
if (setup.exitCode !== 0 && setup.exitCode !== null) {
|
|
6974
7144
|
const live = readThread(thread.id);
|
|
@@ -6981,8 +7151,11 @@ var Orchestrator = class {
|
|
|
6981
7151
|
});
|
|
6982
7152
|
}
|
|
6983
7153
|
}
|
|
6984
|
-
|
|
7154
|
+
finish(setup.exitCode, setup.source);
|
|
6985
7155
|
return { exitCode: setup.exitCode, source: setup.source };
|
|
7156
|
+
} catch (err) {
|
|
7157
|
+
finish(null, null);
|
|
7158
|
+
throw err;
|
|
6986
7159
|
} finally {
|
|
6987
7160
|
this.processes.delete(key);
|
|
6988
7161
|
}
|
|
@@ -7309,7 +7482,7 @@ var Orchestrator = class {
|
|
|
7309
7482
|
updateThread(thread.id, { title: meta.title });
|
|
7310
7483
|
}
|
|
7311
7484
|
}
|
|
7312
|
-
const { autoArchiveOnMergeEnabled } = await import("./app-settings-
|
|
7485
|
+
const { autoArchiveOnMergeEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
7313
7486
|
const latest = this.requireThread(thread.id);
|
|
7314
7487
|
if (!shouldAutoArchiveOnPrMerge({
|
|
7315
7488
|
previousPrState: prevState || null,
|
|
@@ -7626,7 +7799,7 @@ var Orchestrator = class {
|
|
|
7626
7799
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
7627
7800
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
7628
7801
|
try {
|
|
7629
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
7802
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-MQYNZXUK.js");
|
|
7630
7803
|
await ensureWorkspace2(thread.repoPath);
|
|
7631
7804
|
} catch {
|
|
7632
7805
|
}
|
|
@@ -7653,7 +7826,7 @@ var Orchestrator = class {
|
|
|
7653
7826
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
7654
7827
|
} catch {
|
|
7655
7828
|
}
|
|
7656
|
-
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-
|
|
7829
|
+
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
7657
7830
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
7658
7831
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
7659
7832
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -7668,19 +7841,19 @@ var Orchestrator = class {
|
|
|
7668
7841
|
throw new Error("Thread is not archived");
|
|
7669
7842
|
}
|
|
7670
7843
|
if (isGlobalThread(thread)) {
|
|
7671
|
-
const { globalAgentCwd } = await import("./paths-
|
|
7844
|
+
const { globalAgentCwd } = await import("./paths-RRCLNSJB.js");
|
|
7672
7845
|
updateThread(thread.id, { worktreePath: globalAgentCwd() });
|
|
7673
7846
|
const restored2 = setStatus(thread.id, "idle");
|
|
7674
7847
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
7675
7848
|
return restored2;
|
|
7676
7849
|
}
|
|
7677
|
-
if (!
|
|
7850
|
+
if (!existsSync17(thread.worktreePath)) {
|
|
7678
7851
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
7679
7852
|
throw new Error(
|
|
7680
7853
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
7681
7854
|
);
|
|
7682
7855
|
}
|
|
7683
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
7856
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-PEWDAX5O.js");
|
|
7684
7857
|
const slug = thread.worktreePath.split("/").pop();
|
|
7685
7858
|
const dest = thread.worktreePath;
|
|
7686
7859
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -7790,7 +7963,7 @@ async function startOrchestration(opts) {
|
|
|
7790
7963
|
sourceRef: "default",
|
|
7791
7964
|
...createOpts
|
|
7792
7965
|
}).catch(async () => {
|
|
7793
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
7966
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-PEWDAX5O.js");
|
|
7794
7967
|
const repo = await resolveRepoRoot2(repoPath);
|
|
7795
7968
|
const def = await resolveDefaultBranch2(repo);
|
|
7796
7969
|
return orch.createThread({
|
|
@@ -7800,7 +7973,7 @@ async function startOrchestration(opts) {
|
|
|
7800
7973
|
repoPath: repo
|
|
7801
7974
|
});
|
|
7802
7975
|
});
|
|
7803
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
7976
|
+
const { updateThread: upd } = await import("./thread-store-MVQU6HPJ.js");
|
|
7804
7977
|
const updated = upd(thread.id, {
|
|
7805
7978
|
sourceType: "orchestration",
|
|
7806
7979
|
sourceRef: goal
|
|
@@ -7833,7 +8006,6 @@ export {
|
|
|
7833
8006
|
findBoardPr,
|
|
7834
8007
|
assembleHomeBoard,
|
|
7835
8008
|
HOME_BOARD_AGENT_HINT,
|
|
7836
|
-
listLinearIssues,
|
|
7837
8009
|
readTurnLive,
|
|
7838
8010
|
resolveScheduleThreadId,
|
|
7839
8011
|
listSchedules,
|