@sideboard-ai/core 0.1.86 → 0.1.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/cursor-runner.cjs +23 -13
- package/dist/agents/cursor-runner.js +2 -2
- package/dist/{agents-NDHD3VOL.js → agents-LMUFTGKF.js} +8 -8
- package/dist/{agents-HJ3Y2JN5.js → agents-ODBP7J6E.js} +9 -9
- package/dist/{app-settings-K6RFCRF6.js → app-settings-BRF7VKTQ.js} +3 -3
- package/dist/{app-settings-PEXK5VEX.js → app-settings-ZXPAB3QN.js} +2 -2
- package/dist/{caffeinate-hold-EAZNWJBE.js → caffeinate-hold-I7SG6UQR.js} +2 -2
- package/dist/{caffeinate-hold-OHAUWOA6.js → caffeinate-hold-U3QJBV67.js} +2 -2
- package/dist/{chunk-FWJYLBO6.js → chunk-3WA37BRI.js} +1 -1
- package/dist/{chunk-IGEL6M4G.js → chunk-6EZRSCIT.js} +3 -3
- package/dist/{chunk-AY53MPDE.js → chunk-6LFV4VFI.js} +15 -2
- package/dist/{chunk-OBHZKT2T.js → chunk-7D27DD2X.js} +3 -3
- package/dist/{chunk-RV6DBEDQ.js → chunk-7KDBDMNC.js} +1 -1
- package/dist/{chunk-U4RZ3IQI.js → chunk-B2KIO2SD.js} +5 -5
- package/dist/{chunk-M37RITA6.js → chunk-B4R2VB2A.js} +164 -30
- package/dist/{chunk-6K5VAPVR.js → chunk-DKHGWYWR.js} +1 -1
- package/dist/{chunk-I3FRXL7J.js → chunk-FT2SQOL4.js} +2 -2
- package/dist/{chunk-KE6QLNTJ.js → chunk-JE75QW2I.js} +58 -24
- package/dist/{chunk-7MV3RXSC.js → chunk-JL4SJ6V7.js} +137 -26
- package/dist/{chunk-7FD7COKE.js → chunk-JOF3XIEM.js} +1 -1
- package/dist/{chunk-MFF2RE3I.js → chunk-NZPGMNFC.js} +1 -1
- package/dist/{chunk-HA2QTIWN.js → chunk-OB6IRIFV.js} +5 -5
- package/dist/{chunk-HHTHF5BQ.js → chunk-QSLE4VEM.js} +4 -4
- package/dist/{chunk-4Y745GLN.js → chunk-RJLBSYUO.js} +59 -25
- package/dist/{chunk-5KLC2MWZ.js → chunk-TLPJHLLM.js} +14 -1
- package/dist/{chunk-EWKHP6DD.js → chunk-UHTNJKZX.js} +5 -5
- package/dist/{chunk-ZN4NDAHV.js → chunk-VZ2L4AEJ.js} +5 -5
- package/dist/{chunk-45U4RQ74.js → chunk-WANQFU3S.js} +3 -3
- package/dist/{chunk-6ZGTM2E7.js → chunk-ZXYWWSHZ.js} +3 -3
- package/dist/{connected-teams-BNBM7OIC.js → connected-teams-SWHJWK2A.js} +2 -2
- package/dist/{connected-teams-LSQ5TAZP.js → connected-teams-TLVKZPJP.js} +2 -2
- package/dist/{coordinator-prompt-L65MIGCV.js → coordinator-prompt-CI5SHONJ.js} +5 -5
- package/dist/{coordinator-prompt-HOMHBR2L.js → coordinator-prompt-UK5LYFN5.js} +6 -6
- package/dist/{cursor-recover-L5PNQUDT.js → cursor-recover-G34BYKL2.js} +1 -1
- package/dist/{cursor-recover-NNK7JPQM.js → cursor-recover-S5ORPW34.js} +1 -1
- package/dist/{global-workspace-MXOLTUAR.js → global-workspace-2YZ2V4I5.js} +6 -6
- package/dist/{global-workspace-VGKPYFE2.js → global-workspace-JQQLPJM5.js} +7 -7
- package/dist/index.cjs +693 -541
- package/dist/index.d.cts +43 -9
- package/dist/index.d.ts +43 -9
- package/dist/index.js +213 -253
- package/dist/mcp/run-stdio.cjs +630 -505
- package/dist/mcp/run-stdio.js +184 -225
- package/dist/{paths-VPH3ITBK.js → paths-JQM2XRAD.js} +1 -1
- package/dist/{paths-2OFB7UJG.js → paths-TZX4L5X7.js} +1 -1
- package/dist/{thread-store-BUBR24YA.js → thread-store-V7NOOXKE.js} +2 -2
- package/dist/{thread-store-XTPFCJAI.js → thread-store-XAKWCV2E.js} +2 -2
- package/dist/{workspaces-VWQ5YSND.js → workspaces-FDO5L4NI.js} +7 -7
- package/dist/{workspaces-2GZ2VNNU.js → workspaces-YWCC3WV4.js} +8 -8
- package/dist/{worktree-RFCCG23P.js → worktree-4555QBQ7.js} +4 -4
- package/dist/{worktree-WZJ3CFEN.js → worktree-7YNSJ224.js} +5 -5
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -78,10 +78,139 @@ var init_thinking_effort = __esm({
|
|
|
78
78
|
}
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
+
// src/hook/convention-setup.ts
|
|
82
|
+
function isFile(path2) {
|
|
83
|
+
try {
|
|
84
|
+
return (0, import_node_fs.statSync)(path2).isFile();
|
|
85
|
+
} catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function normPath(p) {
|
|
90
|
+
return p.replace(/\/+$/, "");
|
|
91
|
+
}
|
|
92
|
+
function findConventionSetup(worktreePath, repoPath) {
|
|
93
|
+
const roots = [
|
|
94
|
+
{ root: worktreePath, where: "worktree" }
|
|
95
|
+
];
|
|
96
|
+
if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
|
|
97
|
+
roots.push({ root: repoPath, where: "main repo" });
|
|
98
|
+
}
|
|
99
|
+
for (const { root, where } of roots) {
|
|
100
|
+
for (const relPath of CONVENTION_SETUP_RELPATHS) {
|
|
101
|
+
const absPath = (0, import_node_path.join)(root, relPath);
|
|
102
|
+
if (!(0, import_node_fs.existsSync)(absPath) || !isFile(absPath)) continue;
|
|
103
|
+
return {
|
|
104
|
+
relPath,
|
|
105
|
+
absPath,
|
|
106
|
+
command: `bash ${JSON.stringify(absPath)}`,
|
|
107
|
+
source: `${relPath} (${where})`
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
function hasConventionSetup(worktreePath, repoPath) {
|
|
114
|
+
return findConventionSetup(worktreePath, repoPath) !== null;
|
|
115
|
+
}
|
|
116
|
+
var import_node_fs, import_node_path, CONVENTION_SETUP_RELPATHS;
|
|
117
|
+
var init_convention_setup = __esm({
|
|
118
|
+
"src/hook/convention-setup.ts"() {
|
|
119
|
+
"use strict";
|
|
120
|
+
import_node_fs = require("fs");
|
|
121
|
+
import_node_path = require("path");
|
|
122
|
+
CONVENTION_SETUP_RELPATHS = [
|
|
123
|
+
"script/setup",
|
|
124
|
+
"bin/setup",
|
|
125
|
+
"scripts/setup.sh",
|
|
126
|
+
"scripts/setup"
|
|
127
|
+
];
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// src/hook/cursor-worktrees.ts
|
|
132
|
+
function loadCursorWorktreesJson(rootPath) {
|
|
133
|
+
const path2 = (0, import_node_path2.join)(rootPath, ".cursor", "worktrees.json");
|
|
134
|
+
if (!(0, import_node_fs2.existsSync)(path2)) return null;
|
|
135
|
+
try {
|
|
136
|
+
return JSON.parse((0, import_node_fs2.readFileSync)(path2, "utf8"));
|
|
137
|
+
} catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function resolveSetupSpec(config) {
|
|
142
|
+
if (process.platform === "win32") {
|
|
143
|
+
return config["setup-worktree-windows"] ?? config["setup-worktree"] ?? null;
|
|
144
|
+
}
|
|
145
|
+
return config["setup-worktree-unix"] ?? config["setup-worktree"] ?? null;
|
|
146
|
+
}
|
|
147
|
+
async function runCursorWorktreeSetup(repoPath, worktreePath, onLine) {
|
|
148
|
+
const fromWorktree = loadCursorWorktreesJson(worktreePath);
|
|
149
|
+
const fromRepo = worktreePath !== repoPath ? loadCursorWorktreesJson(repoPath) : null;
|
|
150
|
+
const config = fromWorktree ?? fromRepo;
|
|
151
|
+
if (!config) return { ran: false, exitCode: null, source: null };
|
|
152
|
+
const spec = resolveSetupSpec(config);
|
|
153
|
+
if (!spec) return { ran: false, exitCode: null, source: null };
|
|
154
|
+
const sourceLabel = fromWorktree ? ".cursor/worktrees.json (worktree)" : ".cursor/worktrees.json (main repo)";
|
|
155
|
+
const env = {
|
|
156
|
+
...process.env,
|
|
157
|
+
ROOT_WORKTREE_PATH: repoPath
|
|
158
|
+
};
|
|
159
|
+
if (process.platform === "win32") {
|
|
160
|
+
env.ROOT_WORKTREE_PATH = repoPath;
|
|
161
|
+
}
|
|
162
|
+
const commands = Array.isArray(spec) ? spec : [spec.endsWith(".sh") || spec.endsWith(".ps1") ? (0, import_node_path2.join)(
|
|
163
|
+
fromWorktree ? worktreePath : repoPath,
|
|
164
|
+
".cursor",
|
|
165
|
+
spec
|
|
166
|
+
) : spec];
|
|
167
|
+
let lastExit = 0;
|
|
168
|
+
for (const command of commands) {
|
|
169
|
+
const isScriptPath = typeof spec === "string" && (spec.endsWith(".sh") || spec.endsWith(".ps1"));
|
|
170
|
+
const shell = process.platform === "win32" ? "powershell" : "bash";
|
|
171
|
+
const args = process.platform === "win32" ? isScriptPath ? ["-File", command] : ["-Command", command] : isScriptPath ? [command] : ["-lc", command];
|
|
172
|
+
onLine?.(`[cursor setup] ${command}`);
|
|
173
|
+
const child = (0, import_execa.execa)(shell, args, {
|
|
174
|
+
cwd: worktreePath,
|
|
175
|
+
reject: false,
|
|
176
|
+
env
|
|
177
|
+
});
|
|
178
|
+
if (child.stdout && onLine) {
|
|
179
|
+
const rl = (0, import_node_readline.createInterface)({ input: child.stdout });
|
|
180
|
+
rl.on("line", onLine);
|
|
181
|
+
}
|
|
182
|
+
if (child.stderr && onLine) {
|
|
183
|
+
const rl = (0, import_node_readline.createInterface)({ input: child.stderr });
|
|
184
|
+
rl.on("line", onLine);
|
|
185
|
+
}
|
|
186
|
+
const result = await child;
|
|
187
|
+
lastExit = result.exitCode ?? null;
|
|
188
|
+
if (lastExit !== 0 && lastExit !== null) break;
|
|
189
|
+
}
|
|
190
|
+
return { ran: true, exitCode: lastExit, source: sourceLabel };
|
|
191
|
+
}
|
|
192
|
+
function hasCursorWorktreeSetup(worktreePath, repoPath) {
|
|
193
|
+
if (loadCursorWorktreesJson(worktreePath)) return true;
|
|
194
|
+
if (repoPath && repoPath !== worktreePath && loadCursorWorktreesJson(repoPath)) {
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
var import_node_fs2, import_node_path2, import_execa, import_node_readline;
|
|
200
|
+
var init_cursor_worktrees = __esm({
|
|
201
|
+
"src/hook/cursor-worktrees.ts"() {
|
|
202
|
+
"use strict";
|
|
203
|
+
import_node_fs2 = require("fs");
|
|
204
|
+
import_node_path2 = require("path");
|
|
205
|
+
import_execa = require("execa");
|
|
206
|
+
import_node_readline = require("readline");
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
|
|
81
210
|
// src/hook/settings.ts
|
|
82
211
|
function expandHome(path2) {
|
|
83
212
|
if (path2.startsWith("~/") || path2 === "~") {
|
|
84
|
-
return (0,
|
|
213
|
+
return (0, import_node_path3.join)((0, import_node_os.homedir)(), path2.slice(2));
|
|
85
214
|
}
|
|
86
215
|
return path2;
|
|
87
216
|
}
|
|
@@ -94,8 +223,8 @@ function parseAvailableIn(raw) {
|
|
|
94
223
|
return out.length ? out : void 0;
|
|
95
224
|
}
|
|
96
225
|
function parseSettingsFile(path2, source) {
|
|
97
|
-
if (!(0,
|
|
98
|
-
const raw = (0,
|
|
226
|
+
if (!(0, import_node_fs3.existsSync)(path2)) return null;
|
|
227
|
+
const raw = (0, import_node_fs3.readFileSync)(path2, "utf8");
|
|
99
228
|
const data = (0, import_smol_toml.parse)(raw);
|
|
100
229
|
const scripts = data.scripts ?? {};
|
|
101
230
|
const setup = typeof scripts.setup === "string" ? scripts.setup : void 0;
|
|
@@ -198,15 +327,15 @@ function finalizeSettings(parsed) {
|
|
|
198
327
|
};
|
|
199
328
|
}
|
|
200
329
|
function familyFiles(rootPath, source) {
|
|
201
|
-
const dir = (0,
|
|
330
|
+
const dir = (0, import_node_path3.join)(rootPath, `.${source}`);
|
|
202
331
|
return {
|
|
203
|
-
toml: (0,
|
|
204
|
-
local: (0,
|
|
332
|
+
toml: (0, import_node_path3.join)(dir, "settings.toml"),
|
|
333
|
+
local: (0, import_node_path3.join)(dir, "settings.local.toml")
|
|
205
334
|
};
|
|
206
335
|
}
|
|
207
336
|
function familyExists(rootPath, source) {
|
|
208
337
|
const files = familyFiles(rootPath, source);
|
|
209
|
-
return (0,
|
|
338
|
+
return (0, import_node_fs3.existsSync)(files.toml) || (0, import_node_fs3.existsSync)(files.local);
|
|
210
339
|
}
|
|
211
340
|
function detectFamily(rootPath) {
|
|
212
341
|
if (familyExists(rootPath, "sideboard")) return "sideboard";
|
|
@@ -225,7 +354,7 @@ function loadAnyLocal(rootPath) {
|
|
|
225
354
|
loadLocalToml(rootPath, "sideboard")
|
|
226
355
|
);
|
|
227
356
|
}
|
|
228
|
-
function
|
|
357
|
+
function normPath2(p) {
|
|
229
358
|
return p.replace(/\/+$/, "");
|
|
230
359
|
}
|
|
231
360
|
function loadRepoSettings(repoPath) {
|
|
@@ -239,11 +368,11 @@ function loadRepoSettings(repoPath) {
|
|
|
239
368
|
}
|
|
240
369
|
function loadWorkspaceSettings(worktreePath, repoPath) {
|
|
241
370
|
const wtFamily = detectFamily(worktreePath);
|
|
242
|
-
const repoFamily = repoPath &&
|
|
371
|
+
const repoFamily = repoPath && normPath2(repoPath) !== normPath2(worktreePath) ? detectFamily(repoPath) : null;
|
|
243
372
|
const wtToml = wtFamily ? loadCommittedToml(worktreePath, wtFamily) : null;
|
|
244
373
|
const repoToml = repoPath && repoFamily ? loadCommittedToml(repoPath, repoFamily) : null;
|
|
245
374
|
let merged = wtToml ?? repoToml;
|
|
246
|
-
if (repoPath &&
|
|
375
|
+
if (repoPath && normPath2(repoPath) !== normPath2(worktreePath)) {
|
|
247
376
|
merged = mergeSettings(merged, loadAnyLocal(repoPath));
|
|
248
377
|
}
|
|
249
378
|
merged = mergeSettings(merged, loadAnyLocal(worktreePath));
|
|
@@ -257,7 +386,7 @@ function hasRepoHook(repoPath) {
|
|
|
257
386
|
}
|
|
258
387
|
function hasWorkspaceHook(worktreePath, repoPath) {
|
|
259
388
|
if (hasRepoHook(worktreePath)) return true;
|
|
260
|
-
if (repoPath &&
|
|
389
|
+
if (repoPath && normPath2(repoPath) !== normPath2(worktreePath) && hasRepoHook(repoPath)) {
|
|
261
390
|
return true;
|
|
262
391
|
}
|
|
263
392
|
return false;
|
|
@@ -269,16 +398,16 @@ function settingsSourceLabel(rootPath) {
|
|
|
269
398
|
const family = detectFamily(rootPath);
|
|
270
399
|
if (!family) return null;
|
|
271
400
|
const files = familyFiles(rootPath, family);
|
|
272
|
-
if ((0,
|
|
401
|
+
if ((0, import_node_fs3.existsSync)(files.toml) && (0, import_node_fs3.existsSync)(files.local)) {
|
|
273
402
|
return `.${family}/settings.toml + local`;
|
|
274
403
|
}
|
|
275
|
-
if ((0,
|
|
404
|
+
if ((0, import_node_fs3.existsSync)(files.local)) return `.${family}/settings.local.toml`;
|
|
276
405
|
return `.${family}/settings.toml`;
|
|
277
406
|
}
|
|
278
407
|
function workspaceSettingsSourceLabel(worktreePath, repoPath) {
|
|
279
408
|
const wt = settingsSourceLabel(worktreePath);
|
|
280
409
|
if (wt) return `${wt} (worktree)`;
|
|
281
|
-
if (repoPath &&
|
|
410
|
+
if (repoPath && normPath2(repoPath) !== normPath2(worktreePath)) {
|
|
282
411
|
const repo = settingsSourceLabel(repoPath);
|
|
283
412
|
if (repo) return `${repo} (main repo)`;
|
|
284
413
|
}
|
|
@@ -286,20 +415,32 @@ function workspaceSettingsSourceLabel(worktreePath, repoPath) {
|
|
|
286
415
|
}
|
|
287
416
|
function getRepoSetupInfo(worktreePath, repoPath) {
|
|
288
417
|
const settings = loadWorkspaceSettings(worktreePath, repoPath);
|
|
418
|
+
const convention = findConventionSetup(worktreePath, repoPath);
|
|
419
|
+
const cursor = hasCursorWorktreeSetup(worktreePath, repoPath);
|
|
420
|
+
const hasSetupScript = Boolean(settings?.setup) || cursor || Boolean(convention);
|
|
421
|
+
let configLabel = workspaceSettingsSourceLabel(worktreePath, repoPath);
|
|
422
|
+
if (!settings?.setup) {
|
|
423
|
+
if (convention) configLabel = convention.source;
|
|
424
|
+
else if (cursor) {
|
|
425
|
+
configLabel = hasCursorWorktreeSetup(worktreePath) ? ".cursor/worktrees.json (worktree)" : ".cursor/worktrees.json (main repo)";
|
|
426
|
+
}
|
|
427
|
+
}
|
|
289
428
|
return {
|
|
290
|
-
hasConfig: hasWorkspaceHook(worktreePath, repoPath),
|
|
291
|
-
hasSetupScript
|
|
292
|
-
configLabel
|
|
429
|
+
hasConfig: hasWorkspaceHook(worktreePath, repoPath) || cursor || Boolean(convention),
|
|
430
|
+
hasSetupScript,
|
|
431
|
+
configLabel
|
|
293
432
|
};
|
|
294
433
|
}
|
|
295
|
-
var
|
|
434
|
+
var import_node_fs3, import_node_os, import_node_path3, import_smol_toml;
|
|
296
435
|
var init_settings = __esm({
|
|
297
436
|
"src/hook/settings.ts"() {
|
|
298
437
|
"use strict";
|
|
299
|
-
|
|
438
|
+
import_node_fs3 = require("fs");
|
|
300
439
|
import_node_os = require("os");
|
|
301
|
-
|
|
440
|
+
import_node_path3 = require("path");
|
|
302
441
|
import_smol_toml = require("smol-toml");
|
|
442
|
+
init_convention_setup();
|
|
443
|
+
init_cursor_worktrees();
|
|
303
444
|
}
|
|
304
445
|
});
|
|
305
446
|
|
|
@@ -320,67 +461,67 @@ __export(paths_exports, {
|
|
|
320
461
|
});
|
|
321
462
|
function appDataDir() {
|
|
322
463
|
const override = process.env.SIDEBOARD_APP_DATA?.trim();
|
|
323
|
-
const base = override ? override : process.platform === "darwin" ? (0,
|
|
324
|
-
(0,
|
|
464
|
+
const base = override ? override : process.platform === "darwin" ? (0, import_node_path5.join)((0, import_node_os2.homedir)(), "Library", "Application Support", "sideboard") : process.platform === "win32" ? (0, import_node_path5.join)(process.env.APPDATA ?? (0, import_node_path5.join)((0, import_node_os2.homedir)(), "AppData", "Roaming"), "sideboard") : (0, import_node_path5.join)((0, import_node_os2.homedir)(), ".local", "share", "sideboard");
|
|
465
|
+
(0, import_node_fs4.mkdirSync)(base, { recursive: true });
|
|
325
466
|
return base;
|
|
326
467
|
}
|
|
327
468
|
function threadsDir() {
|
|
328
|
-
const dir = (0,
|
|
329
|
-
(0,
|
|
469
|
+
const dir = (0, import_node_path5.join)(appDataDir(), "threads");
|
|
470
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
330
471
|
return dir;
|
|
331
472
|
}
|
|
332
473
|
function locksDir() {
|
|
333
|
-
const dir = (0,
|
|
334
|
-
(0,
|
|
474
|
+
const dir = (0, import_node_path5.join)(appDataDir(), "locks");
|
|
475
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
335
476
|
return dir;
|
|
336
477
|
}
|
|
337
478
|
function sideboardHomeDir() {
|
|
338
|
-
const dir = (0,
|
|
339
|
-
(0,
|
|
479
|
+
const dir = (0, import_node_path5.join)((0, import_node_os2.homedir)(), "sideboard");
|
|
480
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
340
481
|
return dir;
|
|
341
482
|
}
|
|
342
483
|
function sideboardReposDir() {
|
|
343
|
-
const dir = (0,
|
|
344
|
-
(0,
|
|
484
|
+
const dir = (0, import_node_path5.join)(sideboardHomeDir(), "repos");
|
|
485
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
345
486
|
return dir;
|
|
346
487
|
}
|
|
347
488
|
function sideboardWorkspacesDir() {
|
|
348
|
-
const dir = (0,
|
|
349
|
-
(0,
|
|
489
|
+
const dir = (0, import_node_path5.join)(sideboardHomeDir(), "workspaces");
|
|
490
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
350
491
|
return dir;
|
|
351
492
|
}
|
|
352
493
|
function repoSlug(repoPath) {
|
|
353
|
-
return (0,
|
|
494
|
+
return (0, import_node_path4.basename)(repoPath.replace(/\/$/, "")) || "repo";
|
|
354
495
|
}
|
|
355
496
|
function worktreesRoot(repoPath) {
|
|
356
497
|
const settings = loadRepoSettings(repoPath);
|
|
357
498
|
if (settings?.worktreesRoot) {
|
|
358
|
-
(0,
|
|
499
|
+
(0, import_node_fs4.mkdirSync)(settings.worktreesRoot, { recursive: true });
|
|
359
500
|
return settings.worktreesRoot;
|
|
360
501
|
}
|
|
361
|
-
const dir = (0,
|
|
362
|
-
(0,
|
|
502
|
+
const dir = (0, import_node_path5.join)(sideboardWorkspacesDir(), repoSlug(repoPath));
|
|
503
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
363
504
|
return dir;
|
|
364
505
|
}
|
|
365
506
|
function threadFilePath(id) {
|
|
366
|
-
return (0,
|
|
507
|
+
return (0, import_node_path5.join)(threadsDir(), `${id}.json`);
|
|
367
508
|
}
|
|
368
509
|
function threadLockPath(id) {
|
|
369
|
-
return (0,
|
|
510
|
+
return (0, import_node_path5.join)(locksDir(), `${id}.lock`);
|
|
370
511
|
}
|
|
371
512
|
function globalAgentCwd() {
|
|
372
|
-
const dir = (0,
|
|
373
|
-
(0,
|
|
513
|
+
const dir = (0, import_node_path5.join)(appDataDir(), "global");
|
|
514
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
374
515
|
return dir;
|
|
375
516
|
}
|
|
376
|
-
var
|
|
517
|
+
var import_node_path4, import_node_os2, import_node_path5, import_node_fs4;
|
|
377
518
|
var init_paths = __esm({
|
|
378
519
|
"src/store/paths.ts"() {
|
|
379
520
|
"use strict";
|
|
380
|
-
|
|
521
|
+
import_node_path4 = require("path");
|
|
381
522
|
import_node_os2 = require("os");
|
|
382
|
-
|
|
383
|
-
|
|
523
|
+
import_node_path5 = require("path");
|
|
524
|
+
import_node_fs4 = require("fs");
|
|
384
525
|
init_settings();
|
|
385
526
|
}
|
|
386
527
|
});
|
|
@@ -406,6 +547,18 @@ function wrapElectronAsNodeLaunch(file, args) {
|
|
|
406
547
|
function isStrippedElectronLaunch(command, args) {
|
|
407
548
|
return command === "/bin/sh" && Boolean(args?.[1]?.includes("ELECTRON_RUN_AS_NODE") && args[1].includes("unset"));
|
|
408
549
|
}
|
|
550
|
+
function isElectronLikeCommand(command) {
|
|
551
|
+
const name = command.trim();
|
|
552
|
+
if (!name) return false;
|
|
553
|
+
if (process.versions.electron && name === process.execPath) return true;
|
|
554
|
+
return /(?:^|[/\\])Electron(?:\.exe)?$/i.test(name) || /Sideboard\.app[/\\]/i.test(name) || /Electron\.app[/\\]/i.test(name);
|
|
555
|
+
}
|
|
556
|
+
function unwrapStrippedElectronLaunch(command, args) {
|
|
557
|
+
if (!isStrippedElectronLaunch(command, args) || !args || args.length < 4) {
|
|
558
|
+
return null;
|
|
559
|
+
}
|
|
560
|
+
return { file: args[3], args: args.slice(4) };
|
|
561
|
+
}
|
|
409
562
|
var NESTED_ELECTRON_ENV_PREFIXES, STRIP_NESTED_ELECTRON_THEN_EXEC;
|
|
410
563
|
var init_nested_electron_env = __esm({
|
|
411
564
|
"src/hook/nested-electron-env.ts"() {
|
|
@@ -422,22 +575,22 @@ var init_nested_electron_env = __esm({
|
|
|
422
575
|
|
|
423
576
|
// src/store/private-file.ts
|
|
424
577
|
function writePrivateFile(path2, contents) {
|
|
425
|
-
(0,
|
|
426
|
-
(0,
|
|
578
|
+
(0, import_node_fs5.mkdirSync)((0, import_node_path6.dirname)(path2), { recursive: true });
|
|
579
|
+
(0, import_node_fs5.writeFileSync)(path2, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
|
|
427
580
|
chmodOwnerOnly(path2);
|
|
428
581
|
}
|
|
429
582
|
function chmodOwnerOnly(path2) {
|
|
430
583
|
try {
|
|
431
|
-
(0,
|
|
584
|
+
(0, import_node_fs5.chmodSync)(path2, PRIVATE_FILE_MODE);
|
|
432
585
|
} catch {
|
|
433
586
|
}
|
|
434
587
|
}
|
|
435
|
-
var
|
|
588
|
+
var import_node_fs5, import_node_path6, PRIVATE_FILE_MODE;
|
|
436
589
|
var init_private_file = __esm({
|
|
437
590
|
"src/store/private-file.ts"() {
|
|
438
591
|
"use strict";
|
|
439
|
-
|
|
440
|
-
|
|
592
|
+
import_node_fs5 = require("fs");
|
|
593
|
+
import_node_path6 = require("path");
|
|
441
594
|
PRIVATE_FILE_MODE = 384;
|
|
442
595
|
}
|
|
443
596
|
});
|
|
@@ -529,11 +682,11 @@ function decryptEnvelope(envelope, key) {
|
|
|
529
682
|
return JSON.parse(plaintext.toString("utf8"));
|
|
530
683
|
}
|
|
531
684
|
function readSecureJson(path2) {
|
|
532
|
-
if (!(0,
|
|
685
|
+
if (!(0, import_node_fs6.existsSync)(path2)) return null;
|
|
533
686
|
chmodOwnerOnly(path2);
|
|
534
687
|
let parsed;
|
|
535
688
|
try {
|
|
536
|
-
parsed = JSON.parse((0,
|
|
689
|
+
parsed = JSON.parse((0, import_node_fs6.readFileSync)(path2, "utf8"));
|
|
537
690
|
} catch {
|
|
538
691
|
return null;
|
|
539
692
|
}
|
|
@@ -553,17 +706,17 @@ function writeSecureJson(path2, value) {
|
|
|
553
706
|
`);
|
|
554
707
|
}
|
|
555
708
|
function isSecureFileEncrypted(path2) {
|
|
556
|
-
if (!(0,
|
|
709
|
+
if (!(0, import_node_fs6.existsSync)(path2)) return false;
|
|
557
710
|
try {
|
|
558
|
-
return isEnvelope(JSON.parse((0,
|
|
711
|
+
return isEnvelope(JSON.parse((0, import_node_fs6.readFileSync)(path2, "utf8")));
|
|
559
712
|
} catch {
|
|
560
713
|
return false;
|
|
561
714
|
}
|
|
562
715
|
}
|
|
563
716
|
function secureFileUnlocksWith(path2, key) {
|
|
564
|
-
if (!(0,
|
|
717
|
+
if (!(0, import_node_fs6.existsSync)(path2) || key.length !== 32) return true;
|
|
565
718
|
try {
|
|
566
|
-
const parsed = JSON.parse((0,
|
|
719
|
+
const parsed = JSON.parse((0, import_node_fs6.readFileSync)(path2, "utf8"));
|
|
567
720
|
if (!isEnvelope(parsed)) return true;
|
|
568
721
|
decryptEnvelope(parsed, key);
|
|
569
722
|
return true;
|
|
@@ -571,13 +724,13 @@ function secureFileUnlocksWith(path2, key) {
|
|
|
571
724
|
return false;
|
|
572
725
|
}
|
|
573
726
|
}
|
|
574
|
-
var import_node_child_process, import_node_crypto,
|
|
727
|
+
var import_node_child_process, import_node_crypto, import_node_fs6, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, ALG, injectedKey;
|
|
575
728
|
var init_secure_file = __esm({
|
|
576
729
|
"src/store/secure-file.ts"() {
|
|
577
730
|
"use strict";
|
|
578
731
|
import_node_child_process = require("child_process");
|
|
579
732
|
import_node_crypto = require("crypto");
|
|
580
|
-
|
|
733
|
+
import_node_fs6 = require("fs");
|
|
581
734
|
init_private_file();
|
|
582
735
|
KEYCHAIN_SERVICE = "ai.sideboard.app";
|
|
583
736
|
KEYCHAIN_ACCOUNT = "secret-vault-v1";
|
|
@@ -588,7 +741,7 @@ var init_secure_file = __esm({
|
|
|
588
741
|
|
|
589
742
|
// src/store/secret-vault.ts
|
|
590
743
|
function secretVaultPath() {
|
|
591
|
-
return (0,
|
|
744
|
+
return (0, import_node_path7.join)(appDataDir(), "secrets.json");
|
|
592
745
|
}
|
|
593
746
|
function loadSecretVault() {
|
|
594
747
|
const parsed = readSecureJson(secretVaultPath());
|
|
@@ -632,11 +785,11 @@ function normalizeVault(raw) {
|
|
|
632
785
|
}
|
|
633
786
|
return out;
|
|
634
787
|
}
|
|
635
|
-
var
|
|
788
|
+
var import_node_path7;
|
|
636
789
|
var init_secret_vault = __esm({
|
|
637
790
|
"src/store/secret-vault.ts"() {
|
|
638
791
|
"use strict";
|
|
639
|
-
|
|
792
|
+
import_node_path7 = require("path");
|
|
640
793
|
init_paths();
|
|
641
794
|
init_secure_file();
|
|
642
795
|
}
|
|
@@ -737,10 +890,10 @@ function toPublicAppSettings(settings) {
|
|
|
737
890
|
};
|
|
738
891
|
}
|
|
739
892
|
function appSettingsPath() {
|
|
740
|
-
return (0,
|
|
893
|
+
return (0, import_node_path8.join)(appDataDir(), "settings.json");
|
|
741
894
|
}
|
|
742
895
|
function claudeUserSettingsPath() {
|
|
743
|
-
return (0,
|
|
896
|
+
return (0, import_node_path8.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
|
|
744
897
|
}
|
|
745
898
|
function normalizeClaude(raw) {
|
|
746
899
|
if (!raw || typeof raw !== "object") return {};
|
|
@@ -983,10 +1136,10 @@ function normalizeSettings(raw) {
|
|
|
983
1136
|
}
|
|
984
1137
|
function readSettingsFile() {
|
|
985
1138
|
const path2 = appSettingsPath();
|
|
986
|
-
if (!(0,
|
|
1139
|
+
if (!(0, import_node_fs7.existsSync)(path2)) return { ...EMPTY_SETTINGS };
|
|
987
1140
|
try {
|
|
988
1141
|
chmodOwnerOnly(path2);
|
|
989
|
-
const parsed = JSON.parse((0,
|
|
1142
|
+
const parsed = JSON.parse((0, import_node_fs7.readFileSync)(path2, "utf8"));
|
|
990
1143
|
return normalizeSettings(parsed);
|
|
991
1144
|
} catch {
|
|
992
1145
|
return { ...EMPTY_SETTINGS };
|
|
@@ -1546,14 +1699,14 @@ function childEnvWithAppSettings(extra) {
|
|
|
1546
1699
|
function harnessEnvKey(harness) {
|
|
1547
1700
|
return HARNESS_ENV_KEYS[harness];
|
|
1548
1701
|
}
|
|
1549
|
-
var import_node_crypto2,
|
|
1702
|
+
var import_node_crypto2, import_node_fs7, import_node_os3, import_node_path8, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
|
|
1550
1703
|
var init_app_settings = __esm({
|
|
1551
1704
|
"src/store/app-settings.ts"() {
|
|
1552
1705
|
"use strict";
|
|
1553
1706
|
import_node_crypto2 = require("crypto");
|
|
1554
|
-
|
|
1707
|
+
import_node_fs7 = require("fs");
|
|
1555
1708
|
import_node_os3 = require("os");
|
|
1556
|
-
|
|
1709
|
+
import_node_path8 = require("path");
|
|
1557
1710
|
init_thinking_effort();
|
|
1558
1711
|
init_nested_electron_env();
|
|
1559
1712
|
init_paths();
|
|
@@ -1615,7 +1768,7 @@ function setCaffeinateHoldHooks(next) {
|
|
|
1615
1768
|
hooks = next;
|
|
1616
1769
|
}
|
|
1617
1770
|
function caffeinateHoldPath() {
|
|
1618
|
-
return (0,
|
|
1771
|
+
return (0, import_node_path9.join)(appDataDir(), "caffeinate-hold.json");
|
|
1619
1772
|
}
|
|
1620
1773
|
function processAlive(pid) {
|
|
1621
1774
|
if (hooks.processAlive) return hooks.processAlive(pid);
|
|
@@ -1649,9 +1802,9 @@ function uniqueIds(ids) {
|
|
|
1649
1802
|
}
|
|
1650
1803
|
function readHold() {
|
|
1651
1804
|
const path2 = caffeinateHoldPath();
|
|
1652
|
-
if (!(0,
|
|
1805
|
+
if (!(0, import_node_fs8.existsSync)(path2)) return null;
|
|
1653
1806
|
try {
|
|
1654
|
-
const parsed = JSON.parse((0,
|
|
1807
|
+
const parsed = JSON.parse((0, import_node_fs8.readFileSync)(path2, "utf8"));
|
|
1655
1808
|
if (typeof parsed?.pid === "number" && parsed.pid > 0) {
|
|
1656
1809
|
return {
|
|
1657
1810
|
pid: parsed.pid,
|
|
@@ -1673,7 +1826,7 @@ function writeHold(pid, threadIds) {
|
|
|
1673
1826
|
}
|
|
1674
1827
|
function clearHold() {
|
|
1675
1828
|
try {
|
|
1676
|
-
(0,
|
|
1829
|
+
(0, import_node_fs8.unlinkSync)(caffeinateHoldPath());
|
|
1677
1830
|
} catch {
|
|
1678
1831
|
}
|
|
1679
1832
|
}
|
|
@@ -1758,13 +1911,13 @@ function releaseCaffeinateHoldForThread(threadId) {
|
|
|
1758
1911
|
}
|
|
1759
1912
|
return setCaffeinateHold(false, { threadId: id });
|
|
1760
1913
|
}
|
|
1761
|
-
var import_node_child_process2,
|
|
1914
|
+
var import_node_child_process2, import_node_fs8, import_node_path9, hooks;
|
|
1762
1915
|
var init_caffeinate_hold = __esm({
|
|
1763
1916
|
"src/store/caffeinate-hold.ts"() {
|
|
1764
1917
|
"use strict";
|
|
1765
1918
|
import_node_child_process2 = require("child_process");
|
|
1766
|
-
|
|
1767
|
-
|
|
1919
|
+
import_node_fs8 = require("fs");
|
|
1920
|
+
import_node_path9 = require("path");
|
|
1768
1921
|
init_paths();
|
|
1769
1922
|
init_private_file();
|
|
1770
1923
|
hooks = {};
|
|
@@ -1858,7 +2011,7 @@ function createEmptyThread(partial) {
|
|
|
1858
2011
|
}
|
|
1859
2012
|
async function withThreadLock(id, fn) {
|
|
1860
2013
|
const lockPath = threadLockPath(id);
|
|
1861
|
-
(0,
|
|
2014
|
+
(0, import_node_fs9.writeFileSync)(lockPath, "", { flag: "a" });
|
|
1862
2015
|
let release;
|
|
1863
2016
|
try {
|
|
1864
2017
|
release = await import_proper_lockfile.default.lock(lockPath, {
|
|
@@ -1872,26 +2025,26 @@ async function withThreadLock(id, fn) {
|
|
|
1872
2025
|
}
|
|
1873
2026
|
function readThread(id) {
|
|
1874
2027
|
const path2 = threadFilePath(id);
|
|
1875
|
-
if (!(0,
|
|
1876
|
-
const raw = (0,
|
|
2028
|
+
if (!(0, import_node_fs9.existsSync)(path2)) return null;
|
|
2029
|
+
const raw = (0, import_node_fs9.readFileSync)(path2, "utf8");
|
|
1877
2030
|
return normalizeThread(JSON.parse(raw));
|
|
1878
2031
|
}
|
|
1879
2032
|
function writeThread(thread) {
|
|
1880
2033
|
const path2 = threadFilePath(idPath(thread.id));
|
|
1881
2034
|
const tmp = `${path2}.${process.pid}.tmp`;
|
|
1882
2035
|
const next = { ...thread, updatedAt: nowIso() };
|
|
1883
|
-
(0,
|
|
1884
|
-
(0,
|
|
2036
|
+
(0, import_node_fs9.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
|
|
2037
|
+
(0, import_node_fs9.renameSync)(tmp, path2);
|
|
1885
2038
|
}
|
|
1886
2039
|
function idPath(id) {
|
|
1887
2040
|
return id;
|
|
1888
2041
|
}
|
|
1889
2042
|
function listThreads(opts) {
|
|
1890
|
-
const files = (0,
|
|
2043
|
+
const files = (0, import_node_fs9.readdirSync)(threadsDir()).filter((f) => f.endsWith(".json"));
|
|
1891
2044
|
const threads = files.map((f) => {
|
|
1892
2045
|
try {
|
|
1893
2046
|
return normalizeThread(
|
|
1894
|
-
JSON.parse((0,
|
|
2047
|
+
JSON.parse((0, import_node_fs9.readFileSync)(threadFilePath(f.replace(/\.json$/, "")), "utf8"))
|
|
1895
2048
|
);
|
|
1896
2049
|
} catch {
|
|
1897
2050
|
return null;
|
|
@@ -1902,11 +2055,11 @@ function listThreads(opts) {
|
|
|
1902
2055
|
}
|
|
1903
2056
|
function deleteThreadRecord(id) {
|
|
1904
2057
|
const path2 = threadFilePath(id);
|
|
1905
|
-
if ((0,
|
|
2058
|
+
if ((0, import_node_fs9.existsSync)(path2)) (0, import_node_fs9.unlinkSync)(path2);
|
|
1906
2059
|
const lock = threadLockPath(id);
|
|
1907
|
-
if ((0,
|
|
2060
|
+
if ((0, import_node_fs9.existsSync)(lock)) {
|
|
1908
2061
|
try {
|
|
1909
|
-
(0,
|
|
2062
|
+
(0, import_node_fs9.unlinkSync)(lock);
|
|
1910
2063
|
} catch {
|
|
1911
2064
|
}
|
|
1912
2065
|
}
|
|
@@ -1930,12 +2083,12 @@ function findThreadByRef(ref) {
|
|
|
1930
2083
|
const all = listThreads({ includeArchived: true });
|
|
1931
2084
|
return all.find((t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref) ?? null;
|
|
1932
2085
|
}
|
|
1933
|
-
var import_node_crypto3,
|
|
2086
|
+
var import_node_crypto3, import_node_fs9, import_proper_lockfile;
|
|
1934
2087
|
var init_thread_store = __esm({
|
|
1935
2088
|
"src/store/thread-store.ts"() {
|
|
1936
2089
|
"use strict";
|
|
1937
2090
|
import_node_crypto3 = require("crypto");
|
|
1938
|
-
|
|
2091
|
+
import_node_fs9 = require("fs");
|
|
1939
2092
|
import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
|
|
1940
2093
|
init_thinking_effort();
|
|
1941
2094
|
init_paths();
|
|
@@ -2917,17 +3070,17 @@ var init_gh_errors = __esm({
|
|
|
2917
3070
|
|
|
2918
3071
|
// src/agents/path.ts
|
|
2919
3072
|
function prependPathDir(env, dir) {
|
|
2920
|
-
if (!dir || !(0,
|
|
3073
|
+
if (!dir || !(0, import_node_fs10.existsSync)(dir)) return;
|
|
2921
3074
|
const current = env.PATH ?? "";
|
|
2922
|
-
const parts = current.split(
|
|
3075
|
+
const parts = current.split(import_node_path10.delimiter).filter(Boolean);
|
|
2923
3076
|
if (parts.includes(dir)) {
|
|
2924
3077
|
env.PATH = current;
|
|
2925
3078
|
return;
|
|
2926
3079
|
}
|
|
2927
|
-
env.PATH = [dir, ...parts].join(
|
|
3080
|
+
env.PATH = [dir, ...parts].join(import_node_path10.delimiter);
|
|
2928
3081
|
}
|
|
2929
3082
|
function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os4.homedir)()) {
|
|
2930
|
-
return (0,
|
|
3083
|
+
return (0, import_node_path10.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
|
|
2931
3084
|
}
|
|
2932
3085
|
function isConductorBundledCli(filePath) {
|
|
2933
3086
|
const p = (filePath ?? "").replace(/\\/g, "/");
|
|
@@ -2936,21 +3089,21 @@ function isConductorBundledCli(filePath) {
|
|
|
2936
3089
|
function ensureAgentPath(env = process.env) {
|
|
2937
3090
|
const home = env.HOME || env.USERPROFILE || (0, import_node_os4.homedir)();
|
|
2938
3091
|
const current = env.PATH ?? "";
|
|
2939
|
-
const parts = current.split(
|
|
3092
|
+
const parts = current.split(import_node_path10.delimiter).filter(Boolean);
|
|
2940
3093
|
const seen = new Set(parts);
|
|
2941
3094
|
const extras = [
|
|
2942
|
-
...EXTRA_BIN_DIRS.map((rel) => (0,
|
|
3095
|
+
...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path10.join)(home, rel)),
|
|
2943
3096
|
"/opt/homebrew/bin",
|
|
2944
3097
|
"/usr/local/bin",
|
|
2945
3098
|
// Keep after Homebrew/npm so a user-installed CLI still wins.
|
|
2946
3099
|
conductorBundledBinDir(home)
|
|
2947
3100
|
];
|
|
2948
3101
|
for (const dir of extras.reverse()) {
|
|
2949
|
-
if (!dir || seen.has(dir) || !(0,
|
|
3102
|
+
if (!dir || seen.has(dir) || !(0, import_node_fs10.existsSync)(dir)) continue;
|
|
2950
3103
|
parts.unshift(dir);
|
|
2951
3104
|
seen.add(dir);
|
|
2952
3105
|
}
|
|
2953
|
-
const next = parts.join(
|
|
3106
|
+
const next = parts.join(import_node_path10.delimiter);
|
|
2954
3107
|
env.PATH = next;
|
|
2955
3108
|
return next;
|
|
2956
3109
|
}
|
|
@@ -2964,7 +3117,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
|
|
|
2964
3117
|
stdio: ["ignore", "pipe", "ignore"]
|
|
2965
3118
|
}).trim().split(/\r?\n/).find(Boolean);
|
|
2966
3119
|
if (prefix) {
|
|
2967
|
-
const binDir = process.platform === "win32" ? prefix : (0,
|
|
3120
|
+
const binDir = process.platform === "win32" ? prefix : (0, import_node_path10.join)(prefix, "bin");
|
|
2968
3121
|
prependPathDir(env, binDir);
|
|
2969
3122
|
}
|
|
2970
3123
|
} catch {
|
|
@@ -2992,14 +3145,14 @@ function withExportedPath(command, pathValue) {
|
|
|
2992
3145
|
if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
|
|
2993
3146
|
return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
|
|
2994
3147
|
}
|
|
2995
|
-
var
|
|
3148
|
+
var import_node_fs10, import_node_child_process3, import_node_os4, import_node_path10, EXTRA_BIN_DIRS;
|
|
2996
3149
|
var init_path = __esm({
|
|
2997
3150
|
"src/agents/path.ts"() {
|
|
2998
3151
|
"use strict";
|
|
2999
|
-
|
|
3152
|
+
import_node_fs10 = require("fs");
|
|
3000
3153
|
import_node_child_process3 = require("child_process");
|
|
3001
3154
|
import_node_os4 = require("os");
|
|
3002
|
-
|
|
3155
|
+
import_node_path10 = require("path");
|
|
3003
3156
|
EXTRA_BIN_DIRS = [
|
|
3004
3157
|
".local/bin",
|
|
3005
3158
|
".cargo/bin",
|
|
@@ -3027,7 +3180,7 @@ __export(run_exports, {
|
|
|
3027
3180
|
async function run(file, args, opts) {
|
|
3028
3181
|
ensureAgentPath();
|
|
3029
3182
|
try {
|
|
3030
|
-
const result = await (0,
|
|
3183
|
+
const result = await (0, import_execa2.execa)(file, args, {
|
|
3031
3184
|
cwd: opts?.cwd,
|
|
3032
3185
|
env: { ...process.env, ...opts?.env },
|
|
3033
3186
|
reject: opts?.reject ?? true,
|
|
@@ -3091,11 +3244,11 @@ async function resolveGhAuthToken(cwd) {
|
|
|
3091
3244
|
const token = result.stdout.trim();
|
|
3092
3245
|
return token || null;
|
|
3093
3246
|
}
|
|
3094
|
-
var
|
|
3247
|
+
var import_execa2;
|
|
3095
3248
|
var init_run = __esm({
|
|
3096
3249
|
"src/git/run.ts"() {
|
|
3097
3250
|
"use strict";
|
|
3098
|
-
|
|
3251
|
+
import_execa2 = require("execa");
|
|
3099
3252
|
init_path();
|
|
3100
3253
|
}
|
|
3101
3254
|
});
|
|
@@ -4318,8 +4471,8 @@ function isLocalPrFetchBranch(ref) {
|
|
|
4318
4471
|
}
|
|
4319
4472
|
async function createThreadWorktree(opts) {
|
|
4320
4473
|
let branchName = `thread/${opts.slug}`;
|
|
4321
|
-
const worktreePath = (0,
|
|
4322
|
-
if ((0,
|
|
4474
|
+
const worktreePath = (0, import_node_path11.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
4475
|
+
if ((0, import_node_fs11.existsSync)(worktreePath)) {
|
|
4323
4476
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
4324
4477
|
}
|
|
4325
4478
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -4388,8 +4541,8 @@ ${add.stdout}`;
|
|
|
4388
4541
|
async function createExistingBranchWorktree(opts) {
|
|
4389
4542
|
const branchName = opts.branchName.trim();
|
|
4390
4543
|
if (!branchName) throw new Error("branch name required");
|
|
4391
|
-
const worktreePath = (0,
|
|
4392
|
-
if ((0,
|
|
4544
|
+
const worktreePath = (0, import_node_path11.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
4545
|
+
if ((0, import_node_fs11.existsSync)(worktreePath)) {
|
|
4393
4546
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
4394
4547
|
}
|
|
4395
4548
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -4677,10 +4830,10 @@ function sameRepoPath(a, b) {
|
|
|
4677
4830
|
return normalizeWorktreePath(a) === normalizeWorktreePath(b);
|
|
4678
4831
|
}
|
|
4679
4832
|
function listLocalThreadBranchSlugs(repoPath) {
|
|
4680
|
-
const refsDir = (0,
|
|
4681
|
-
if (!(0,
|
|
4833
|
+
const refsDir = (0, import_node_path11.join)(repoPath, ".git", "refs", "heads", "thread");
|
|
4834
|
+
if (!(0, import_node_fs11.existsSync)(refsDir)) return [];
|
|
4682
4835
|
try {
|
|
4683
|
-
return (0,
|
|
4836
|
+
return (0, import_node_fs11.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
|
|
4684
4837
|
} catch {
|
|
4685
4838
|
return [];
|
|
4686
4839
|
}
|
|
@@ -4688,8 +4841,8 @@ function listLocalThreadBranchSlugs(repoPath) {
|
|
|
4688
4841
|
function collectTakenTeamSlugs(repoPath) {
|
|
4689
4842
|
const taken = /* @__PURE__ */ new Set();
|
|
4690
4843
|
const root = worktreesRoot(repoPath);
|
|
4691
|
-
if ((0,
|
|
4692
|
-
for (const entry of (0,
|
|
4844
|
+
if ((0, import_node_fs11.existsSync)(root)) {
|
|
4845
|
+
for (const entry of (0, import_node_fs11.readdirSync)(root, { withFileTypes: true })) {
|
|
4693
4846
|
if (entry.isDirectory() && entry.name !== ".DS_Store") {
|
|
4694
4847
|
taken.add(normalizeTakenSlug(entry.name));
|
|
4695
4848
|
}
|
|
@@ -4710,18 +4863,18 @@ function allocateTeamSlug(repoPath) {
|
|
|
4710
4863
|
const taken = collectTakenTeamSlugs(repoPath);
|
|
4711
4864
|
for (let attempt = 0; attempt < 32; attempt++) {
|
|
4712
4865
|
const team = allocateTeamName(taken);
|
|
4713
|
-
const path2 = (0,
|
|
4714
|
-
if (!(0,
|
|
4866
|
+
const path2 = (0, import_node_path11.join)(worktreesRoot(repoPath), team.slug);
|
|
4867
|
+
if (!(0, import_node_fs11.existsSync)(path2)) return team;
|
|
4715
4868
|
taken.add(team.slug);
|
|
4716
4869
|
}
|
|
4717
4870
|
throw new Error("No available soccer team worktree directories left");
|
|
4718
4871
|
}
|
|
4719
|
-
var
|
|
4872
|
+
var import_node_fs11, import_node_path11;
|
|
4720
4873
|
var init_worktree = __esm({
|
|
4721
4874
|
"src/git/worktree.ts"() {
|
|
4722
4875
|
"use strict";
|
|
4723
|
-
|
|
4724
|
-
|
|
4876
|
+
import_node_fs11 = require("fs");
|
|
4877
|
+
import_node_path11 = require("path");
|
|
4725
4878
|
init_paths();
|
|
4726
4879
|
init_thread_store();
|
|
4727
4880
|
init_teams();
|
|
@@ -4805,7 +4958,7 @@ function coordinatorTurnReminder(opts) {
|
|
|
4805
4958
|
function ensureGlobalCoordinatorCwd(opts) {
|
|
4806
4959
|
const dir = globalAgentCwd();
|
|
4807
4960
|
try {
|
|
4808
|
-
(0,
|
|
4961
|
+
(0, import_node_fs12.mkdirSync)(dir, { recursive: true });
|
|
4809
4962
|
} catch {
|
|
4810
4963
|
return dir;
|
|
4811
4964
|
}
|
|
@@ -4813,7 +4966,7 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
4813
4966
|
let orchId = opts?.orchestratorThreadId?.trim() || "";
|
|
4814
4967
|
if (!orchId) {
|
|
4815
4968
|
try {
|
|
4816
|
-
const existing = (0,
|
|
4969
|
+
const existing = (0, import_node_fs12.readFileSync)((0, import_node_path12.join)(dir, "AGENTS.md"), "utf8");
|
|
4817
4970
|
const m = existing.match(
|
|
4818
4971
|
/YOUR orchestration thread id is `([0-9a-f-]{36})`/i
|
|
4819
4972
|
);
|
|
@@ -4855,9 +5008,9 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
4855
5008
|
"Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
|
|
4856
5009
|
].join("\n");
|
|
4857
5010
|
try {
|
|
4858
|
-
(0,
|
|
5011
|
+
(0, import_node_fs12.writeFileSync)((0, import_node_path12.join)(dir, "CLAUDE.md"), `${body}
|
|
4859
5012
|
`, "utf8");
|
|
4860
|
-
(0,
|
|
5013
|
+
(0, import_node_fs12.writeFileSync)((0, import_node_path12.join)(dir, "AGENTS.md"), `${body}
|
|
4861
5014
|
`, "utf8");
|
|
4862
5015
|
} catch {
|
|
4863
5016
|
}
|
|
@@ -4889,12 +5042,12 @@ function coordinatorSystemPrompt(opts) {
|
|
|
4889
5042
|
formatWorkspaceInventory(opts.workspaces)
|
|
4890
5043
|
].join("\n");
|
|
4891
5044
|
}
|
|
4892
|
-
var
|
|
5045
|
+
var import_node_fs12, import_node_path12, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
|
|
4893
5046
|
var init_coordinator_prompt = __esm({
|
|
4894
5047
|
"src/orchestrator/coordinator-prompt.ts"() {
|
|
4895
5048
|
"use strict";
|
|
4896
|
-
|
|
4897
|
-
|
|
5049
|
+
import_node_fs12 = require("fs");
|
|
5050
|
+
import_node_path12 = require("path");
|
|
4898
5051
|
init_worktree();
|
|
4899
5052
|
init_app_settings();
|
|
4900
5053
|
init_paths();
|
|
@@ -4915,7 +5068,7 @@ var init_coordinator_prompt = __esm({
|
|
|
4915
5068
|
"Workspaces:",
|
|
4916
5069
|
"- add_workspace / remove_workspace \u2014 register or unregister a git repo",
|
|
4917
5070
|
"Worktree threads (chats):",
|
|
4918
|
-
"- create_thread \u2014 create a worktree + chat from branch | pr | ticket; pass repoPath + parentThreadId; omit agent and model to use Sideboard Account defaults (Settings \u2192 Default agent, model & effort). If you are Codex, do not set agent=codex (nested Codex deadlocks)",
|
|
5071
|
+
"- create_thread \u2014 create a worktree + chat from branch | pr | ticket; pass repoPath + parentThreadId; omit agent and model to use Sideboard Account defaults (Settings \u2192 Default agent, model & effort). If the repo has a setup script, Sideboard runs it in the background (does not block send_to_thread). If you are Codex, do not set agent=codex (nested Codex deadlocks)",
|
|
4919
5072
|
"- fork_worktree \u2014 fork a worktree chat into a NEW git worktree + chat (transcript attached); optional agent; leave model unset (Auto) unless you have a reason. Not for orchestration chats.",
|
|
4920
5073
|
"- fork_chat \u2014 fork a worktree chat (same worktree tab) OR a Global orchestration chat (new orchestration tab); optional agent; leave model unset (Auto) unless you have a reason. Remote coordinators: use this to continue another orchestration chat on a different agent after session limits.",
|
|
4921
5074
|
"- send_to_thread \u2014 queue a prompt (start/continue a chat turn); pass force_stop: true to interrupt mid-turn / clear stale queued prompts before replacing with a new request",
|
|
@@ -4923,7 +5076,7 @@ var init_coordinator_prompt = __esm({
|
|
|
4923
5076
|
"- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
|
|
4924
5077
|
"- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
|
|
4925
5078
|
"Setup / run:",
|
|
4926
|
-
"- run_setup \u2014 re-run worktree setup",
|
|
5079
|
+
"- run_setup \u2014 re-run worktree setup (already runs automatically on create when a script exists)",
|
|
4927
5080
|
"- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
|
|
4928
5081
|
"Inspect / review / PRs:",
|
|
4929
5082
|
"- get_diff \u2014 compact diff summary",
|
|
@@ -5200,38 +5353,38 @@ __export(workspaces_exports, {
|
|
|
5200
5353
|
syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
|
|
5201
5354
|
});
|
|
5202
5355
|
function workspacesFile() {
|
|
5203
|
-
return (0,
|
|
5356
|
+
return (0, import_node_path13.join)(appDataDir(), "workspaces.json");
|
|
5204
5357
|
}
|
|
5205
5358
|
function removedWorkspacesFile() {
|
|
5206
|
-
return (0,
|
|
5359
|
+
return (0, import_node_path13.join)(appDataDir(), "removed-workspaces.json");
|
|
5207
5360
|
}
|
|
5208
5361
|
function readAll() {
|
|
5209
5362
|
const path2 = workspacesFile();
|
|
5210
|
-
if (!(0,
|
|
5363
|
+
if (!(0, import_node_fs13.existsSync)(path2)) return [];
|
|
5211
5364
|
try {
|
|
5212
|
-
const raw = JSON.parse((0,
|
|
5365
|
+
const raw = JSON.parse((0, import_node_fs13.readFileSync)(path2, "utf8"));
|
|
5213
5366
|
return Array.isArray(raw) ? raw : [];
|
|
5214
5367
|
} catch {
|
|
5215
5368
|
return [];
|
|
5216
5369
|
}
|
|
5217
5370
|
}
|
|
5218
5371
|
function writeAll(list) {
|
|
5219
|
-
(0,
|
|
5220
|
-
(0,
|
|
5372
|
+
(0, import_node_fs13.mkdirSync)(appDataDir(), { recursive: true });
|
|
5373
|
+
(0, import_node_fs13.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
|
|
5221
5374
|
}
|
|
5222
5375
|
function readRemoved() {
|
|
5223
5376
|
const path2 = removedWorkspacesFile();
|
|
5224
|
-
if (!(0,
|
|
5377
|
+
if (!(0, import_node_fs13.existsSync)(path2)) return /* @__PURE__ */ new Set();
|
|
5225
5378
|
try {
|
|
5226
|
-
const raw = JSON.parse((0,
|
|
5379
|
+
const raw = JSON.parse((0, import_node_fs13.readFileSync)(path2, "utf8"));
|
|
5227
5380
|
return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
|
|
5228
5381
|
} catch {
|
|
5229
5382
|
return /* @__PURE__ */ new Set();
|
|
5230
5383
|
}
|
|
5231
5384
|
}
|
|
5232
5385
|
function writeRemoved(paths) {
|
|
5233
|
-
(0,
|
|
5234
|
-
(0,
|
|
5386
|
+
(0, import_node_fs13.mkdirSync)(appDataDir(), { recursive: true });
|
|
5387
|
+
(0, import_node_fs13.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
|
|
5235
5388
|
}
|
|
5236
5389
|
function rememberRemoved(repoPath) {
|
|
5237
5390
|
const next = readRemoved();
|
|
@@ -5254,7 +5407,7 @@ function listWorkspaces() {
|
|
|
5254
5407
|
async function addWorkspace(repoPath) {
|
|
5255
5408
|
const root = await resolveRepoRoot(repoPath);
|
|
5256
5409
|
if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
|
|
5257
|
-
if (!(0,
|
|
5410
|
+
if (!(0, import_node_fs13.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
|
|
5258
5411
|
forgetRemoved(root);
|
|
5259
5412
|
await ensureGhPreferOrigin(root);
|
|
5260
5413
|
const current = readAll();
|
|
@@ -5262,7 +5415,7 @@ async function addWorkspace(repoPath) {
|
|
|
5262
5415
|
if (existing) return existing;
|
|
5263
5416
|
const next = {
|
|
5264
5417
|
path: root,
|
|
5265
|
-
name: (0,
|
|
5418
|
+
name: (0, import_node_path13.basename)(root),
|
|
5266
5419
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5267
5420
|
};
|
|
5268
5421
|
writeAll([...current, next]);
|
|
@@ -5284,10 +5437,10 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
5284
5437
|
if (!path2 || path2 === "/" || isGlobalRepoPath(path2) || byPath.has(path2) || removed.has(path2)) {
|
|
5285
5438
|
continue;
|
|
5286
5439
|
}
|
|
5287
|
-
if (!(0,
|
|
5440
|
+
if (!(0, import_node_fs13.existsSync)(path2)) continue;
|
|
5288
5441
|
const ws = {
|
|
5289
5442
|
path: path2,
|
|
5290
|
-
name: (0,
|
|
5443
|
+
name: (0, import_node_path13.basename)(path2),
|
|
5291
5444
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5292
5445
|
};
|
|
5293
5446
|
byPath.set(path2, ws);
|
|
@@ -5297,12 +5450,12 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
5297
5450
|
if (dirty) writeAll(next);
|
|
5298
5451
|
return next.sort((a, b) => a.name.localeCompare(b.name));
|
|
5299
5452
|
}
|
|
5300
|
-
var
|
|
5453
|
+
var import_node_fs13, import_node_path13;
|
|
5301
5454
|
var init_workspaces = __esm({
|
|
5302
5455
|
"src/store/workspaces.ts"() {
|
|
5303
5456
|
"use strict";
|
|
5304
|
-
|
|
5305
|
-
|
|
5457
|
+
import_node_fs13 = require("fs");
|
|
5458
|
+
import_node_path13 = require("path");
|
|
5306
5459
|
init_paths();
|
|
5307
5460
|
init_global_workspace();
|
|
5308
5461
|
init_worktree();
|
|
@@ -5311,32 +5464,32 @@ var init_workspaces = __esm({
|
|
|
5311
5464
|
|
|
5312
5465
|
// src/brightsy/config.ts
|
|
5313
5466
|
function brightsyConfigPath() {
|
|
5314
|
-
return (0,
|
|
5467
|
+
return (0, import_node_path14.join)((0, import_node_os5.homedir)(), ".brightsy", "config.json");
|
|
5315
5468
|
}
|
|
5316
5469
|
function loadBrightsyConfig() {
|
|
5317
5470
|
const path2 = brightsyConfigPath();
|
|
5318
|
-
if (!(0,
|
|
5471
|
+
if (!(0, import_node_fs14.existsSync)(path2)) {
|
|
5319
5472
|
throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
|
|
5320
5473
|
}
|
|
5321
|
-
const raw = JSON.parse((0,
|
|
5474
|
+
const raw = JSON.parse((0, import_node_fs14.readFileSync)(path2, "utf8"));
|
|
5322
5475
|
if (!raw.access_token || !raw.account_id) {
|
|
5323
5476
|
throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
|
|
5324
5477
|
}
|
|
5325
5478
|
return raw;
|
|
5326
5479
|
}
|
|
5327
5480
|
function saveBrightsyConfig(cfg) {
|
|
5328
|
-
(0,
|
|
5481
|
+
(0, import_node_fs14.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
|
|
5329
5482
|
`, {
|
|
5330
5483
|
mode: 384
|
|
5331
5484
|
});
|
|
5332
5485
|
}
|
|
5333
|
-
var
|
|
5486
|
+
var import_node_fs14, import_node_os5, import_node_path14;
|
|
5334
5487
|
var init_config = __esm({
|
|
5335
5488
|
"src/brightsy/config.ts"() {
|
|
5336
5489
|
"use strict";
|
|
5337
|
-
|
|
5490
|
+
import_node_fs14 = require("fs");
|
|
5338
5491
|
import_node_os5 = require("os");
|
|
5339
|
-
|
|
5492
|
+
import_node_path14 = require("path");
|
|
5340
5493
|
}
|
|
5341
5494
|
});
|
|
5342
5495
|
|
|
@@ -5439,22 +5592,22 @@ __export(connected_teams_exports, {
|
|
|
5439
5592
|
listConnectedBrightsyTeams: () => listConnectedBrightsyTeams
|
|
5440
5593
|
});
|
|
5441
5594
|
function storePath() {
|
|
5442
|
-
return (0,
|
|
5595
|
+
return (0, import_node_path15.join)(appDataDir(), "brightsy-teams.json");
|
|
5443
5596
|
}
|
|
5444
5597
|
function readStore() {
|
|
5445
5598
|
const path2 = storePath();
|
|
5446
|
-
if (!(0,
|
|
5599
|
+
if (!(0, import_node_fs15.existsSync)(path2)) return [];
|
|
5447
5600
|
try {
|
|
5448
|
-
const parsed = JSON.parse((0,
|
|
5601
|
+
const parsed = JSON.parse((0, import_node_fs15.readFileSync)(path2, "utf8"));
|
|
5449
5602
|
return Array.isArray(parsed.teams) ? parsed.teams : [];
|
|
5450
5603
|
} catch {
|
|
5451
5604
|
return [];
|
|
5452
5605
|
}
|
|
5453
5606
|
}
|
|
5454
5607
|
function writeStore(teams) {
|
|
5455
|
-
(0,
|
|
5608
|
+
(0, import_node_fs15.mkdirSync)(appDataDir(), { recursive: true });
|
|
5456
5609
|
const path2 = storePath();
|
|
5457
|
-
(0,
|
|
5610
|
+
(0, import_node_fs15.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
|
|
5458
5611
|
`, {
|
|
5459
5612
|
mode: 384
|
|
5460
5613
|
});
|
|
@@ -5616,12 +5769,12 @@ function brightsyMcpServerName(slug) {
|
|
|
5616
5769
|
const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
|
|
5617
5770
|
return `brightsy_${cleaned || "team"}`;
|
|
5618
5771
|
}
|
|
5619
|
-
var
|
|
5772
|
+
var import_node_fs15, import_node_path15;
|
|
5620
5773
|
var init_connected_teams = __esm({
|
|
5621
5774
|
"src/brightsy/connected-teams.ts"() {
|
|
5622
5775
|
"use strict";
|
|
5623
|
-
|
|
5624
|
-
|
|
5776
|
+
import_node_fs15 = require("fs");
|
|
5777
|
+
import_node_path15 = require("path");
|
|
5625
5778
|
init_paths();
|
|
5626
5779
|
init_accounts();
|
|
5627
5780
|
init_config();
|
|
@@ -6150,11 +6303,11 @@ async function syncCliForTarget(accountId) {
|
|
|
6150
6303
|
}
|
|
6151
6304
|
applyConnectedTeamToCli(team);
|
|
6152
6305
|
}
|
|
6153
|
-
var
|
|
6306
|
+
var import_node_fs16, brightsyAdapter;
|
|
6154
6307
|
var init_brightsy = __esm({
|
|
6155
6308
|
"src/agents/brightsy.ts"() {
|
|
6156
6309
|
"use strict";
|
|
6157
|
-
|
|
6310
|
+
import_node_fs16 = require("fs");
|
|
6158
6311
|
init_run();
|
|
6159
6312
|
init_connected_teams();
|
|
6160
6313
|
init_config();
|
|
@@ -6169,7 +6322,7 @@ var init_brightsy = __esm({
|
|
|
6169
6322
|
async detect() {
|
|
6170
6323
|
const brightsy = resolveAgentExecutable("brightsy");
|
|
6171
6324
|
if (brightsy !== "brightsy") {
|
|
6172
|
-
if (!(0,
|
|
6325
|
+
if (!(0, import_node_fs16.existsSync)(brightsy)) {
|
|
6173
6326
|
return {
|
|
6174
6327
|
agent: "brightsy",
|
|
6175
6328
|
installed: false,
|
|
@@ -6426,35 +6579,35 @@ function corePackageDir() {
|
|
|
6426
6579
|
try {
|
|
6427
6580
|
const url = import_meta.url;
|
|
6428
6581
|
if (typeof url === "string" && url.length > 0) {
|
|
6429
|
-
return (0,
|
|
6582
|
+
return (0, import_node_path16.dirname)((0, import_node_url.fileURLToPath)(url));
|
|
6430
6583
|
}
|
|
6431
6584
|
} catch {
|
|
6432
6585
|
}
|
|
6433
6586
|
try {
|
|
6434
|
-
const req = (0, import_node_module.createRequire)((0,
|
|
6435
|
-
return (0,
|
|
6587
|
+
const req = (0, import_node_module.createRequire)((0, import_node_path16.join)(process.cwd(), "package.json"));
|
|
6588
|
+
return (0, import_node_path16.dirname)(req.resolve("@sideboard-ai/core"));
|
|
6436
6589
|
} catch {
|
|
6437
6590
|
return process.cwd();
|
|
6438
6591
|
}
|
|
6439
6592
|
}
|
|
6440
6593
|
function findSideboardMcpJsEntry() {
|
|
6441
6594
|
const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
|
|
6442
|
-
if (override && (0,
|
|
6595
|
+
if (override && (0, import_node_fs17.existsSync)(override)) return override;
|
|
6443
6596
|
let dir = corePackageDir();
|
|
6444
6597
|
for (let i = 0; i < 10; i++) {
|
|
6445
6598
|
const candidates = [
|
|
6446
|
-
(0,
|
|
6447
|
-
(0,
|
|
6448
|
-
(0,
|
|
6449
|
-
(0,
|
|
6450
|
-
(0,
|
|
6451
|
-
(0,
|
|
6452
|
-
(0,
|
|
6599
|
+
(0, import_node_path16.join)(dir, "mcp/run-stdio.js"),
|
|
6600
|
+
(0, import_node_path16.join)(dir, "mcp/run-stdio.cjs"),
|
|
6601
|
+
(0, import_node_path16.join)(dir, "dist/mcp/run-stdio.js"),
|
|
6602
|
+
(0, import_node_path16.join)(dir, "dist/mcp/run-stdio.cjs"),
|
|
6603
|
+
(0, import_node_path16.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
6604
|
+
(0, import_node_path16.join)(dir, "packages/cli/dist/index.js"),
|
|
6605
|
+
(0, import_node_path16.join)(dir, "cli/dist/index.js")
|
|
6453
6606
|
];
|
|
6454
6607
|
for (const p of candidates) {
|
|
6455
|
-
if ((0,
|
|
6608
|
+
if ((0, import_node_fs17.existsSync)(p)) return p;
|
|
6456
6609
|
}
|
|
6457
|
-
const parent = (0,
|
|
6610
|
+
const parent = (0, import_node_path16.dirname)(dir);
|
|
6458
6611
|
if (parent === dir) break;
|
|
6459
6612
|
dir = parent;
|
|
6460
6613
|
}
|
|
@@ -6516,22 +6669,52 @@ async function buildInjectedMcpServers(opts) {
|
|
|
6516
6669
|
}
|
|
6517
6670
|
return servers;
|
|
6518
6671
|
}
|
|
6672
|
+
function shSingleQuote(value) {
|
|
6673
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
6674
|
+
}
|
|
6675
|
+
function cursorSafeMcpLaunch(command, args) {
|
|
6676
|
+
if (process.platform === "win32") {
|
|
6677
|
+
return args && args.length > 0 ? { command, args } : { command };
|
|
6678
|
+
}
|
|
6679
|
+
const unwrapped = unwrapStrippedElectronLaunch(command, args);
|
|
6680
|
+
const file = unwrapped?.file ?? command;
|
|
6681
|
+
const fileArgs = unwrapped?.args ?? args ?? [];
|
|
6682
|
+
if (!isElectronLikeCommand(file)) {
|
|
6683
|
+
return fileArgs.length > 0 ? { command: file, args: fileArgs } : { command: file };
|
|
6684
|
+
}
|
|
6685
|
+
const dir = (0, import_node_path16.join)(appDataDir(), "mcp-launch");
|
|
6686
|
+
(0, import_node_fs17.mkdirSync)(dir, { recursive: true });
|
|
6687
|
+
const wrap = (0, import_node_path16.join)(dir, "cursor-electron-as-node.sh");
|
|
6688
|
+
const execLine = [file, ...fileArgs].map(shSingleQuote).join(" ");
|
|
6689
|
+
(0, import_node_fs17.writeFileSync)(
|
|
6690
|
+
wrap,
|
|
6691
|
+
[
|
|
6692
|
+
"#!/bin/sh",
|
|
6693
|
+
"vars=`printenv | awk -F= '/^(ELECTRON_|CHROME_)/{print $1}'`",
|
|
6694
|
+
'[ -n "$vars" ] && unset $vars',
|
|
6695
|
+
"export ELECTRON_RUN_AS_NODE=1",
|
|
6696
|
+
`exec ${execLine} "$@"`,
|
|
6697
|
+
""
|
|
6698
|
+
].join("\n"),
|
|
6699
|
+
{ mode: 493 }
|
|
6700
|
+
);
|
|
6701
|
+
return { command: wrap };
|
|
6702
|
+
}
|
|
6703
|
+
function mcpSpawnEnv(env) {
|
|
6704
|
+
if (!env) return void 0;
|
|
6705
|
+
const out = { ...env };
|
|
6706
|
+
delete out.ELECTRON_RUN_AS_NODE;
|
|
6707
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
6708
|
+
}
|
|
6519
6709
|
function toCursorMcpServers(servers) {
|
|
6520
6710
|
const out = {};
|
|
6521
6711
|
for (const s of servers) {
|
|
6522
|
-
const env = s.env
|
|
6523
|
-
|
|
6524
|
-
let command = s.command;
|
|
6525
|
-
let args = s.args;
|
|
6526
|
-
if (process.platform !== "win32" && !isStrippedElectronLaunch(command, args)) {
|
|
6527
|
-
const wrapped = wrapElectronAsNodeLaunch(command, args ?? []);
|
|
6528
|
-
command = wrapped.file;
|
|
6529
|
-
args = wrapped.args;
|
|
6530
|
-
}
|
|
6712
|
+
const env = mcpSpawnEnv(s.env);
|
|
6713
|
+
const launch = cursorSafeMcpLaunch(s.command, s.args);
|
|
6531
6714
|
out[s.name] = {
|
|
6532
|
-
command,
|
|
6533
|
-
...args && args.length > 0 ? { args } : {},
|
|
6534
|
-
...env
|
|
6715
|
+
command: launch.command,
|
|
6716
|
+
...launch.args && launch.args.length > 0 ? { args: launch.args } : {},
|
|
6717
|
+
...env ? { env } : {}
|
|
6535
6718
|
};
|
|
6536
6719
|
}
|
|
6537
6720
|
return out;
|
|
@@ -6544,8 +6727,9 @@ function toCodexMcpConfigArgs(servers) {
|
|
|
6544
6727
|
if (s.args?.length) {
|
|
6545
6728
|
args.push("-c", `${prefix}.args=${JSON.stringify(s.args)}`);
|
|
6546
6729
|
}
|
|
6547
|
-
|
|
6548
|
-
|
|
6730
|
+
const env = mcpSpawnEnv(s.env);
|
|
6731
|
+
if (env) {
|
|
6732
|
+
for (const [key, value] of Object.entries(env)) {
|
|
6549
6733
|
args.push("-c", `${prefix}.env.${key}=${JSON.stringify(value)}`);
|
|
6550
6734
|
}
|
|
6551
6735
|
}
|
|
@@ -6558,11 +6742,12 @@ function toCodexMcpConfigArgs(servers) {
|
|
|
6558
6742
|
function toOpencodeMcpConfigContent(servers) {
|
|
6559
6743
|
const mcp = {};
|
|
6560
6744
|
for (const s of servers) {
|
|
6745
|
+
const env = mcpSpawnEnv(s.env);
|
|
6561
6746
|
mcp[s.name] = {
|
|
6562
6747
|
type: "local",
|
|
6563
6748
|
command: [s.command, ...s.args ?? []],
|
|
6564
6749
|
enabled: true,
|
|
6565
|
-
...
|
|
6750
|
+
...env ? { environment: env } : {}
|
|
6566
6751
|
};
|
|
6567
6752
|
}
|
|
6568
6753
|
return JSON.stringify({ mcp });
|
|
@@ -6571,28 +6756,29 @@ function writeMcpServersConfig(servers) {
|
|
|
6571
6756
|
if (servers.length === 0) return null;
|
|
6572
6757
|
const mcpServers = {};
|
|
6573
6758
|
for (const s of servers) {
|
|
6759
|
+
const env = mcpSpawnEnv(s.env);
|
|
6574
6760
|
mcpServers[s.name] = {
|
|
6575
6761
|
command: s.command,
|
|
6576
6762
|
...s.args ? { args: s.args } : {},
|
|
6577
|
-
...
|
|
6763
|
+
...env ? { env } : {}
|
|
6578
6764
|
};
|
|
6579
6765
|
}
|
|
6580
|
-
const dir = (0,
|
|
6581
|
-
const cfgPath = (0,
|
|
6582
|
-
(0,
|
|
6766
|
+
const dir = (0, import_node_fs17.mkdtempSync)((0, import_node_path16.join)((0, import_node_os6.tmpdir)(), "sideboard-mcp-"));
|
|
6767
|
+
const cfgPath = (0, import_node_path16.join)(dir, "mcp.json");
|
|
6768
|
+
(0, import_node_fs17.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
|
|
6583
6769
|
return cfgPath;
|
|
6584
6770
|
}
|
|
6585
6771
|
async function writeInjectedMcpConfig(opts) {
|
|
6586
6772
|
return writeMcpServersConfig(await buildInjectedMcpServers(opts));
|
|
6587
6773
|
}
|
|
6588
|
-
var
|
|
6774
|
+
var import_node_fs17, import_node_module, import_node_os6, import_node_path16, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
|
|
6589
6775
|
var init_injected_mcp = __esm({
|
|
6590
6776
|
"src/agents/injected-mcp.ts"() {
|
|
6591
6777
|
"use strict";
|
|
6592
|
-
|
|
6778
|
+
import_node_fs17 = require("fs");
|
|
6593
6779
|
import_node_module = require("module");
|
|
6594
6780
|
import_node_os6 = require("os");
|
|
6595
|
-
|
|
6781
|
+
import_node_path16 = require("path");
|
|
6596
6782
|
import_node_url = require("url");
|
|
6597
6783
|
init_run();
|
|
6598
6784
|
init_config();
|
|
@@ -6784,11 +6970,11 @@ function parseIssuesJson(raw) {
|
|
|
6784
6970
|
}
|
|
6785
6971
|
return [];
|
|
6786
6972
|
}
|
|
6787
|
-
var
|
|
6973
|
+
var import_node_fs18, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
|
|
6788
6974
|
var init_claude = __esm({
|
|
6789
6975
|
"src/agents/claude.ts"() {
|
|
6790
6976
|
"use strict";
|
|
6791
|
-
|
|
6977
|
+
import_node_fs18 = require("fs");
|
|
6792
6978
|
init_run();
|
|
6793
6979
|
init_app_settings();
|
|
6794
6980
|
init_claude_mcp();
|
|
@@ -6817,7 +7003,7 @@ var init_claude = __esm({
|
|
|
6817
7003
|
async detect() {
|
|
6818
7004
|
const claude = resolveClaudeExecutable();
|
|
6819
7005
|
if (claude !== "claude") {
|
|
6820
|
-
if (!(0,
|
|
7006
|
+
if (!(0, import_node_fs18.existsSync)(claude)) {
|
|
6821
7007
|
return {
|
|
6822
7008
|
agent: "claude",
|
|
6823
7009
|
installed: false,
|
|
@@ -7054,7 +7240,7 @@ async function listCodexModels() {
|
|
|
7054
7240
|
if (codex === "codex") {
|
|
7055
7241
|
const which = await run("which", ["codex"], { reject: false });
|
|
7056
7242
|
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
7057
|
-
} else if (!(0,
|
|
7243
|
+
} else if (!(0, import_node_fs19.existsSync)(codex)) {
|
|
7058
7244
|
return FALLBACK_CODEX_MODELS;
|
|
7059
7245
|
}
|
|
7060
7246
|
const listed = await run(codex, ["debug", "models"], { reject: false });
|
|
@@ -7089,12 +7275,12 @@ function usageFromCodex(usage) {
|
|
|
7089
7275
|
}
|
|
7090
7276
|
function codexConfigHasNetworkAccess() {
|
|
7091
7277
|
const candidates = [
|
|
7092
|
-
(0,
|
|
7093
|
-
(0,
|
|
7278
|
+
(0, import_node_path17.join)((0, import_node_os7.homedir)(), ".codex", "config.toml"),
|
|
7279
|
+
(0, import_node_path17.join)((0, import_node_os7.homedir)(), ".config", "codex", "config.toml")
|
|
7094
7280
|
];
|
|
7095
7281
|
for (const path2 of candidates) {
|
|
7096
|
-
if (!(0,
|
|
7097
|
-
const text3 = (0,
|
|
7282
|
+
if (!(0, import_node_fs19.existsSync)(path2)) continue;
|
|
7283
|
+
const text3 = (0, import_node_fs19.readFileSync)(path2, "utf8");
|
|
7098
7284
|
if (/network_access\s*=\s*true/.test(text3)) return true;
|
|
7099
7285
|
}
|
|
7100
7286
|
return false;
|
|
@@ -7126,21 +7312,21 @@ function asRecord(value) {
|
|
|
7126
7312
|
return void 0;
|
|
7127
7313
|
}
|
|
7128
7314
|
function codexLooksAuthenticated() {
|
|
7129
|
-
const authPath = (0,
|
|
7130
|
-
if (!(0,
|
|
7315
|
+
const authPath = (0, import_node_path17.join)((0, import_node_os7.homedir)(), ".codex", "auth.json");
|
|
7316
|
+
if (!(0, import_node_fs19.existsSync)(authPath)) return false;
|
|
7131
7317
|
try {
|
|
7132
|
-
return (0,
|
|
7318
|
+
return (0, import_node_fs19.statSync)(authPath).size > 2;
|
|
7133
7319
|
} catch {
|
|
7134
7320
|
return false;
|
|
7135
7321
|
}
|
|
7136
7322
|
}
|
|
7137
|
-
var
|
|
7323
|
+
var import_node_fs19, import_node_os7, import_node_path17, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
7138
7324
|
var init_codex = __esm({
|
|
7139
7325
|
"src/agents/codex.ts"() {
|
|
7140
7326
|
"use strict";
|
|
7141
|
-
|
|
7327
|
+
import_node_fs19 = require("fs");
|
|
7142
7328
|
import_node_os7 = require("os");
|
|
7143
|
-
|
|
7329
|
+
import_node_path17 = require("path");
|
|
7144
7330
|
init_run();
|
|
7145
7331
|
init_app_settings();
|
|
7146
7332
|
init_global_workspace();
|
|
@@ -7165,7 +7351,7 @@ var init_codex = __esm({
|
|
|
7165
7351
|
async detect() {
|
|
7166
7352
|
const codex = resolveAgentExecutable("codex");
|
|
7167
7353
|
if (codex !== "codex") {
|
|
7168
|
-
if (!(0,
|
|
7354
|
+
if (!(0, import_node_fs19.existsSync)(codex)) {
|
|
7169
7355
|
return {
|
|
7170
7356
|
agent: "codex",
|
|
7171
7357
|
installed: false,
|
|
@@ -7599,11 +7785,11 @@ function entryDir() {
|
|
|
7599
7785
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
7600
7786
|
if (cjsDir) return cjsDir;
|
|
7601
7787
|
try {
|
|
7602
|
-
return (0,
|
|
7788
|
+
return (0, import_node_path18.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
7603
7789
|
} catch {
|
|
7604
7790
|
try {
|
|
7605
7791
|
const req = (0, import_node_module2.createRequire)(process.cwd() + "/");
|
|
7606
|
-
return (0,
|
|
7792
|
+
return (0, import_node_path18.dirname)(req.resolve("@sideboard-ai/core"));
|
|
7607
7793
|
} catch {
|
|
7608
7794
|
return process.cwd();
|
|
7609
7795
|
}
|
|
@@ -7612,27 +7798,27 @@ function entryDir() {
|
|
|
7612
7798
|
function cursorRunnerPath() {
|
|
7613
7799
|
const root = entryDir();
|
|
7614
7800
|
const candidates = [
|
|
7615
|
-
(0,
|
|
7616
|
-
(0,
|
|
7801
|
+
(0, import_node_path18.join)(root, "agents", "cursor-runner.js"),
|
|
7802
|
+
(0, import_node_path18.join)(root, "agents", "cursor-runner.cjs"),
|
|
7617
7803
|
// If somehow resolved from package root instead of dist/
|
|
7618
|
-
(0,
|
|
7619
|
-
(0,
|
|
7804
|
+
(0, import_node_path18.join)(root, "dist", "agents", "cursor-runner.js"),
|
|
7805
|
+
(0, import_node_path18.join)(root, "dist", "agents", "cursor-runner.cjs"),
|
|
7620
7806
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
7621
|
-
(0,
|
|
7622
|
-
(0,
|
|
7807
|
+
(0, import_node_path18.join)(root, "cursor-runner.ts"),
|
|
7808
|
+
(0, import_node_path18.join)(root, "src", "agents", "cursor-runner.ts")
|
|
7623
7809
|
];
|
|
7624
7810
|
for (const candidate of candidates) {
|
|
7625
|
-
if ((0,
|
|
7811
|
+
if ((0, import_node_fs20.existsSync)(candidate)) return candidate;
|
|
7626
7812
|
}
|
|
7627
7813
|
return candidates[0];
|
|
7628
7814
|
}
|
|
7629
|
-
var
|
|
7815
|
+
var import_node_fs20, import_node_module2, import_node_path18, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
|
|
7630
7816
|
var init_cursor = __esm({
|
|
7631
7817
|
"src/agents/cursor.ts"() {
|
|
7632
7818
|
"use strict";
|
|
7633
|
-
|
|
7819
|
+
import_node_fs20 = require("fs");
|
|
7634
7820
|
import_node_module2 = require("module");
|
|
7635
|
-
|
|
7821
|
+
import_node_path18 = require("path");
|
|
7636
7822
|
import_node_url2 = require("url");
|
|
7637
7823
|
import_sdk = require("@cursor/sdk");
|
|
7638
7824
|
init_run();
|
|
@@ -7761,7 +7947,7 @@ async function listOpencodeModels() {
|
|
|
7761
7947
|
if (opencode === "opencode") {
|
|
7762
7948
|
const which = await run("which", ["opencode"], { reject: false });
|
|
7763
7949
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
7764
|
-
} else if (!(0,
|
|
7950
|
+
} else if (!(0, import_node_fs21.existsSync)(opencode)) {
|
|
7765
7951
|
return FALLBACK_OPENCODE_MODELS;
|
|
7766
7952
|
}
|
|
7767
7953
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -7791,11 +7977,11 @@ function usageFromOpencode(tokens) {
|
|
|
7791
7977
|
cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
|
|
7792
7978
|
};
|
|
7793
7979
|
}
|
|
7794
|
-
var
|
|
7980
|
+
var import_node_fs21, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
|
|
7795
7981
|
var init_opencode = __esm({
|
|
7796
7982
|
"src/agents/opencode.ts"() {
|
|
7797
7983
|
"use strict";
|
|
7798
|
-
|
|
7984
|
+
import_node_fs21 = require("fs");
|
|
7799
7985
|
init_run();
|
|
7800
7986
|
init_app_settings();
|
|
7801
7987
|
init_global_workspace();
|
|
@@ -7821,7 +8007,7 @@ var init_opencode = __esm({
|
|
|
7821
8007
|
async detect() {
|
|
7822
8008
|
const opencode = resolveAgentExecutable("opencode");
|
|
7823
8009
|
if (opencode !== "opencode") {
|
|
7824
|
-
if (!(0,
|
|
8010
|
+
if (!(0, import_node_fs21.existsSync)(opencode)) {
|
|
7825
8011
|
return {
|
|
7826
8012
|
agent: "opencode",
|
|
7827
8013
|
installed: false,
|
|
@@ -8618,40 +8804,40 @@ __export(plan_file_exports, {
|
|
|
8618
8804
|
writePlanFile: () => writePlanFile
|
|
8619
8805
|
});
|
|
8620
8806
|
function ensureAttachmentsGitignore2(worktreePath) {
|
|
8621
|
-
const gitignoreAbs = (0,
|
|
8622
|
-
if ((0,
|
|
8623
|
-
(0,
|
|
8624
|
-
(0,
|
|
8807
|
+
const gitignoreAbs = (0, import_node_path31.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
8808
|
+
if ((0, import_node_fs35.existsSync)(gitignoreAbs)) return;
|
|
8809
|
+
(0, import_node_fs35.mkdirSync)((0, import_node_path31.dirname)(gitignoreAbs), { recursive: true });
|
|
8810
|
+
(0, import_node_fs35.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
8625
8811
|
}
|
|
8626
8812
|
function planFileAbs(worktreePath) {
|
|
8627
|
-
return (0,
|
|
8813
|
+
return (0, import_node_path31.join)(worktreePath, PLAN_FILE_REL);
|
|
8628
8814
|
}
|
|
8629
8815
|
function readTextIfPresent2(abs) {
|
|
8630
|
-
if (!(0,
|
|
8816
|
+
if (!(0, import_node_fs35.existsSync)(abs)) return null;
|
|
8631
8817
|
try {
|
|
8632
|
-
const content = (0,
|
|
8818
|
+
const content = (0, import_node_fs35.readFileSync)(abs, "utf8");
|
|
8633
8819
|
return content.trim() ? content : null;
|
|
8634
8820
|
} catch {
|
|
8635
8821
|
return null;
|
|
8636
8822
|
}
|
|
8637
8823
|
}
|
|
8638
8824
|
function readPlanFile(worktreePath) {
|
|
8639
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
8825
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path31.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path31.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
8640
8826
|
}
|
|
8641
8827
|
function writePlanFile(worktreePath, content) {
|
|
8642
8828
|
ensureAttachmentsGitignore2(worktreePath);
|
|
8643
8829
|
const abs = planFileAbs(worktreePath);
|
|
8644
|
-
(0,
|
|
8830
|
+
(0, import_node_fs35.mkdirSync)((0, import_node_path31.dirname)(abs), { recursive: true });
|
|
8645
8831
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
8646
|
-
(0,
|
|
8832
|
+
(0, import_node_fs35.writeFileSync)(abs, body, "utf8");
|
|
8647
8833
|
return PLAN_FILE_REL;
|
|
8648
8834
|
}
|
|
8649
|
-
var
|
|
8835
|
+
var import_node_fs35, import_node_path31;
|
|
8650
8836
|
var init_plan_file = __esm({
|
|
8651
8837
|
"src/plan/plan-file.ts"() {
|
|
8652
8838
|
"use strict";
|
|
8653
|
-
|
|
8654
|
-
|
|
8839
|
+
import_node_fs35 = require("fs");
|
|
8840
|
+
import_node_path31 = require("path");
|
|
8655
8841
|
init_workspace_scratch();
|
|
8656
8842
|
init_plan_present();
|
|
8657
8843
|
init_plan_present();
|
|
@@ -8666,10 +8852,10 @@ __export(cursor_recover_exports, {
|
|
|
8666
8852
|
function recoverFinishedCursorRun(opts) {
|
|
8667
8853
|
const agentId = opts.agentId.trim();
|
|
8668
8854
|
if (!agentId) return null;
|
|
8669
|
-
const runsPath = (0,
|
|
8670
|
-
if (!(0,
|
|
8855
|
+
const runsPath = (0, import_node_path32.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
|
|
8856
|
+
if (!(0, import_node_fs36.existsSync)(runsPath)) return null;
|
|
8671
8857
|
try {
|
|
8672
|
-
const lines = (0,
|
|
8858
|
+
const lines = (0, import_node_fs36.readFileSync)(runsPath, "utf8").split("\n");
|
|
8673
8859
|
let best = null;
|
|
8674
8860
|
for (const line of lines) {
|
|
8675
8861
|
const trimmed = line.trim();
|
|
@@ -8695,12 +8881,12 @@ function recoverFinishedCursorRun(opts) {
|
|
|
8695
8881
|
return null;
|
|
8696
8882
|
}
|
|
8697
8883
|
}
|
|
8698
|
-
var
|
|
8884
|
+
var import_node_fs36, import_node_path32;
|
|
8699
8885
|
var init_cursor_recover = __esm({
|
|
8700
8886
|
"src/agents/cursor-recover.ts"() {
|
|
8701
8887
|
"use strict";
|
|
8702
|
-
|
|
8703
|
-
|
|
8888
|
+
import_node_fs36 = require("fs");
|
|
8889
|
+
import_node_path32 = require("path");
|
|
8704
8890
|
init_paths();
|
|
8705
8891
|
}
|
|
8706
8892
|
});
|
|
@@ -8753,6 +8939,7 @@ __export(index_exports, {
|
|
|
8753
8939
|
CONTEXT_KEEP_RECENT_CHARS: () => CONTEXT_KEEP_RECENT_CHARS,
|
|
8754
8940
|
CONTEXT_KEEP_RECENT_MESSAGES: () => CONTEXT_KEEP_RECENT_MESSAGES,
|
|
8755
8941
|
CONTEXT_MIN_MESSAGES: () => CONTEXT_MIN_MESSAGES,
|
|
8942
|
+
CONVENTION_SETUP_RELPATHS: () => CONVENTION_SETUP_RELPATHS,
|
|
8756
8943
|
COORDINATOR_TOOL_PLAYBOOK: () => COORDINATOR_TOOL_PLAYBOOK,
|
|
8757
8944
|
FAMOUS_SOCCER_TEAMS: () => FAMOUS_SOCCER_TEAMS,
|
|
8758
8945
|
GITHUB_GIT_AUTH_MODES: () => GITHUB_GIT_AUTH_MODES,
|
|
@@ -8914,6 +9101,7 @@ __export(index_exports, {
|
|
|
8914
9101
|
extractiveSummary: () => extractiveSummary,
|
|
8915
9102
|
fetchPrHead: () => fetchPrHead,
|
|
8916
9103
|
finalizeParts: () => finalizeParts,
|
|
9104
|
+
findConventionSetup: () => findConventionSetup,
|
|
8917
9105
|
findInvalidCacheControlTtlOrder: () => findInvalidCacheControlTtlOrder,
|
|
8918
9106
|
findOrphanWorktrees: () => findOrphanWorktrees,
|
|
8919
9107
|
findThreadByRef: () => findThreadByRef,
|
|
@@ -8985,6 +9173,7 @@ __export(index_exports, {
|
|
|
8985
9173
|
hasBakedLinearOAuth: () => hasBakedLinearOAuth,
|
|
8986
9174
|
hasBakedSlackOAuth: () => hasBakedSlackOAuth,
|
|
8987
9175
|
hasConductorHook: () => hasConductorHook,
|
|
9176
|
+
hasConventionSetup: () => hasConventionSetup,
|
|
8988
9177
|
hasCursorWorktreeSetup: () => hasCursorWorktreeSetup,
|
|
8989
9178
|
hasRepoHook: () => hasRepoHook,
|
|
8990
9179
|
hasWorkspaceHook: () => hasWorkspaceHook,
|
|
@@ -9160,10 +9349,12 @@ __export(index_exports, {
|
|
|
9160
9349
|
run: () => run,
|
|
9161
9350
|
runArchiveScript: () => runArchiveScript,
|
|
9162
9351
|
runCloudConnect: () => runCloudConnect,
|
|
9352
|
+
runConventionSetup: () => runConventionSetup,
|
|
9163
9353
|
runCursorWorktreeSetup: () => runCursorWorktreeSetup,
|
|
9164
9354
|
runSetupScript: () => runSetupScript,
|
|
9165
9355
|
runSlackListen: () => runSlackListen,
|
|
9166
9356
|
runSlackRelayClient: () => runSlackRelayClient,
|
|
9357
|
+
runWorkspaceSetup: () => runWorkspaceSetup,
|
|
9167
9358
|
sameWorktreePath: () => sameWorktreePath,
|
|
9168
9359
|
sanitizeMcpServerName: () => sanitizeMcpServerName,
|
|
9169
9360
|
saveAppSettings: () => saveAppSettings,
|
|
@@ -10009,8 +10200,8 @@ async function listIssues(repoPath) {
|
|
|
10009
10200
|
init_agents();
|
|
10010
10201
|
|
|
10011
10202
|
// src/agents/spawn.ts
|
|
10012
|
-
var
|
|
10013
|
-
var
|
|
10203
|
+
var import_node_readline2 = require("readline");
|
|
10204
|
+
var import_execa3 = require("execa");
|
|
10014
10205
|
init_worktree();
|
|
10015
10206
|
init_git_auth_mode();
|
|
10016
10207
|
init_app_settings();
|
|
@@ -10286,7 +10477,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
10286
10477
|
const detail = err instanceof Error ? err.message : String(err);
|
|
10287
10478
|
console.warn(`[sideboard] git auth env failed (${thread.worktreePath}): ${detail}`);
|
|
10288
10479
|
}
|
|
10289
|
-
const child = (0,
|
|
10480
|
+
const child = (0, import_execa3.execa)(cmd.file, cmd.args, {
|
|
10290
10481
|
cwd: cmd.cwd,
|
|
10291
10482
|
env,
|
|
10292
10483
|
reject: false,
|
|
@@ -10306,7 +10497,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
10306
10497
|
let usage = null;
|
|
10307
10498
|
const consume = (stream, kind) => {
|
|
10308
10499
|
if (!stream) return;
|
|
10309
|
-
const rl = (0,
|
|
10500
|
+
const rl = (0, import_node_readline2.createInterface)({ input: stream, crlfDelay: Infinity });
|
|
10310
10501
|
rl.on("line", (line) => {
|
|
10311
10502
|
if (kind === "stderr") {
|
|
10312
10503
|
onEvent({ type: "stderr", data: line });
|
|
@@ -10373,11 +10564,11 @@ init_usage();
|
|
|
10373
10564
|
init_claude_mcp();
|
|
10374
10565
|
|
|
10375
10566
|
// src/agents/instructions.ts
|
|
10376
|
-
var
|
|
10377
|
-
var
|
|
10567
|
+
var import_node_fs22 = require("fs");
|
|
10568
|
+
var import_node_path19 = require("path");
|
|
10378
10569
|
init_git_auth_mode();
|
|
10379
10570
|
init_worktree_labels();
|
|
10380
|
-
function
|
|
10571
|
+
function normPath3(p) {
|
|
10381
10572
|
return p.replace(/\/+$/, "");
|
|
10382
10573
|
}
|
|
10383
10574
|
function formatRenameBranchDirective(thread, opts) {
|
|
@@ -10398,8 +10589,8 @@ function formatRenameBranchDirective(thread, opts) {
|
|
|
10398
10589
|
return lines.join("\n");
|
|
10399
10590
|
}
|
|
10400
10591
|
function formatWorktreeDirective(thread, opts) {
|
|
10401
|
-
const worktree =
|
|
10402
|
-
const repo =
|
|
10592
|
+
const worktree = normPath3(thread.worktreePath);
|
|
10593
|
+
const repo = normPath3(thread.repoPath);
|
|
10403
10594
|
const dir = worktreeNameFromPath(thread.worktreePath);
|
|
10404
10595
|
const lines = [
|
|
10405
10596
|
"Sideboard workspace (mandatory):",
|
|
@@ -10544,11 +10735,11 @@ function loadAgentInstructions(worktreePath, agent) {
|
|
|
10544
10735
|
const out = [];
|
|
10545
10736
|
for (const rel of candidates) {
|
|
10546
10737
|
if (seenPaths.has(rel)) continue;
|
|
10547
|
-
const abs = (0,
|
|
10548
|
-
if (!(0,
|
|
10738
|
+
const abs = (0, import_node_path19.join)(worktreePath, rel);
|
|
10739
|
+
if (!(0, import_node_fs22.existsSync)(abs)) continue;
|
|
10549
10740
|
try {
|
|
10550
|
-
if (!(0,
|
|
10551
|
-
let content = (0,
|
|
10741
|
+
if (!(0, import_node_fs22.statSync)(abs).isFile()) continue;
|
|
10742
|
+
let content = (0, import_node_fs22.readFileSync)(abs, "utf8");
|
|
10552
10743
|
if (!content.trim()) continue;
|
|
10553
10744
|
if (content.length > MAX_CHARS_PER_FILE) {
|
|
10554
10745
|
content = `${content.slice(0, MAX_CHARS_PER_FILE)}
|
|
@@ -10630,13 +10821,15 @@ async function requireAgent(agent, opts) {
|
|
|
10630
10821
|
init_settings();
|
|
10631
10822
|
|
|
10632
10823
|
// src/hook/conductor.ts
|
|
10633
|
-
var
|
|
10824
|
+
var import_node_fs23 = require("fs");
|
|
10634
10825
|
var import_node_net = require("net");
|
|
10635
|
-
var
|
|
10636
|
-
var
|
|
10637
|
-
var
|
|
10826
|
+
var import_node_path20 = require("path");
|
|
10827
|
+
var import_execa4 = require("execa");
|
|
10828
|
+
var import_node_readline3 = require("readline");
|
|
10638
10829
|
init_settings();
|
|
10639
10830
|
init_nested_electron_env();
|
|
10831
|
+
init_convention_setup();
|
|
10832
|
+
init_cursor_worktrees();
|
|
10640
10833
|
init_git_auth_mode();
|
|
10641
10834
|
init_nested_electron_env();
|
|
10642
10835
|
var PORT_RANGE_SIZE = 10;
|
|
@@ -10645,9 +10838,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
10645
10838
|
return new RegExp(`^${escaped}$`).test(name);
|
|
10646
10839
|
}
|
|
10647
10840
|
function readWorktreeInclude(repoPath) {
|
|
10648
|
-
const path2 = (0,
|
|
10649
|
-
if (!(0,
|
|
10650
|
-
return (0,
|
|
10841
|
+
const path2 = (0, import_node_path20.join)(repoPath, ".worktreeinclude");
|
|
10842
|
+
if (!(0, import_node_fs23.existsSync)(path2)) return [];
|
|
10843
|
+
return (0, import_node_fs23.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
10651
10844
|
}
|
|
10652
10845
|
function resolveFilesToCopy(repoPath) {
|
|
10653
10846
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -10657,10 +10850,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
10657
10850
|
if (settings?.fileIncludeGlobs?.length) {
|
|
10658
10851
|
const matched = [];
|
|
10659
10852
|
try {
|
|
10660
|
-
for (const entry of (0,
|
|
10853
|
+
for (const entry of (0, import_node_fs23.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
10661
10854
|
if (!entry.isFile()) continue;
|
|
10662
10855
|
for (const glob of settings.fileIncludeGlobs) {
|
|
10663
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
10856
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path20.basename)(glob), entry.name)) {
|
|
10664
10857
|
matched.push(entry.name);
|
|
10665
10858
|
break;
|
|
10666
10859
|
}
|
|
@@ -10672,7 +10865,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
10672
10865
|
}
|
|
10673
10866
|
const defaults = [];
|
|
10674
10867
|
try {
|
|
10675
|
-
for (const entry of (0,
|
|
10868
|
+
for (const entry of (0, import_node_fs23.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
10676
10869
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
10677
10870
|
defaults.push(entry.name);
|
|
10678
10871
|
}
|
|
@@ -10686,11 +10879,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
10686
10879
|
const patterns = resolveFilesToCopy(repoPath);
|
|
10687
10880
|
const copied = [];
|
|
10688
10881
|
for (const rel of patterns) {
|
|
10689
|
-
const src = (0,
|
|
10690
|
-
if (!(0,
|
|
10691
|
-
const dest = (0,
|
|
10692
|
-
(0,
|
|
10693
|
-
(0,
|
|
10882
|
+
const src = (0, import_node_path20.join)(repoPath, rel);
|
|
10883
|
+
if (!(0, import_node_fs23.existsSync)(src)) continue;
|
|
10884
|
+
const dest = (0, import_node_path20.join)(worktreePath, rel);
|
|
10885
|
+
(0, import_node_fs23.mkdirSync)((0, import_node_path20.dirname)(dest), { recursive: true });
|
|
10886
|
+
(0, import_node_fs23.copyFileSync)(src, dest);
|
|
10694
10887
|
copied.push(rel);
|
|
10695
10888
|
}
|
|
10696
10889
|
return copied;
|
|
@@ -10700,7 +10893,7 @@ async function captureLoginEnv() {
|
|
|
10700
10893
|
if (cachedLoginEnv) return { ...cachedLoginEnv };
|
|
10701
10894
|
const shell = process.env.SHELL?.trim() || (process.platform === "darwin" ? "/bin/zsh" : "/bin/bash");
|
|
10702
10895
|
try {
|
|
10703
|
-
const result = await (0,
|
|
10896
|
+
const result = await (0, import_execa4.execa)(shell, ["-l", "-c", "env -0"], {
|
|
10704
10897
|
reject: false,
|
|
10705
10898
|
timeout: 5e3
|
|
10706
10899
|
});
|
|
@@ -10726,7 +10919,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
10726
10919
|
const env = stripNestedElectronEnv({
|
|
10727
10920
|
...baseEnv ?? process.env
|
|
10728
10921
|
});
|
|
10729
|
-
const name = opts.workspaceName ?? (0,
|
|
10922
|
+
const name = opts.workspaceName ?? (0, import_node_path20.basename)(opts.worktreePath);
|
|
10730
10923
|
const ports = opts.ports ?? [];
|
|
10731
10924
|
const primary = ports[0];
|
|
10732
10925
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -10753,7 +10946,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
10753
10946
|
}
|
|
10754
10947
|
function pipeLines(stream, onLine) {
|
|
10755
10948
|
if (!stream || !onLine) return;
|
|
10756
|
-
const rl = (0,
|
|
10949
|
+
const rl = (0, import_node_readline3.createInterface)({ input: stream });
|
|
10757
10950
|
rl.on("line", onLine);
|
|
10758
10951
|
}
|
|
10759
10952
|
function killScriptTree(child, ports = []) {
|
|
@@ -10761,7 +10954,7 @@ function killScriptTree(child, ports = []) {
|
|
|
10761
10954
|
if (pid) {
|
|
10762
10955
|
try {
|
|
10763
10956
|
if (process.platform === "win32") {
|
|
10764
|
-
void (0,
|
|
10957
|
+
void (0, import_execa4.execa)("taskkill", ["/pid", String(pid), "/T", "/F"], { reject: false });
|
|
10765
10958
|
} else {
|
|
10766
10959
|
process.kill(-pid, "SIGTERM");
|
|
10767
10960
|
setTimeout(() => {
|
|
@@ -10781,7 +10974,7 @@ function killScriptTree(child, ports = []) {
|
|
|
10781
10974
|
for (const port of ports) {
|
|
10782
10975
|
if (!Number.isFinite(port) || port <= 0) continue;
|
|
10783
10976
|
if (process.platform === "win32") {
|
|
10784
|
-
void (0,
|
|
10977
|
+
void (0, import_execa4.execa)(
|
|
10785
10978
|
"powershell",
|
|
10786
10979
|
[
|
|
10787
10980
|
"-NoProfile",
|
|
@@ -10791,7 +10984,7 @@ function killScriptTree(child, ports = []) {
|
|
|
10791
10984
|
{ reject: false }
|
|
10792
10985
|
);
|
|
10793
10986
|
} else {
|
|
10794
|
-
void (0,
|
|
10987
|
+
void (0, import_execa4.execa)(
|
|
10795
10988
|
"zsh",
|
|
10796
10989
|
["-lc", `pids=$(lsof -tiTCP:${port} -sTCP:LISTEN 2>/dev/null); [ -n "$pids" ] && kill -TERM $pids 2>/dev/null; true`],
|
|
10797
10990
|
{ reject: false }
|
|
@@ -10816,7 +11009,7 @@ async function spawnWorkspaceScript(command, opts) {
|
|
|
10816
11009
|
} catch {
|
|
10817
11010
|
}
|
|
10818
11011
|
const shell = process.platform === "darwin" ? "zsh" : "bash";
|
|
10819
|
-
const child = (0,
|
|
11012
|
+
const child = (0, import_execa4.execa)(shell, ["-lc", command], {
|
|
10820
11013
|
cwd: opts.worktreePath,
|
|
10821
11014
|
reject: false,
|
|
10822
11015
|
env,
|
|
@@ -10834,6 +11027,14 @@ async function spawnWorkspaceScript(command, opts) {
|
|
|
10834
11027
|
child
|
|
10835
11028
|
};
|
|
10836
11029
|
}
|
|
11030
|
+
async function attachAbort(handle, signal) {
|
|
11031
|
+
if (signal) {
|
|
11032
|
+
const onAbort = () => handle.kill();
|
|
11033
|
+
if (signal.aborted) onAbort();
|
|
11034
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
11035
|
+
}
|
|
11036
|
+
return handle.done;
|
|
11037
|
+
}
|
|
10837
11038
|
async function runSetupScript(repoPath, worktreePath, onLine, opts) {
|
|
10838
11039
|
const settings = loadWorkspaceSettings(worktreePath, repoPath);
|
|
10839
11040
|
if (!settings?.setup) return { ran: false, exitCode: null, source: null };
|
|
@@ -10843,12 +11044,7 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
|
|
|
10843
11044
|
defaultBranch: opts?.defaultBranch,
|
|
10844
11045
|
onLine
|
|
10845
11046
|
});
|
|
10846
|
-
|
|
10847
|
-
const onAbort = () => handle.kill();
|
|
10848
|
-
if (opts.signal.aborted) onAbort();
|
|
10849
|
-
else opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
10850
|
-
}
|
|
10851
|
-
const exitCode = await handle.done;
|
|
11047
|
+
const exitCode = await attachAbort(handle, opts?.signal);
|
|
10852
11048
|
return {
|
|
10853
11049
|
ran: true,
|
|
10854
11050
|
exitCode,
|
|
@@ -10856,6 +11052,34 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
|
|
|
10856
11052
|
kill: handle.kill
|
|
10857
11053
|
};
|
|
10858
11054
|
}
|
|
11055
|
+
async function runConventionSetup(repoPath, worktreePath, onLine, opts) {
|
|
11056
|
+
const found = findConventionSetup(worktreePath, repoPath);
|
|
11057
|
+
if (!found) return { ran: false, exitCode: null, source: null };
|
|
11058
|
+
onLine?.(`[setup] ${found.source}`);
|
|
11059
|
+
const handle = await spawnWorkspaceScript(found.command, {
|
|
11060
|
+
worktreePath,
|
|
11061
|
+
repoPath,
|
|
11062
|
+
defaultBranch: opts?.defaultBranch,
|
|
11063
|
+
onLine
|
|
11064
|
+
});
|
|
11065
|
+
const exitCode = await attachAbort(handle, opts?.signal);
|
|
11066
|
+
return {
|
|
11067
|
+
ran: true,
|
|
11068
|
+
exitCode,
|
|
11069
|
+
source: found.source,
|
|
11070
|
+
kill: handle.kill
|
|
11071
|
+
};
|
|
11072
|
+
}
|
|
11073
|
+
async function runWorkspaceSetup(repoPath, worktreePath, onLine, opts) {
|
|
11074
|
+
let setup = await runSetupScript(repoPath, worktreePath, onLine, opts);
|
|
11075
|
+
if (!setup.ran) {
|
|
11076
|
+
setup = await runCursorWorktreeSetup(repoPath, worktreePath, onLine);
|
|
11077
|
+
}
|
|
11078
|
+
if (!setup.ran) {
|
|
11079
|
+
setup = await runConventionSetup(repoPath, worktreePath, onLine, opts);
|
|
11080
|
+
}
|
|
11081
|
+
return setup;
|
|
11082
|
+
}
|
|
10859
11083
|
async function runArchiveScript(repoPath, worktreePath, onLine) {
|
|
10860
11084
|
const settings = loadWorkspaceSettings(worktreePath, repoPath);
|
|
10861
11085
|
if (!settings?.archive) return { ran: false, exitCode: null };
|
|
@@ -10948,86 +11172,17 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
10948
11172
|
};
|
|
10949
11173
|
}
|
|
10950
11174
|
|
|
10951
|
-
// src/
|
|
10952
|
-
|
|
10953
|
-
|
|
10954
|
-
var import_execa4 = require("execa");
|
|
10955
|
-
var import_node_readline3 = require("readline");
|
|
10956
|
-
function loadCursorWorktreesJson(rootPath) {
|
|
10957
|
-
const path2 = (0, import_node_path19.join)(rootPath, ".cursor", "worktrees.json");
|
|
10958
|
-
if (!(0, import_node_fs22.existsSync)(path2)) return null;
|
|
10959
|
-
try {
|
|
10960
|
-
return JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf8"));
|
|
10961
|
-
} catch {
|
|
10962
|
-
return null;
|
|
10963
|
-
}
|
|
10964
|
-
}
|
|
10965
|
-
function resolveSetupSpec(config) {
|
|
10966
|
-
if (process.platform === "win32") {
|
|
10967
|
-
return config["setup-worktree-windows"] ?? config["setup-worktree"] ?? null;
|
|
10968
|
-
}
|
|
10969
|
-
return config["setup-worktree-unix"] ?? config["setup-worktree"] ?? null;
|
|
10970
|
-
}
|
|
10971
|
-
async function runCursorWorktreeSetup(repoPath, worktreePath, onLine) {
|
|
10972
|
-
const fromWorktree = loadCursorWorktreesJson(worktreePath);
|
|
10973
|
-
const fromRepo = worktreePath !== repoPath ? loadCursorWorktreesJson(repoPath) : null;
|
|
10974
|
-
const config = fromWorktree ?? fromRepo;
|
|
10975
|
-
if (!config) return { ran: false, exitCode: null, source: null };
|
|
10976
|
-
const spec = resolveSetupSpec(config);
|
|
10977
|
-
if (!spec) return { ran: false, exitCode: null, source: null };
|
|
10978
|
-
const sourceLabel = fromWorktree ? ".cursor/worktrees.json (worktree)" : ".cursor/worktrees.json (main repo)";
|
|
10979
|
-
const env = {
|
|
10980
|
-
...process.env,
|
|
10981
|
-
ROOT_WORKTREE_PATH: repoPath
|
|
10982
|
-
};
|
|
10983
|
-
if (process.platform === "win32") {
|
|
10984
|
-
env.ROOT_WORKTREE_PATH = repoPath;
|
|
10985
|
-
}
|
|
10986
|
-
const commands = Array.isArray(spec) ? spec : [spec.endsWith(".sh") || spec.endsWith(".ps1") ? (0, import_node_path19.join)(
|
|
10987
|
-
fromWorktree ? worktreePath : repoPath,
|
|
10988
|
-
".cursor",
|
|
10989
|
-
spec
|
|
10990
|
-
) : spec];
|
|
10991
|
-
let lastExit = 0;
|
|
10992
|
-
for (const command of commands) {
|
|
10993
|
-
const isScriptPath = typeof spec === "string" && (spec.endsWith(".sh") || spec.endsWith(".ps1"));
|
|
10994
|
-
const shell = process.platform === "win32" ? "powershell" : "bash";
|
|
10995
|
-
const args = process.platform === "win32" ? isScriptPath ? ["-File", command] : ["-Command", command] : isScriptPath ? [command] : ["-lc", command];
|
|
10996
|
-
onLine?.(`[cursor setup] ${command}`);
|
|
10997
|
-
const child = (0, import_execa4.execa)(shell, args, {
|
|
10998
|
-
cwd: worktreePath,
|
|
10999
|
-
reject: false,
|
|
11000
|
-
env
|
|
11001
|
-
});
|
|
11002
|
-
if (child.stdout && onLine) {
|
|
11003
|
-
const rl = (0, import_node_readline3.createInterface)({ input: child.stdout });
|
|
11004
|
-
rl.on("line", onLine);
|
|
11005
|
-
}
|
|
11006
|
-
if (child.stderr && onLine) {
|
|
11007
|
-
const rl = (0, import_node_readline3.createInterface)({ input: child.stderr });
|
|
11008
|
-
rl.on("line", onLine);
|
|
11009
|
-
}
|
|
11010
|
-
const result = await child;
|
|
11011
|
-
lastExit = result.exitCode ?? null;
|
|
11012
|
-
if (lastExit !== 0 && lastExit !== null) break;
|
|
11013
|
-
}
|
|
11014
|
-
return { ran: true, exitCode: lastExit, source: sourceLabel };
|
|
11015
|
-
}
|
|
11016
|
-
function hasCursorWorktreeSetup(worktreePath, repoPath) {
|
|
11017
|
-
if (loadCursorWorktreesJson(worktreePath)) return true;
|
|
11018
|
-
if (repoPath && repoPath !== worktreePath && loadCursorWorktreesJson(repoPath)) {
|
|
11019
|
-
return true;
|
|
11020
|
-
}
|
|
11021
|
-
return false;
|
|
11022
|
-
}
|
|
11175
|
+
// src/index.ts
|
|
11176
|
+
init_convention_setup();
|
|
11177
|
+
init_cursor_worktrees();
|
|
11023
11178
|
|
|
11024
11179
|
// src/diff/diff.ts
|
|
11025
|
-
var
|
|
11026
|
-
var
|
|
11180
|
+
var import_node_fs24 = require("fs");
|
|
11181
|
+
var import_node_path21 = require("path");
|
|
11027
11182
|
init_run();
|
|
11028
11183
|
init_worktree();
|
|
11029
11184
|
async function inspectGitWorktree(worktreePath) {
|
|
11030
|
-
if (!worktreePath || !(0,
|
|
11185
|
+
if (!worktreePath || !(0, import_node_fs24.existsSync)(worktreePath)) return "missing_worktree";
|
|
11031
11186
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
11032
11187
|
reject: false
|
|
11033
11188
|
});
|
|
@@ -11035,7 +11190,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
11035
11190
|
return "ok";
|
|
11036
11191
|
}
|
|
11037
11192
|
async function initializeGitRepository(worktreePath) {
|
|
11038
|
-
if (!worktreePath || !(0,
|
|
11193
|
+
if (!worktreePath || !(0, import_node_fs24.existsSync)(worktreePath)) {
|
|
11039
11194
|
throw new Error("Worktree not found");
|
|
11040
11195
|
}
|
|
11041
11196
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -11170,11 +11325,11 @@ new file mode 100644
|
|
|
11170
11325
|
};
|
|
11171
11326
|
}
|
|
11172
11327
|
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
11173
|
-
const abs = (0,
|
|
11328
|
+
const abs = (0, import_node_path21.join)(worktreePath, path2);
|
|
11174
11329
|
try {
|
|
11175
|
-
const st = (0,
|
|
11330
|
+
const st = (0, import_node_fs24.statSync)(abs);
|
|
11176
11331
|
if (st.isFile() && st.size > maxHunk) {
|
|
11177
|
-
const buf = (0,
|
|
11332
|
+
const buf = (0, import_node_fs24.readFileSync)(abs).subarray(0, maxHunk);
|
|
11178
11333
|
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
11179
11334
|
}
|
|
11180
11335
|
} catch {
|
|
@@ -11675,8 +11830,8 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
|
11675
11830
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
11676
11831
|
assertSafeRelativePath(relativePath);
|
|
11677
11832
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
11678
|
-
const abs = (0,
|
|
11679
|
-
const st = (0,
|
|
11833
|
+
const abs = (0, import_node_path21.join)(worktreePath, relativePath);
|
|
11834
|
+
const st = (0, import_node_fs24.statSync)(abs);
|
|
11680
11835
|
if (!st.isFile()) {
|
|
11681
11836
|
throw new Error(`Not a file: ${relativePath}`);
|
|
11682
11837
|
}
|
|
@@ -11685,7 +11840,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
11685
11840
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
11686
11841
|
);
|
|
11687
11842
|
}
|
|
11688
|
-
const buf = (0,
|
|
11843
|
+
const buf = (0, import_node_fs24.readFileSync)(abs);
|
|
11689
11844
|
return {
|
|
11690
11845
|
path: relativePath,
|
|
11691
11846
|
contentBase64: buf.toString("base64"),
|
|
@@ -11695,12 +11850,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
11695
11850
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
11696
11851
|
assertSafeRelativePath(relativePath);
|
|
11697
11852
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
11698
|
-
const abs = (0,
|
|
11699
|
-
const st = (0,
|
|
11853
|
+
const abs = (0, import_node_path21.join)(worktreePath, relativePath);
|
|
11854
|
+
const st = (0, import_node_fs24.statSync)(abs);
|
|
11700
11855
|
if (!st.isFile()) {
|
|
11701
11856
|
throw new Error(`Not a file: ${relativePath}`);
|
|
11702
11857
|
}
|
|
11703
|
-
const buf = (0,
|
|
11858
|
+
const buf = (0, import_node_fs24.readFileSync)(abs);
|
|
11704
11859
|
if (isImageRelativePath(relativePath)) {
|
|
11705
11860
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
11706
11861
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -11743,9 +11898,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
11743
11898
|
}
|
|
11744
11899
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
11745
11900
|
assertSafeRelativePath(relativePath);
|
|
11746
|
-
const abs = (0,
|
|
11747
|
-
(0,
|
|
11748
|
-
(0,
|
|
11901
|
+
const abs = (0, import_node_path21.join)(worktreePath, relativePath);
|
|
11902
|
+
(0, import_node_fs24.mkdirSync)((0, import_node_path21.dirname)(abs), { recursive: true });
|
|
11903
|
+
(0, import_node_fs24.writeFileSync)(abs, content, "utf8");
|
|
11749
11904
|
return { path: relativePath };
|
|
11750
11905
|
}
|
|
11751
11906
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -11764,9 +11919,9 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
11764
11919
|
}
|
|
11765
11920
|
|
|
11766
11921
|
// src/skills/discover.ts
|
|
11767
|
-
var
|
|
11922
|
+
var import_node_fs25 = require("fs");
|
|
11768
11923
|
var import_node_os8 = require("os");
|
|
11769
|
-
var
|
|
11924
|
+
var import_node_path22 = require("path");
|
|
11770
11925
|
function toCommand(name) {
|
|
11771
11926
|
return name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
11772
11927
|
}
|
|
@@ -11798,7 +11953,7 @@ function parseFrontmatter(content) {
|
|
|
11798
11953
|
}
|
|
11799
11954
|
function readSkill(skillMd, source) {
|
|
11800
11955
|
try {
|
|
11801
|
-
const content = (0,
|
|
11956
|
+
const content = (0, import_node_fs25.readFileSync)(skillMd, "utf8");
|
|
11802
11957
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
11803
11958
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
11804
11959
|
const name = fmName || dirName;
|
|
@@ -11817,19 +11972,19 @@ function readSkill(skillMd, source) {
|
|
|
11817
11972
|
}
|
|
11818
11973
|
}
|
|
11819
11974
|
function scanSkillsDir(dir, source, out) {
|
|
11820
|
-
if (!(0,
|
|
11975
|
+
if (!(0, import_node_fs25.existsSync)(dir)) return;
|
|
11821
11976
|
let entries;
|
|
11822
11977
|
try {
|
|
11823
|
-
entries = (0,
|
|
11978
|
+
entries = (0, import_node_fs25.readdirSync)(dir);
|
|
11824
11979
|
} catch {
|
|
11825
11980
|
return;
|
|
11826
11981
|
}
|
|
11827
11982
|
for (const entry of entries) {
|
|
11828
11983
|
if (entry.startsWith(".")) continue;
|
|
11829
|
-
const skillMd = (0,
|
|
11830
|
-
if (!(0,
|
|
11984
|
+
const skillMd = (0, import_node_path22.join)(dir, entry, "SKILL.md");
|
|
11985
|
+
if (!(0, import_node_fs25.existsSync)(skillMd)) continue;
|
|
11831
11986
|
try {
|
|
11832
|
-
if (!(0,
|
|
11987
|
+
if (!(0, import_node_fs25.statSync)(skillMd).isFile()) continue;
|
|
11833
11988
|
} catch {
|
|
11834
11989
|
continue;
|
|
11835
11990
|
}
|
|
@@ -11838,24 +11993,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
11838
11993
|
}
|
|
11839
11994
|
}
|
|
11840
11995
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
11841
|
-
if (!(0,
|
|
11996
|
+
if (!(0, import_node_fs25.existsSync)(pluginsRoot)) return;
|
|
11842
11997
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
11843
11998
|
if (depth > 7) return;
|
|
11844
11999
|
let entries;
|
|
11845
12000
|
try {
|
|
11846
|
-
entries = (0,
|
|
12001
|
+
entries = (0, import_node_fs25.readdirSync)(dir);
|
|
11847
12002
|
} catch {
|
|
11848
12003
|
return;
|
|
11849
12004
|
}
|
|
11850
12005
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
11851
|
-
const skill = readSkill((0,
|
|
12006
|
+
const skill = readSkill((0, import_node_path22.join)(dir, "SKILL.md"), "cli");
|
|
11852
12007
|
if (skill) out.push(skill);
|
|
11853
12008
|
}
|
|
11854
12009
|
for (const entry of entries) {
|
|
11855
12010
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
11856
|
-
const full = (0,
|
|
12011
|
+
const full = (0, import_node_path22.join)(dir, entry);
|
|
11857
12012
|
try {
|
|
11858
|
-
if (!(0,
|
|
12013
|
+
if (!(0, import_node_fs25.statSync)(full).isDirectory()) continue;
|
|
11859
12014
|
} catch {
|
|
11860
12015
|
continue;
|
|
11861
12016
|
}
|
|
@@ -11873,17 +12028,17 @@ function discoverSkills(worktreePath) {
|
|
|
11873
12028
|
const home = (0, import_node_os8.homedir)();
|
|
11874
12029
|
const collected = [];
|
|
11875
12030
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
11876
|
-
scanSkillsDir((0,
|
|
12031
|
+
scanSkillsDir((0, import_node_path22.join)(worktreePath, rel), "workspace", collected);
|
|
11877
12032
|
}
|
|
11878
12033
|
for (const abs of [
|
|
11879
|
-
(0,
|
|
11880
|
-
(0,
|
|
11881
|
-
(0,
|
|
11882
|
-
(0,
|
|
12034
|
+
(0, import_node_path22.join)(home, ".claude/skills"),
|
|
12035
|
+
(0, import_node_path22.join)(home, ".cursor/skills"),
|
|
12036
|
+
(0, import_node_path22.join)(home, ".sideboard/skills"),
|
|
12037
|
+
(0, import_node_path22.join)(home, ".brightsy/skills")
|
|
11883
12038
|
]) {
|
|
11884
12039
|
scanSkillsDir(abs, "user", collected);
|
|
11885
12040
|
}
|
|
11886
|
-
scanClaudePluginSkills((0,
|
|
12041
|
+
scanClaudePluginSkills((0, import_node_path22.join)(home, ".claude/plugins"), collected);
|
|
11887
12042
|
const rank = { workspace: 0, user: 1, cli: 2 };
|
|
11888
12043
|
const byCommand = /* @__PURE__ */ new Map();
|
|
11889
12044
|
for (const skill of collected) {
|
|
@@ -11895,7 +12050,7 @@ function discoverSkills(worktreePath) {
|
|
|
11895
12050
|
return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
|
|
11896
12051
|
}
|
|
11897
12052
|
function readSkillBody(skillPath, maxChars = 12e3) {
|
|
11898
|
-
const raw = (0,
|
|
12053
|
+
const raw = (0, import_node_fs25.readFileSync)(skillPath, "utf8");
|
|
11899
12054
|
if (raw.startsWith("---")) {
|
|
11900
12055
|
const end = raw.indexOf("\n---", 3);
|
|
11901
12056
|
if (end >= 0) {
|
|
@@ -12036,8 +12191,8 @@ function buildDiffCommentAttachment(input) {
|
|
|
12036
12191
|
}
|
|
12037
12192
|
|
|
12038
12193
|
// src/composer/stage-files.ts
|
|
12039
|
-
var
|
|
12040
|
-
var
|
|
12194
|
+
var import_node_fs26 = require("fs");
|
|
12195
|
+
var import_node_path23 = require("path");
|
|
12041
12196
|
var import_node_crypto5 = require("crypto");
|
|
12042
12197
|
init_workspace_scratch();
|
|
12043
12198
|
var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
@@ -12063,7 +12218,7 @@ var IMAGE_MIME_BY_EXT = {
|
|
|
12063
12218
|
var MAX_INLINE_BYTES = 4e5;
|
|
12064
12219
|
var MAX_PREVIEW_BYTES = 5e6;
|
|
12065
12220
|
function fileExtension(filePath) {
|
|
12066
|
-
const base = (0,
|
|
12221
|
+
const base = (0, import_node_path23.basename)(filePath).toLowerCase();
|
|
12067
12222
|
return base.includes(".") ? base.split(".").pop() || "" : "";
|
|
12068
12223
|
}
|
|
12069
12224
|
function isImageFilePath(filePath) {
|
|
@@ -12073,22 +12228,22 @@ function imageMimeType(filePath) {
|
|
|
12073
12228
|
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
12074
12229
|
}
|
|
12075
12230
|
function ensureAttachmentsDir(worktreePath) {
|
|
12076
|
-
const dir = (0,
|
|
12077
|
-
(0,
|
|
12078
|
-
const gi = (0,
|
|
12079
|
-
if (!(0,
|
|
12080
|
-
(0,
|
|
12231
|
+
const dir = (0, import_node_path23.join)(worktreePath, ATTACHMENTS_DIR);
|
|
12232
|
+
(0, import_node_fs26.mkdirSync)(dir, { recursive: true });
|
|
12233
|
+
const gi = (0, import_node_path23.join)(dir, ".gitignore");
|
|
12234
|
+
if (!(0, import_node_fs26.existsSync)(gi)) {
|
|
12235
|
+
(0, import_node_fs26.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
|
|
12081
12236
|
}
|
|
12082
12237
|
return dir;
|
|
12083
12238
|
}
|
|
12084
12239
|
function uniqueAttachmentName(dir, originalName) {
|
|
12085
12240
|
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
12086
|
-
if (!(0,
|
|
12087
|
-
const ext = (0,
|
|
12241
|
+
if (!(0, import_node_fs26.existsSync)((0, import_node_path23.join)(dir, safe))) return safe;
|
|
12242
|
+
const ext = (0, import_node_path23.extname)(safe);
|
|
12088
12243
|
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
12089
12244
|
for (let i = 1; i < 1e4; i++) {
|
|
12090
12245
|
const candidate = `${stem}-${i}${ext}`;
|
|
12091
|
-
if (!(0,
|
|
12246
|
+
if (!(0, import_node_fs26.existsSync)((0, import_node_path23.join)(dir, candidate))) return candidate;
|
|
12092
12247
|
}
|
|
12093
12248
|
return `${stem}-${(0, import_node_crypto5.randomUUID)()}${ext}`;
|
|
12094
12249
|
}
|
|
@@ -12140,9 +12295,9 @@ function attachmentFromBuffer(name, buf, opts) {
|
|
|
12140
12295
|
};
|
|
12141
12296
|
}
|
|
12142
12297
|
function attachmentFromAbsolutePath(absolutePath) {
|
|
12143
|
-
const name = (0,
|
|
12298
|
+
const name = (0, import_node_path23.basename)(absolutePath);
|
|
12144
12299
|
try {
|
|
12145
|
-
const st = (0,
|
|
12300
|
+
const st = (0, import_node_fs26.statSync)(absolutePath);
|
|
12146
12301
|
if (!st.isFile()) {
|
|
12147
12302
|
return {
|
|
12148
12303
|
id: (0, import_node_crypto5.randomUUID)(),
|
|
@@ -12151,7 +12306,7 @@ function attachmentFromAbsolutePath(absolutePath) {
|
|
|
12151
12306
|
content: `(not a file: ${absolutePath})`
|
|
12152
12307
|
};
|
|
12153
12308
|
}
|
|
12154
|
-
const buf = (0,
|
|
12309
|
+
const buf = (0, import_node_fs26.readFileSync)(absolutePath);
|
|
12155
12310
|
return attachmentFromBuffer(name, buf, { sourceLabel: absolutePath });
|
|
12156
12311
|
} catch (err) {
|
|
12157
12312
|
return {
|
|
@@ -12167,15 +12322,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
|
12167
12322
|
const dir = ensureAttachmentsDir(worktreePath);
|
|
12168
12323
|
const out = [];
|
|
12169
12324
|
for (const abs of absolutePaths) {
|
|
12170
|
-
const originalName = (0,
|
|
12325
|
+
const originalName = (0, import_node_path23.basename)(abs);
|
|
12171
12326
|
try {
|
|
12172
|
-
const st = (0,
|
|
12327
|
+
const st = (0, import_node_fs26.statSync)(abs);
|
|
12173
12328
|
if (!st.isFile()) continue;
|
|
12174
12329
|
const name = uniqueAttachmentName(dir, originalName);
|
|
12175
|
-
const destAbs = (0,
|
|
12176
|
-
(0,
|
|
12330
|
+
const destAbs = (0, import_node_path23.join)(dir, name);
|
|
12331
|
+
(0, import_node_fs26.copyFileSync)(abs, destAbs);
|
|
12177
12332
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
12178
|
-
const buf = (0,
|
|
12333
|
+
const buf = (0, import_node_fs26.readFileSync)(destAbs);
|
|
12179
12334
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
12180
12335
|
} catch (err) {
|
|
12181
12336
|
out.push({
|
|
@@ -12197,8 +12352,8 @@ function stageBuffersAsAttachments(worktreePath, buffers) {
|
|
|
12197
12352
|
try {
|
|
12198
12353
|
const buf = Buffer.from(item.dataBase64, "base64");
|
|
12199
12354
|
const name = uniqueAttachmentName(dir, originalName);
|
|
12200
|
-
const destAbs = (0,
|
|
12201
|
-
(0,
|
|
12355
|
+
const destAbs = (0, import_node_path23.join)(dir, name);
|
|
12356
|
+
(0, import_node_fs26.writeFileSync)(destAbs, buf);
|
|
12202
12357
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
12203
12358
|
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
12204
12359
|
} catch (err) {
|
|
@@ -12234,18 +12389,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
12234
12389
|
if (!rel || rel.includes("..") || rel.startsWith("/")) {
|
|
12235
12390
|
out.push({
|
|
12236
12391
|
id: (0, import_node_crypto5.randomUUID)(),
|
|
12237
|
-
name: (0,
|
|
12392
|
+
name: (0, import_node_path23.basename)(rel) || "file",
|
|
12238
12393
|
kind: "file",
|
|
12239
12394
|
content: `(invalid path: ${rel})`
|
|
12240
12395
|
});
|
|
12241
12396
|
continue;
|
|
12242
12397
|
}
|
|
12243
|
-
const name = (0,
|
|
12398
|
+
const name = (0, import_node_path23.basename)(rel);
|
|
12244
12399
|
try {
|
|
12245
|
-
const abs = (0,
|
|
12246
|
-
const st = (0,
|
|
12400
|
+
const abs = (0, import_node_path23.join)(worktreePath, rel);
|
|
12401
|
+
const st = (0, import_node_fs26.statSync)(abs);
|
|
12247
12402
|
if (!st.isFile()) continue;
|
|
12248
|
-
const buf = (0,
|
|
12403
|
+
const buf = (0, import_node_fs26.readFileSync)(abs);
|
|
12249
12404
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
12250
12405
|
} catch (err) {
|
|
12251
12406
|
out.push({
|
|
@@ -12733,7 +12888,7 @@ async function confirmLand(thread, opts) {
|
|
|
12733
12888
|
}
|
|
12734
12889
|
|
|
12735
12890
|
// src/threads/create.ts
|
|
12736
|
-
var
|
|
12891
|
+
var import_node_fs27 = require("fs");
|
|
12737
12892
|
init_worktree();
|
|
12738
12893
|
init_app_settings();
|
|
12739
12894
|
init_thread_store();
|
|
@@ -12747,7 +12902,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
12747
12902
|
});
|
|
12748
12903
|
await requireAgent(resolved.agent);
|
|
12749
12904
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
12750
|
-
if (!(0,
|
|
12905
|
+
if (!(0, import_node_fs27.existsSync)(repoPath)) {
|
|
12751
12906
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
12752
12907
|
}
|
|
12753
12908
|
let sourceRef = input.sourceRef;
|
|
@@ -12974,7 +13129,7 @@ async function forkThreadWorktree(input, onSetupLine) {
|
|
|
12974
13129
|
}
|
|
12975
13130
|
|
|
12976
13131
|
// src/threads/stack-layers.ts
|
|
12977
|
-
var
|
|
13132
|
+
var import_node_fs28 = require("fs");
|
|
12978
13133
|
init_run();
|
|
12979
13134
|
init_stack();
|
|
12980
13135
|
init_worktree();
|
|
@@ -13042,7 +13197,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
13042
13197
|
let createdWorktree = false;
|
|
13043
13198
|
const trees = await listWorktrees(repoPath);
|
|
13044
13199
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
13045
|
-
if (checkedOut?.path && (0,
|
|
13200
|
+
if (checkedOut?.path && (0, import_node_fs28.existsSync)(checkedOut.path)) {
|
|
13046
13201
|
if (input.reuseExistingWorktree !== false) {
|
|
13047
13202
|
worktreePath = checkedOut.path;
|
|
13048
13203
|
} else {
|
|
@@ -13184,7 +13339,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
13184
13339
|
async function createPrStack(input, onSetupLine) {
|
|
13185
13340
|
await requireAgent(input.agent);
|
|
13186
13341
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
13187
|
-
if (!(0,
|
|
13342
|
+
if (!(0, import_node_fs28.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
13188
13343
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
13189
13344
|
const status = await detectGhStack(repoPath);
|
|
13190
13345
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -13251,7 +13406,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
13251
13406
|
}
|
|
13252
13407
|
}
|
|
13253
13408
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
13254
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
13409
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs28.existsSync)(bootstrap.worktreePath)) {
|
|
13255
13410
|
try {
|
|
13256
13411
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
13257
13412
|
deleteBranch: bootstrap.branchName
|
|
@@ -13274,20 +13429,20 @@ function stackAgentDefaultsFrom(input) {
|
|
|
13274
13429
|
|
|
13275
13430
|
// src/threads/adopt.ts
|
|
13276
13431
|
var import_node_child_process4 = require("child_process");
|
|
13277
|
-
var
|
|
13432
|
+
var import_node_fs29 = require("fs");
|
|
13278
13433
|
var import_node_os9 = require("os");
|
|
13279
|
-
var
|
|
13434
|
+
var import_node_path24 = require("path");
|
|
13280
13435
|
var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
|
|
13281
13436
|
init_worktree();
|
|
13282
13437
|
init_thread_store();
|
|
13283
|
-
var CONDUCTOR_APP_SUPPORT = (0,
|
|
13438
|
+
var CONDUCTOR_APP_SUPPORT = (0, import_node_path24.join)(
|
|
13284
13439
|
process.env.HOME ?? "",
|
|
13285
13440
|
"Library",
|
|
13286
13441
|
"Application Support",
|
|
13287
13442
|
"com.conductor.app"
|
|
13288
13443
|
);
|
|
13289
|
-
var CONDUCTOR_DB = (0,
|
|
13290
|
-
var CURSOR_SDK_STORE = (0,
|
|
13444
|
+
var CONDUCTOR_DB = (0, import_node_path24.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
13445
|
+
var CURSOR_SDK_STORE = (0, import_node_path24.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
13291
13446
|
function mapAgentType(raw) {
|
|
13292
13447
|
if (!raw) return null;
|
|
13293
13448
|
const v = raw.toLowerCase();
|
|
@@ -13299,21 +13454,21 @@ function mapAgentType(raw) {
|
|
|
13299
13454
|
return null;
|
|
13300
13455
|
}
|
|
13301
13456
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
13302
|
-
if (!workspacePath || !(0,
|
|
13457
|
+
if (!workspacePath || !(0, import_node_fs29.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
13303
13458
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
13304
13459
|
let best = null;
|
|
13305
13460
|
let hashes;
|
|
13306
13461
|
try {
|
|
13307
|
-
hashes = (0,
|
|
13462
|
+
hashes = (0, import_node_fs29.readdirSync)(CURSOR_SDK_STORE);
|
|
13308
13463
|
} catch {
|
|
13309
13464
|
return null;
|
|
13310
13465
|
}
|
|
13311
13466
|
for (const hash of hashes) {
|
|
13312
|
-
const agentsFile = (0,
|
|
13313
|
-
if (!(0,
|
|
13467
|
+
const agentsFile = (0, import_node_path24.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
13468
|
+
if (!(0, import_node_fs29.existsSync)(agentsFile)) continue;
|
|
13314
13469
|
let text3;
|
|
13315
13470
|
try {
|
|
13316
|
-
text3 = (0,
|
|
13471
|
+
text3 = (0, import_node_fs29.readFileSync)(agentsFile, "utf8");
|
|
13317
13472
|
} catch {
|
|
13318
13473
|
continue;
|
|
13319
13474
|
}
|
|
@@ -13337,7 +13492,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
13337
13492
|
return best?.agentId ?? null;
|
|
13338
13493
|
}
|
|
13339
13494
|
async function adoptThread(input) {
|
|
13340
|
-
if (!(0,
|
|
13495
|
+
if (!(0, import_node_fs29.existsSync)(input.worktreePath)) {
|
|
13341
13496
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
13342
13497
|
}
|
|
13343
13498
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -13364,18 +13519,18 @@ function conductorDbPath() {
|
|
|
13364
13519
|
return CONDUCTOR_DB;
|
|
13365
13520
|
}
|
|
13366
13521
|
function listConductorWorkspaces() {
|
|
13367
|
-
if (!(0,
|
|
13522
|
+
if (!(0, import_node_fs29.existsSync)(CONDUCTOR_DB)) {
|
|
13368
13523
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
13369
13524
|
}
|
|
13370
|
-
const tmp = (0,
|
|
13371
|
-
const snapshot = (0,
|
|
13525
|
+
const tmp = (0, import_node_fs29.mkdtempSync)((0, import_node_path24.join)((0, import_node_os9.tmpdir)(), "sideboard-conductor-"));
|
|
13526
|
+
const snapshot = (0, import_node_path24.join)(tmp, "conductor.db");
|
|
13372
13527
|
try {
|
|
13373
|
-
(0,
|
|
13528
|
+
(0, import_node_fs29.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
13374
13529
|
for (const suffix of ["-wal", "-shm"]) {
|
|
13375
13530
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
13376
|
-
if ((0,
|
|
13531
|
+
if ((0, import_node_fs29.existsSync)(src)) {
|
|
13377
13532
|
try {
|
|
13378
|
-
(0,
|
|
13533
|
+
(0, import_node_fs29.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
13379
13534
|
} catch {
|
|
13380
13535
|
}
|
|
13381
13536
|
}
|
|
@@ -13451,22 +13606,22 @@ function listConductorWorkspaces() {
|
|
|
13451
13606
|
db.close();
|
|
13452
13607
|
}
|
|
13453
13608
|
} finally {
|
|
13454
|
-
(0,
|
|
13609
|
+
(0, import_node_fs29.rmSync)(tmp, { recursive: true, force: true });
|
|
13455
13610
|
}
|
|
13456
13611
|
}
|
|
13457
13612
|
function importConductorWorkspace(workspaceId) {
|
|
13458
|
-
if (!(0,
|
|
13613
|
+
if (!(0, import_node_fs29.existsSync)(CONDUCTOR_DB)) {
|
|
13459
13614
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
13460
13615
|
}
|
|
13461
|
-
const tmp = (0,
|
|
13462
|
-
const snapshot = (0,
|
|
13616
|
+
const tmp = (0, import_node_fs29.mkdtempSync)((0, import_node_path24.join)((0, import_node_os9.tmpdir)(), "sideboard-conductor-"));
|
|
13617
|
+
const snapshot = (0, import_node_path24.join)(tmp, "conductor.db");
|
|
13463
13618
|
try {
|
|
13464
|
-
(0,
|
|
13619
|
+
(0, import_node_fs29.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
13465
13620
|
for (const suffix of ["-wal", "-shm"]) {
|
|
13466
13621
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
13467
|
-
if ((0,
|
|
13622
|
+
if ((0, import_node_fs29.existsSync)(src)) {
|
|
13468
13623
|
try {
|
|
13469
|
-
(0,
|
|
13624
|
+
(0, import_node_fs29.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
13470
13625
|
} catch {
|
|
13471
13626
|
}
|
|
13472
13627
|
}
|
|
@@ -13484,7 +13639,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
13484
13639
|
).get(workspaceId);
|
|
13485
13640
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
13486
13641
|
const worktreePath = String(row.workspacePath);
|
|
13487
|
-
if (!(0,
|
|
13642
|
+
if (!(0, import_node_fs29.existsSync)(worktreePath)) {
|
|
13488
13643
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
13489
13644
|
}
|
|
13490
13645
|
let sessionId = null;
|
|
@@ -13547,7 +13702,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
13547
13702
|
db.close();
|
|
13548
13703
|
}
|
|
13549
13704
|
} finally {
|
|
13550
|
-
(0,
|
|
13705
|
+
(0, import_node_fs29.rmSync)(tmp, { recursive: true, force: true });
|
|
13551
13706
|
}
|
|
13552
13707
|
}
|
|
13553
13708
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
@@ -13558,8 +13713,8 @@ async function importConductorWorkspaceAsync(workspaceId) {
|
|
|
13558
13713
|
var import_node_events = require("events");
|
|
13559
13714
|
|
|
13560
13715
|
// src/slack/outbound-watch.ts
|
|
13561
|
-
var
|
|
13562
|
-
var
|
|
13716
|
+
var import_node_fs31 = require("fs");
|
|
13717
|
+
var import_node_path27 = require("path");
|
|
13563
13718
|
init_paths();
|
|
13564
13719
|
init_private_file();
|
|
13565
13720
|
init_secure_file();
|
|
@@ -13605,19 +13760,19 @@ async function slackAuthTest(token) {
|
|
|
13605
13760
|
}
|
|
13606
13761
|
|
|
13607
13762
|
// src/slack/reply-target.ts
|
|
13608
|
-
var
|
|
13609
|
-
var
|
|
13763
|
+
var import_node_fs30 = require("fs");
|
|
13764
|
+
var import_node_path25 = require("path");
|
|
13610
13765
|
init_paths();
|
|
13611
13766
|
init_private_file();
|
|
13612
13767
|
init_secure_file();
|
|
13613
13768
|
function storePath2() {
|
|
13614
|
-
return (0,
|
|
13769
|
+
return (0, import_node_path25.join)(appDataDir(), "slack-reply-to.json");
|
|
13615
13770
|
}
|
|
13616
13771
|
function readStore2() {
|
|
13617
13772
|
const path2 = storePath2();
|
|
13618
|
-
if (!(0,
|
|
13773
|
+
if (!(0, import_node_fs30.existsSync)(path2)) return {};
|
|
13619
13774
|
try {
|
|
13620
|
-
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0,
|
|
13775
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs30.readFileSync)(path2, "utf8"));
|
|
13621
13776
|
return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
|
|
13622
13777
|
} catch {
|
|
13623
13778
|
return {};
|
|
@@ -13634,11 +13789,11 @@ function getSlackReplyTarget(threadId) {
|
|
|
13634
13789
|
}
|
|
13635
13790
|
|
|
13636
13791
|
// src/slack/workspaces.ts
|
|
13637
|
-
var
|
|
13792
|
+
var import_node_path26 = require("path");
|
|
13638
13793
|
init_paths();
|
|
13639
13794
|
init_secure_file();
|
|
13640
13795
|
function storePath3() {
|
|
13641
|
-
return (0,
|
|
13796
|
+
return (0, import_node_path26.join)(appDataDir(), "slack-workspaces.json");
|
|
13642
13797
|
}
|
|
13643
13798
|
function readStore3() {
|
|
13644
13799
|
try {
|
|
@@ -13754,7 +13909,7 @@ var POLL_INTERVAL_MS = 12e3;
|
|
|
13754
13909
|
var lastPollMs = 0;
|
|
13755
13910
|
var nameCache = /* @__PURE__ */ new Map();
|
|
13756
13911
|
function storePath4() {
|
|
13757
|
-
return (0,
|
|
13912
|
+
return (0, import_node_path27.join)(appDataDir(), "slack-outbound-watch.json");
|
|
13758
13913
|
}
|
|
13759
13914
|
function watchId(teamId, channelId, ts) {
|
|
13760
13915
|
return `${teamId}:${channelId}:${ts}`;
|
|
@@ -13784,9 +13939,9 @@ function tsNewer(a, b) {
|
|
|
13784
13939
|
}
|
|
13785
13940
|
function readStore4() {
|
|
13786
13941
|
const path2 = storePath4();
|
|
13787
|
-
if (!(0,
|
|
13942
|
+
if (!(0, import_node_fs31.existsSync)(path2)) return [];
|
|
13788
13943
|
try {
|
|
13789
|
-
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0,
|
|
13944
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs31.readFileSync)(path2, "utf8"));
|
|
13790
13945
|
return Array.isArray(parsed?.watches) ? parsed.watches : [];
|
|
13791
13946
|
} catch {
|
|
13792
13947
|
return [];
|
|
@@ -14131,7 +14286,7 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
14131
14286
|
}
|
|
14132
14287
|
|
|
14133
14288
|
// src/orchestrator/orchestrator.ts
|
|
14134
|
-
var
|
|
14289
|
+
var import_node_fs37 = require("fs");
|
|
14135
14290
|
init_error_detail();
|
|
14136
14291
|
init_agents();
|
|
14137
14292
|
init_worktree();
|
|
@@ -14152,8 +14307,8 @@ function shouldAutoArchiveOnPrMerge(opts) {
|
|
|
14152
14307
|
}
|
|
14153
14308
|
|
|
14154
14309
|
// src/git/orphan-cleanup.ts
|
|
14155
|
-
var
|
|
14156
|
-
var
|
|
14310
|
+
var import_node_fs32 = require("fs");
|
|
14311
|
+
var import_node_path28 = require("path");
|
|
14157
14312
|
init_worktree();
|
|
14158
14313
|
init_thread_store();
|
|
14159
14314
|
init_paths();
|
|
@@ -14168,9 +14323,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14168
14323
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
14169
14324
|
);
|
|
14170
14325
|
const homeRoot = sideboardWorkspacesDir();
|
|
14171
|
-
if ((0,
|
|
14326
|
+
if ((0, import_node_fs32.existsSync)(homeRoot)) {
|
|
14172
14327
|
try {
|
|
14173
|
-
for (const entry of (0,
|
|
14328
|
+
for (const entry of (0, import_node_fs32.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
14174
14329
|
if (!entry.isDirectory()) continue;
|
|
14175
14330
|
void entry;
|
|
14176
14331
|
}
|
|
@@ -14180,7 +14335,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14180
14335
|
const orphans = [];
|
|
14181
14336
|
const seen = /* @__PURE__ */ new Set();
|
|
14182
14337
|
for (const repoPath of repos) {
|
|
14183
|
-
if (!repoPath || !(0,
|
|
14338
|
+
if (!repoPath || !(0, import_node_fs32.existsSync)(repoPath)) continue;
|
|
14184
14339
|
try {
|
|
14185
14340
|
const wts = await listWorktrees(repoPath);
|
|
14186
14341
|
for (const wt of wts) {
|
|
@@ -14191,7 +14346,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14191
14346
|
seen.add(path2);
|
|
14192
14347
|
let mtimeMs = 0;
|
|
14193
14348
|
try {
|
|
14194
|
-
mtimeMs = (0,
|
|
14349
|
+
mtimeMs = (0, import_node_fs32.statSync)(path2).mtimeMs;
|
|
14195
14350
|
} catch {
|
|
14196
14351
|
mtimeMs = 0;
|
|
14197
14352
|
}
|
|
@@ -14201,16 +14356,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14201
14356
|
}
|
|
14202
14357
|
try {
|
|
14203
14358
|
const root = worktreesRoot(repoPath);
|
|
14204
|
-
if ((0,
|
|
14205
|
-
for (const entry of (0,
|
|
14359
|
+
if ((0, import_node_fs32.existsSync)(root)) {
|
|
14360
|
+
for (const entry of (0, import_node_fs32.readdirSync)(root, { withFileTypes: true })) {
|
|
14206
14361
|
if (!entry.isDirectory()) continue;
|
|
14207
|
-
const path2 = (0,
|
|
14362
|
+
const path2 = (0, import_node_path28.join)(root, entry.name).replace(/\/$/, "");
|
|
14208
14363
|
if (known.has(path2) || seen.has(path2)) continue;
|
|
14209
|
-
if (!(0,
|
|
14364
|
+
if (!(0, import_node_fs32.existsSync)((0, import_node_path28.join)(path2, ".git"))) continue;
|
|
14210
14365
|
seen.add(path2);
|
|
14211
14366
|
let mtimeMs = 0;
|
|
14212
14367
|
try {
|
|
14213
|
-
mtimeMs = (0,
|
|
14368
|
+
mtimeMs = (0, import_node_fs32.statSync)(path2).mtimeMs;
|
|
14214
14369
|
} catch {
|
|
14215
14370
|
mtimeMs = Date.now();
|
|
14216
14371
|
}
|
|
@@ -14356,8 +14511,8 @@ async function applyThreadIntoMain(thread, opts) {
|
|
|
14356
14511
|
}
|
|
14357
14512
|
|
|
14358
14513
|
// src/git/clone-repo.ts
|
|
14359
|
-
var
|
|
14360
|
-
var
|
|
14514
|
+
var import_node_fs33 = require("fs");
|
|
14515
|
+
var import_node_path29 = require("path");
|
|
14361
14516
|
var import_execa6 = require("execa");
|
|
14362
14517
|
init_paths();
|
|
14363
14518
|
init_workspaces();
|
|
@@ -14367,12 +14522,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
14367
14522
|
if (!url) throw new Error("Clone URL is required");
|
|
14368
14523
|
let name = opts.name?.trim();
|
|
14369
14524
|
if (!name) {
|
|
14370
|
-
const leaf = (0,
|
|
14525
|
+
const leaf = (0, import_node_path29.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
14371
14526
|
name = leaf || "repo";
|
|
14372
14527
|
}
|
|
14373
14528
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
14374
|
-
const dest = (0,
|
|
14375
|
-
if ((0,
|
|
14529
|
+
const dest = (0, import_node_path29.join)(sideboardReposDir(), name);
|
|
14530
|
+
if ((0, import_node_fs33.existsSync)(dest)) {
|
|
14376
14531
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
14377
14532
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
14378
14533
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -14394,8 +14549,8 @@ init_orchestrator_capable();
|
|
|
14394
14549
|
|
|
14395
14550
|
// src/review/request-review.ts
|
|
14396
14551
|
var import_node_crypto8 = require("crypto");
|
|
14397
|
-
var
|
|
14398
|
-
var
|
|
14552
|
+
var import_node_fs34 = require("fs");
|
|
14553
|
+
var import_node_path30 = require("path");
|
|
14399
14554
|
init_global_workspace();
|
|
14400
14555
|
init_thread_store();
|
|
14401
14556
|
|
|
@@ -14543,22 +14698,22 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
14543
14698
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
14544
14699
|
}
|
|
14545
14700
|
function readTextIfPresent(abs) {
|
|
14546
|
-
if (!(0,
|
|
14701
|
+
if (!(0, import_node_fs34.existsSync)(abs)) return null;
|
|
14547
14702
|
try {
|
|
14548
|
-
const content = (0,
|
|
14703
|
+
const content = (0, import_node_fs34.readFileSync)(abs, "utf8");
|
|
14549
14704
|
return content.trim() ? content : null;
|
|
14550
14705
|
} catch {
|
|
14551
14706
|
return null;
|
|
14552
14707
|
}
|
|
14553
14708
|
}
|
|
14554
14709
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
14555
|
-
const gitignoreAbs = (0,
|
|
14556
|
-
if ((0,
|
|
14557
|
-
(0,
|
|
14558
|
-
(0,
|
|
14710
|
+
const gitignoreAbs = (0, import_node_path30.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
14711
|
+
if ((0, import_node_fs34.existsSync)(gitignoreAbs)) return;
|
|
14712
|
+
(0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(gitignoreAbs), { recursive: true });
|
|
14713
|
+
(0, import_node_fs34.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
14559
14714
|
}
|
|
14560
14715
|
function resolveReviewGuidelines(worktreePath) {
|
|
14561
|
-
const repoAbs = (0,
|
|
14716
|
+
const repoAbs = (0, import_node_path30.join)(worktreePath, REPO_REVIEW_PATH);
|
|
14562
14717
|
const repoContent = readTextIfPresent(repoAbs);
|
|
14563
14718
|
if (repoContent) {
|
|
14564
14719
|
return {
|
|
@@ -14568,7 +14723,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
14568
14723
|
source: "repo"
|
|
14569
14724
|
};
|
|
14570
14725
|
}
|
|
14571
|
-
const localAbs = (0,
|
|
14726
|
+
const localAbs = (0, import_node_path30.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
14572
14727
|
const localContent = readTextIfPresent(localAbs);
|
|
14573
14728
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
14574
14729
|
return {
|
|
@@ -14578,7 +14733,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
14578
14733
|
source: "local"
|
|
14579
14734
|
};
|
|
14580
14735
|
}
|
|
14581
|
-
const legacyAbs = (0,
|
|
14736
|
+
const legacyAbs = (0, import_node_path30.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
14582
14737
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
14583
14738
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
14584
14739
|
return {
|
|
@@ -14589,8 +14744,8 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
14589
14744
|
};
|
|
14590
14745
|
}
|
|
14591
14746
|
ensureAttachmentsGitignore(worktreePath);
|
|
14592
|
-
(0,
|
|
14593
|
-
(0,
|
|
14747
|
+
(0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(localAbs), { recursive: true });
|
|
14748
|
+
(0, import_node_fs34.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
|
|
14594
14749
|
return {
|
|
14595
14750
|
path: REVIEW_REQUEST_PATH,
|
|
14596
14751
|
name: REVIEW_REQUEST_NAME,
|
|
@@ -14599,7 +14754,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
14599
14754
|
};
|
|
14600
14755
|
}
|
|
14601
14756
|
function ensureReviewRequestFile(worktreePath) {
|
|
14602
|
-
const repoAbs = (0,
|
|
14757
|
+
const repoAbs = (0, import_node_path30.join)(worktreePath, REPO_REVIEW_PATH);
|
|
14603
14758
|
const repoContent = readTextIfPresent(repoAbs);
|
|
14604
14759
|
if (repoContent) {
|
|
14605
14760
|
return {
|
|
@@ -14609,10 +14764,10 @@ function ensureReviewRequestFile(worktreePath) {
|
|
|
14609
14764
|
source: "repo"
|
|
14610
14765
|
};
|
|
14611
14766
|
}
|
|
14612
|
-
const localAbs = (0,
|
|
14613
|
-
const localContent = readTextIfPresent(localAbs) ?? readTextIfPresent((0,
|
|
14767
|
+
const localAbs = (0, import_node_path30.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
14768
|
+
const localContent = readTextIfPresent(localAbs) ?? readTextIfPresent((0, import_node_path30.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
14614
14769
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
14615
|
-
const path2 = (0,
|
|
14770
|
+
const path2 = (0, import_node_fs34.existsSync)(localAbs) ? REVIEW_REQUEST_PATH : LEGACY_REVIEW_REQUEST_PATH;
|
|
14616
14771
|
return {
|
|
14617
14772
|
path: path2,
|
|
14618
14773
|
name: REVIEW_REQUEST_NAME,
|
|
@@ -14620,8 +14775,8 @@ function ensureReviewRequestFile(worktreePath) {
|
|
|
14620
14775
|
source: "local"
|
|
14621
14776
|
};
|
|
14622
14777
|
}
|
|
14623
|
-
(0,
|
|
14624
|
-
(0,
|
|
14778
|
+
(0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(repoAbs), { recursive: true });
|
|
14779
|
+
(0, import_node_fs34.writeFileSync)(repoAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
|
|
14625
14780
|
return {
|
|
14626
14781
|
path: REPO_REVIEW_PATH,
|
|
14627
14782
|
name: REPO_REVIEW_NAME,
|
|
@@ -14641,7 +14796,7 @@ function buildReviewRequestAttachment(content, opts) {
|
|
|
14641
14796
|
};
|
|
14642
14797
|
}
|
|
14643
14798
|
function readExistingReviewRequestFile(worktreePath) {
|
|
14644
|
-
return readTextIfPresent((0,
|
|
14799
|
+
return readTextIfPresent((0, import_node_path30.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path30.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path30.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
14645
14800
|
}
|
|
14646
14801
|
async function requestReview(threadRef, send2) {
|
|
14647
14802
|
const from = findThreadByRef(threadRef);
|
|
@@ -14902,7 +15057,7 @@ var Orchestrator = class {
|
|
|
14902
15057
|
}
|
|
14903
15058
|
continue;
|
|
14904
15059
|
}
|
|
14905
|
-
if (!(0,
|
|
15060
|
+
if (!(0, import_node_fs37.existsSync)(thread.worktreePath)) {
|
|
14906
15061
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
14907
15062
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
14908
15063
|
continue;
|
|
@@ -15077,14 +15232,7 @@ var Orchestrator = class {
|
|
|
15077
15232
|
return thread;
|
|
15078
15233
|
}
|
|
15079
15234
|
async finishCreateThread(threadId, prompt) {
|
|
15080
|
-
|
|
15081
|
-
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
15082
|
-
if (autoRunAfterSetupEnabled2()) {
|
|
15083
|
-
try {
|
|
15084
|
-
await this.startDev(threadId);
|
|
15085
|
-
} catch {
|
|
15086
|
-
}
|
|
15087
|
-
}
|
|
15235
|
+
const setup = this.runSetupAfterCreate(threadId);
|
|
15088
15236
|
if (prompt) {
|
|
15089
15237
|
try {
|
|
15090
15238
|
await this.send(threadId, prompt);
|
|
@@ -15095,6 +15243,14 @@ var Orchestrator = class {
|
|
|
15095
15243
|
});
|
|
15096
15244
|
}
|
|
15097
15245
|
}
|
|
15246
|
+
await setup;
|
|
15247
|
+
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
15248
|
+
if (autoRunAfterSetupEnabled2()) {
|
|
15249
|
+
try {
|
|
15250
|
+
await this.startDev(threadId);
|
|
15251
|
+
} catch {
|
|
15252
|
+
}
|
|
15253
|
+
}
|
|
15098
15254
|
}
|
|
15099
15255
|
/** Run workspace setup after a new worktree is created (no-op if none configured). */
|
|
15100
15256
|
async runSetupAfterCreate(threadId) {
|
|
@@ -15792,7 +15948,7 @@ var Orchestrator = class {
|
|
|
15792
15948
|
});
|
|
15793
15949
|
this.emit({ type: "setup_started", threadId: thread.id });
|
|
15794
15950
|
try {
|
|
15795
|
-
|
|
15951
|
+
const setup = await runWorkspaceSetup(
|
|
15796
15952
|
thread.repoPath,
|
|
15797
15953
|
thread.worktreePath,
|
|
15798
15954
|
(line) => {
|
|
@@ -15800,18 +15956,9 @@ var Orchestrator = class {
|
|
|
15800
15956
|
},
|
|
15801
15957
|
{ signal: abort.signal }
|
|
15802
15958
|
);
|
|
15803
|
-
if (!setup.ran) {
|
|
15804
|
-
setup = await runCursorWorktreeSetup(
|
|
15805
|
-
thread.repoPath,
|
|
15806
|
-
thread.worktreePath,
|
|
15807
|
-
(line) => {
|
|
15808
|
-
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
15809
|
-
}
|
|
15810
|
-
);
|
|
15811
|
-
}
|
|
15812
15959
|
if (!setup.ran) {
|
|
15813
15960
|
throw new Error(
|
|
15814
|
-
"No setup script in .sideboard/settings.toml, .conductor/settings.toml,
|
|
15961
|
+
"No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)"
|
|
15815
15962
|
);
|
|
15816
15963
|
}
|
|
15817
15964
|
if (setup.exitCode !== 0 && setup.exitCode !== null) {
|
|
@@ -16119,7 +16266,7 @@ var Orchestrator = class {
|
|
|
16119
16266
|
this.emit({ type: "status_changed", threadId: t.id, status: t.status });
|
|
16120
16267
|
}
|
|
16121
16268
|
for (const id of result.createdThreadIds) {
|
|
16122
|
-
|
|
16269
|
+
void this.runSetupAfterCreate(id);
|
|
16123
16270
|
}
|
|
16124
16271
|
return { stack: result.stack, threads: result.threads };
|
|
16125
16272
|
}
|
|
@@ -16136,7 +16283,7 @@ var Orchestrator = class {
|
|
|
16136
16283
|
status: result.thread.status
|
|
16137
16284
|
});
|
|
16138
16285
|
if (result.createdWorktree) {
|
|
16139
|
-
|
|
16286
|
+
void this.runSetupAfterCreate(result.thread.id);
|
|
16140
16287
|
}
|
|
16141
16288
|
return { stack: result.stack, thread: result.thread };
|
|
16142
16289
|
}
|
|
@@ -16151,7 +16298,7 @@ var Orchestrator = class {
|
|
|
16151
16298
|
this.emit({ type: "status_changed", threadId: t.id, status: t.status });
|
|
16152
16299
|
}
|
|
16153
16300
|
for (const id of result.createdThreadIds) {
|
|
16154
|
-
|
|
16301
|
+
void this.runSetupAfterCreate(id);
|
|
16155
16302
|
}
|
|
16156
16303
|
return { stack: result.stack, threads: result.threads };
|
|
16157
16304
|
}
|
|
@@ -16162,7 +16309,7 @@ var Orchestrator = class {
|
|
|
16162
16309
|
this.emit({ type: "status_changed", threadId: t.id, status: t.status });
|
|
16163
16310
|
}
|
|
16164
16311
|
for (const id of result.createdThreadIds) {
|
|
16165
|
-
|
|
16312
|
+
void this.runSetupAfterCreate(id);
|
|
16166
16313
|
}
|
|
16167
16314
|
return { stack: result.stack, threads: result.threads };
|
|
16168
16315
|
}
|
|
@@ -16293,7 +16440,7 @@ var Orchestrator = class {
|
|
|
16293
16440
|
async forkThreadWorktree(input) {
|
|
16294
16441
|
const thread = await forkThreadWorktree(input);
|
|
16295
16442
|
this.emit({ type: "status_changed", threadId: thread.id, status: thread.status });
|
|
16296
|
-
|
|
16443
|
+
void this.runSetupAfterCreate(thread.id);
|
|
16297
16444
|
return thread;
|
|
16298
16445
|
}
|
|
16299
16446
|
renameThread(threadRef, title) {
|
|
@@ -16396,7 +16543,7 @@ var Orchestrator = class {
|
|
|
16396
16543
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
16397
16544
|
return restored2;
|
|
16398
16545
|
}
|
|
16399
|
-
if (!(0,
|
|
16546
|
+
if (!(0, import_node_fs37.existsSync)(thread.worktreePath)) {
|
|
16400
16547
|
const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
|
|
16401
16548
|
const { execa: execa7 } = await import("execa");
|
|
16402
16549
|
const slug = thread.worktreePath.split("/").pop();
|
|
@@ -16501,7 +16648,7 @@ async function startOrchestration(opts) {
|
|
|
16501
16648
|
planMode: opts.planMode,
|
|
16502
16649
|
attachments: opts.attachments
|
|
16503
16650
|
};
|
|
16504
|
-
const thread = await createThread({
|
|
16651
|
+
const thread = await orch.createThread({
|
|
16505
16652
|
sourceType: "branch",
|
|
16506
16653
|
sourceRef: "default",
|
|
16507
16654
|
...createOpts
|
|
@@ -16509,7 +16656,7 @@ async function startOrchestration(opts) {
|
|
|
16509
16656
|
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
|
|
16510
16657
|
const repo = await resolveRepoRoot2(repoPath);
|
|
16511
16658
|
const def = await resolveDefaultBranch2(repo);
|
|
16512
|
-
return createThread({
|
|
16659
|
+
return orch.createThread({
|
|
16513
16660
|
sourceType: "branch",
|
|
16514
16661
|
sourceRef: def,
|
|
16515
16662
|
...createOpts,
|
|
@@ -16637,7 +16784,7 @@ init_coordinator_prompt();
|
|
|
16637
16784
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
16638
16785
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
16639
16786
|
var import_zod3 = require("zod");
|
|
16640
|
-
var
|
|
16787
|
+
var import_node_path33 = require("path");
|
|
16641
16788
|
init_worktree();
|
|
16642
16789
|
init_global_workspace();
|
|
16643
16790
|
init_list_models();
|
|
@@ -17315,7 +17462,7 @@ async function startMcpServer() {
|
|
|
17315
17462
|
async () => {
|
|
17316
17463
|
const threads = orch.getThreads(true);
|
|
17317
17464
|
const lines = threads.map((t) => {
|
|
17318
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
17465
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path33.basename)(t.repoPath) || t.repoPath;
|
|
17319
17466
|
return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title} sideboard://thread/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}`;
|
|
17320
17467
|
});
|
|
17321
17468
|
return {
|
|
@@ -17526,7 +17673,7 @@ async function startMcpServer() {
|
|
|
17526
17673
|
);
|
|
17527
17674
|
server.tool(
|
|
17528
17675
|
"create_thread",
|
|
17529
|
-
`Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces. From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Then use send_to_thread to chat.`,
|
|
17676
|
+
`Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces. From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Setup (settings.toml, .cursor/worktrees.json, or script/setup) runs in the background in parallel with the first turn. Then use send_to_thread to chat.`,
|
|
17530
17677
|
{
|
|
17531
17678
|
sourceType: import_zod3.z.enum(["branch", "pr", "ticket"]),
|
|
17532
17679
|
sourceRef: import_zod3.z.string(),
|
|
@@ -18044,7 +18191,7 @@ async function startMcpServer() {
|
|
|
18044
18191
|
);
|
|
18045
18192
|
server.tool(
|
|
18046
18193
|
"run_setup",
|
|
18047
|
-
"Re-run workspace setup (Sideboard/Conductor settings
|
|
18194
|
+
"Re-run workspace setup (Sideboard/Conductor settings, .cursor/worktrees.json, or script/setup). New worktrees already run this automatically.",
|
|
18048
18195
|
{ ref: import_zod3.z.string() },
|
|
18049
18196
|
async ({ ref }) => {
|
|
18050
18197
|
const result = await orch.runSetup(ref);
|
|
@@ -19929,9 +20076,9 @@ var import_node_http3 = require("http");
|
|
|
19929
20076
|
var import_ws3 = require("ws");
|
|
19930
20077
|
|
|
19931
20078
|
// src/slack/relay-static.ts
|
|
19932
|
-
var
|
|
20079
|
+
var import_node_fs38 = require("fs");
|
|
19933
20080
|
var import_promises = require("fs/promises");
|
|
19934
|
-
var
|
|
20081
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
19935
20082
|
var TYPES = {
|
|
19936
20083
|
".css": "text/css; charset=utf-8",
|
|
19937
20084
|
".html": "text/html; charset=utf-8",
|
|
@@ -19962,9 +20109,9 @@ function resolveStaticPath(root, requestUrl) {
|
|
|
19962
20109
|
return null;
|
|
19963
20110
|
}
|
|
19964
20111
|
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
19965
|
-
const rootResolved =
|
|
19966
|
-
const candidate =
|
|
19967
|
-
if (candidate !== rootResolved && !candidate.startsWith(rootResolved +
|
|
20112
|
+
const rootResolved = import_node_path34.default.resolve(root);
|
|
20113
|
+
const candidate = import_node_path34.default.resolve(rootResolved, `.${pathname}`);
|
|
20114
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path34.default.sep)) {
|
|
19968
20115
|
return null;
|
|
19969
20116
|
}
|
|
19970
20117
|
return candidate;
|
|
@@ -19978,7 +20125,7 @@ async function fileSize(file) {
|
|
|
19978
20125
|
}
|
|
19979
20126
|
}
|
|
19980
20127
|
function sendFile(req, res, file, size) {
|
|
19981
|
-
const ext =
|
|
20128
|
+
const ext = import_node_path34.default.extname(file).toLowerCase();
|
|
19982
20129
|
res.writeHead(200, {
|
|
19983
20130
|
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
19984
20131
|
"Content-Length": size,
|
|
@@ -19988,7 +20135,7 @@ function sendFile(req, res, file, size) {
|
|
|
19988
20135
|
res.end();
|
|
19989
20136
|
return true;
|
|
19990
20137
|
}
|
|
19991
|
-
(0,
|
|
20138
|
+
(0, import_node_fs38.createReadStream)(file).pipe(res);
|
|
19992
20139
|
return true;
|
|
19993
20140
|
}
|
|
19994
20141
|
async function tryServeStatic(req, res, root) {
|
|
@@ -19997,7 +20144,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
19997
20144
|
if (!candidate) return false;
|
|
19998
20145
|
const direct = await fileSize(candidate);
|
|
19999
20146
|
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
20000
|
-
const asIndex =
|
|
20147
|
+
const asIndex = import_node_path34.default.join(candidate, "index.html");
|
|
20001
20148
|
const indexSize = await fileSize(asIndex);
|
|
20002
20149
|
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
20003
20150
|
return false;
|
|
@@ -20229,6 +20376,7 @@ async function startSlackRelayServer(opts) {
|
|
|
20229
20376
|
CONTEXT_KEEP_RECENT_CHARS,
|
|
20230
20377
|
CONTEXT_KEEP_RECENT_MESSAGES,
|
|
20231
20378
|
CONTEXT_MIN_MESSAGES,
|
|
20379
|
+
CONVENTION_SETUP_RELPATHS,
|
|
20232
20380
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
20233
20381
|
FAMOUS_SOCCER_TEAMS,
|
|
20234
20382
|
GITHUB_GIT_AUTH_MODES,
|
|
@@ -20390,6 +20538,7 @@ async function startSlackRelayServer(opts) {
|
|
|
20390
20538
|
extractiveSummary,
|
|
20391
20539
|
fetchPrHead,
|
|
20392
20540
|
finalizeParts,
|
|
20541
|
+
findConventionSetup,
|
|
20393
20542
|
findInvalidCacheControlTtlOrder,
|
|
20394
20543
|
findOrphanWorktrees,
|
|
20395
20544
|
findThreadByRef,
|
|
@@ -20461,6 +20610,7 @@ async function startSlackRelayServer(opts) {
|
|
|
20461
20610
|
hasBakedLinearOAuth,
|
|
20462
20611
|
hasBakedSlackOAuth,
|
|
20463
20612
|
hasConductorHook,
|
|
20613
|
+
hasConventionSetup,
|
|
20464
20614
|
hasCursorWorktreeSetup,
|
|
20465
20615
|
hasRepoHook,
|
|
20466
20616
|
hasWorkspaceHook,
|
|
@@ -20636,10 +20786,12 @@ async function startSlackRelayServer(opts) {
|
|
|
20636
20786
|
run,
|
|
20637
20787
|
runArchiveScript,
|
|
20638
20788
|
runCloudConnect,
|
|
20789
|
+
runConventionSetup,
|
|
20639
20790
|
runCursorWorktreeSetup,
|
|
20640
20791
|
runSetupScript,
|
|
20641
20792
|
runSlackListen,
|
|
20642
20793
|
runSlackRelayClient,
|
|
20794
|
+
runWorkspaceSetup,
|
|
20643
20795
|
sameWorktreePath,
|
|
20644
20796
|
sanitizeMcpServerName,
|
|
20645
20797
|
saveAppSettings,
|