@sideboard-ai/core 0.1.85 → 0.1.87
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 +77 -29
- package/dist/agents/cursor-runner.js +55 -17
- package/dist/{agents-YAYNNJWC.js → agents-V6PVSQYH.js} +8 -8
- package/dist/{agents-FD77JUOP.js → agents-W5446HSV.js} +8 -8
- package/dist/{app-settings-PEXK5VEX.js → app-settings-F36ISTCF.js} +2 -2
- package/dist/{app-settings-K6RFCRF6.js → app-settings-HFINR3XG.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-XVFV56JG.js → chunk-3MA6JH6G.js} +5 -5
- package/dist/{chunk-FWJYLBO6.js → chunk-3WA37BRI.js} +1 -1
- package/dist/{chunk-JTHWVYSD.js → chunk-4PTN2LED.js} +5 -5
- package/dist/{chunk-RV6DBEDQ.js → chunk-7KDBDMNC.js} +1 -1
- package/dist/{chunk-SH75CXJR.js → chunk-A7LONVNO.js} +5 -5
- package/dist/{chunk-M37RITA6.js → chunk-B4R2VB2A.js} +164 -30
- package/dist/{chunk-6WQAYBVE.js → chunk-CY45C3GA.js} +4 -4
- package/dist/{chunk-6K5VAPVR.js → chunk-DKHGWYWR.js} +1 -1
- package/dist/{chunk-2N5DVTGH.js → chunk-HBXQQ5TO.js} +3 -3
- package/dist/{chunk-7MV3RXSC.js → chunk-JL4SJ6V7.js} +137 -26
- package/dist/{chunk-7FD7COKE.js → chunk-JOF3XIEM.js} +1 -1
- package/dist/{chunk-KRAUS3RF.js → chunk-L63LLCTX.js} +4 -4
- package/dist/{chunk-MFF2RE3I.js → chunk-NZPGMNFC.js} +1 -1
- package/dist/{chunk-HHTHF5BQ.js → chunk-QSLE4VEM.js} +4 -4
- package/dist/{chunk-3CCRD6WS.js → chunk-QWNROSRB.js} +6 -6
- package/dist/{chunk-JFQ2M6NQ.js → chunk-R2EOZNQI.js} +3 -3
- package/dist/{chunk-AY53MPDE.js → chunk-TC2KY5G7.js} +1 -1
- package/dist/{chunk-WGI6KXKJ.js → chunk-U4GZKLIV.js} +6 -6
- package/dist/{chunk-6GKDYUTJ.js → chunk-UVNXLTFB.js} +5 -5
- package/dist/{chunk-I3FRXL7J.js → chunk-XY6XXMAK.js} +1 -1
- 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-VN7FF76K.js → coordinator-prompt-EC3KQLN3.js} +5 -5
- package/dist/{coordinator-prompt-YYQSPLIP.js → coordinator-prompt-PYRAXZN3.js} +5 -5
- 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-BRIDCBMY.js → global-workspace-ICWOWUW6.js} +6 -6
- package/dist/{global-workspace-U3XVTQLL.js → global-workspace-T5IAJF4R.js} +6 -6
- package/dist/index.cjs +633 -526
- package/dist/index.d.cts +45 -11
- package/dist/index.d.ts +45 -11
- package/dist/index.js +212 -252
- package/dist/mcp/run-stdio.cjs +570 -490
- 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-IWQIWAMQ.js → workspaces-AJCAFW64.js} +7 -7
- package/dist/{workspaces-AIZDG6PS.js → workspaces-J4ULXOUH.js} +7 -7
- package/dist/{worktree-6ZALJUWG.js → worktree-4Z2VSHAQ.js} +4 -4
- package/dist/{worktree-7Y22WHR7.js → worktree-H57CCHWO.js} +4 -4
- package/package.json +1 -1
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -71,10 +71,129 @@ var init_nested_electron_env = __esm({
|
|
|
71
71
|
}
|
|
72
72
|
});
|
|
73
73
|
|
|
74
|
+
// src/hook/convention-setup.ts
|
|
75
|
+
function isFile(path) {
|
|
76
|
+
try {
|
|
77
|
+
return (0, import_node_fs.statSync)(path).isFile();
|
|
78
|
+
} catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function normPath(p) {
|
|
83
|
+
return p.replace(/\/+$/, "");
|
|
84
|
+
}
|
|
85
|
+
function findConventionSetup(worktreePath, repoPath) {
|
|
86
|
+
const roots = [
|
|
87
|
+
{ root: worktreePath, where: "worktree" }
|
|
88
|
+
];
|
|
89
|
+
if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
|
|
90
|
+
roots.push({ root: repoPath, where: "main repo" });
|
|
91
|
+
}
|
|
92
|
+
for (const { root, where } of roots) {
|
|
93
|
+
for (const relPath of CONVENTION_SETUP_RELPATHS) {
|
|
94
|
+
const absPath = (0, import_node_path.join)(root, relPath);
|
|
95
|
+
if (!(0, import_node_fs.existsSync)(absPath) || !isFile(absPath)) continue;
|
|
96
|
+
return {
|
|
97
|
+
relPath,
|
|
98
|
+
absPath,
|
|
99
|
+
command: `bash ${JSON.stringify(absPath)}`,
|
|
100
|
+
source: `${relPath} (${where})`
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
var import_node_fs, import_node_path, CONVENTION_SETUP_RELPATHS;
|
|
107
|
+
var init_convention_setup = __esm({
|
|
108
|
+
"src/hook/convention-setup.ts"() {
|
|
109
|
+
"use strict";
|
|
110
|
+
import_node_fs = require("fs");
|
|
111
|
+
import_node_path = require("path");
|
|
112
|
+
CONVENTION_SETUP_RELPATHS = [
|
|
113
|
+
"script/setup",
|
|
114
|
+
"bin/setup",
|
|
115
|
+
"scripts/setup.sh",
|
|
116
|
+
"scripts/setup"
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// src/hook/cursor-worktrees.ts
|
|
122
|
+
function loadCursorWorktreesJson(rootPath) {
|
|
123
|
+
const path = (0, import_node_path2.join)(rootPath, ".cursor", "worktrees.json");
|
|
124
|
+
if (!(0, import_node_fs2.existsSync)(path)) return null;
|
|
125
|
+
try {
|
|
126
|
+
return JSON.parse((0, import_node_fs2.readFileSync)(path, "utf8"));
|
|
127
|
+
} catch {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function resolveSetupSpec(config) {
|
|
132
|
+
if (process.platform === "win32") {
|
|
133
|
+
return config["setup-worktree-windows"] ?? config["setup-worktree"] ?? null;
|
|
134
|
+
}
|
|
135
|
+
return config["setup-worktree-unix"] ?? config["setup-worktree"] ?? null;
|
|
136
|
+
}
|
|
137
|
+
async function runCursorWorktreeSetup(repoPath, worktreePath, onLine) {
|
|
138
|
+
const fromWorktree = loadCursorWorktreesJson(worktreePath);
|
|
139
|
+
const fromRepo = worktreePath !== repoPath ? loadCursorWorktreesJson(repoPath) : null;
|
|
140
|
+
const config = fromWorktree ?? fromRepo;
|
|
141
|
+
if (!config) return { ran: false, exitCode: null, source: null };
|
|
142
|
+
const spec = resolveSetupSpec(config);
|
|
143
|
+
if (!spec) return { ran: false, exitCode: null, source: null };
|
|
144
|
+
const sourceLabel = fromWorktree ? ".cursor/worktrees.json (worktree)" : ".cursor/worktrees.json (main repo)";
|
|
145
|
+
const env = {
|
|
146
|
+
...process.env,
|
|
147
|
+
ROOT_WORKTREE_PATH: repoPath
|
|
148
|
+
};
|
|
149
|
+
if (process.platform === "win32") {
|
|
150
|
+
env.ROOT_WORKTREE_PATH = repoPath;
|
|
151
|
+
}
|
|
152
|
+
const commands = Array.isArray(spec) ? spec : [spec.endsWith(".sh") || spec.endsWith(".ps1") ? (0, import_node_path2.join)(
|
|
153
|
+
fromWorktree ? worktreePath : repoPath,
|
|
154
|
+
".cursor",
|
|
155
|
+
spec
|
|
156
|
+
) : spec];
|
|
157
|
+
let lastExit = 0;
|
|
158
|
+
for (const command of commands) {
|
|
159
|
+
const isScriptPath = typeof spec === "string" && (spec.endsWith(".sh") || spec.endsWith(".ps1"));
|
|
160
|
+
const shell = process.platform === "win32" ? "powershell" : "bash";
|
|
161
|
+
const args = process.platform === "win32" ? isScriptPath ? ["-File", command] : ["-Command", command] : isScriptPath ? [command] : ["-lc", command];
|
|
162
|
+
onLine?.(`[cursor setup] ${command}`);
|
|
163
|
+
const child = (0, import_execa.execa)(shell, args, {
|
|
164
|
+
cwd: worktreePath,
|
|
165
|
+
reject: false,
|
|
166
|
+
env
|
|
167
|
+
});
|
|
168
|
+
if (child.stdout && onLine) {
|
|
169
|
+
const rl = (0, import_node_readline.createInterface)({ input: child.stdout });
|
|
170
|
+
rl.on("line", onLine);
|
|
171
|
+
}
|
|
172
|
+
if (child.stderr && onLine) {
|
|
173
|
+
const rl = (0, import_node_readline.createInterface)({ input: child.stderr });
|
|
174
|
+
rl.on("line", onLine);
|
|
175
|
+
}
|
|
176
|
+
const result = await child;
|
|
177
|
+
lastExit = result.exitCode ?? null;
|
|
178
|
+
if (lastExit !== 0 && lastExit !== null) break;
|
|
179
|
+
}
|
|
180
|
+
return { ran: true, exitCode: lastExit, source: sourceLabel };
|
|
181
|
+
}
|
|
182
|
+
var import_node_fs2, import_node_path2, import_execa, import_node_readline;
|
|
183
|
+
var init_cursor_worktrees = __esm({
|
|
184
|
+
"src/hook/cursor-worktrees.ts"() {
|
|
185
|
+
"use strict";
|
|
186
|
+
import_node_fs2 = require("fs");
|
|
187
|
+
import_node_path2 = require("path");
|
|
188
|
+
import_execa = require("execa");
|
|
189
|
+
import_node_readline = require("readline");
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
74
193
|
// src/hook/settings.ts
|
|
75
194
|
function expandHome(path) {
|
|
76
195
|
if (path.startsWith("~/") || path === "~") {
|
|
77
|
-
return (0,
|
|
196
|
+
return (0, import_node_path3.join)((0, import_node_os.homedir)(), path.slice(2));
|
|
78
197
|
}
|
|
79
198
|
return path;
|
|
80
199
|
}
|
|
@@ -87,8 +206,8 @@ function parseAvailableIn(raw) {
|
|
|
87
206
|
return out.length ? out : void 0;
|
|
88
207
|
}
|
|
89
208
|
function parseSettingsFile(path, source) {
|
|
90
|
-
if (!(0,
|
|
91
|
-
const raw = (0,
|
|
209
|
+
if (!(0, import_node_fs3.existsSync)(path)) return null;
|
|
210
|
+
const raw = (0, import_node_fs3.readFileSync)(path, "utf8");
|
|
92
211
|
const data = (0, import_smol_toml.parse)(raw);
|
|
93
212
|
const scripts = data.scripts ?? {};
|
|
94
213
|
const setup = typeof scripts.setup === "string" ? scripts.setup : void 0;
|
|
@@ -191,15 +310,15 @@ function finalizeSettings(parsed) {
|
|
|
191
310
|
};
|
|
192
311
|
}
|
|
193
312
|
function familyFiles(rootPath, source) {
|
|
194
|
-
const dir = (0,
|
|
313
|
+
const dir = (0, import_node_path3.join)(rootPath, `.${source}`);
|
|
195
314
|
return {
|
|
196
|
-
toml: (0,
|
|
197
|
-
local: (0,
|
|
315
|
+
toml: (0, import_node_path3.join)(dir, "settings.toml"),
|
|
316
|
+
local: (0, import_node_path3.join)(dir, "settings.local.toml")
|
|
198
317
|
};
|
|
199
318
|
}
|
|
200
319
|
function familyExists(rootPath, source) {
|
|
201
320
|
const files = familyFiles(rootPath, source);
|
|
202
|
-
return (0,
|
|
321
|
+
return (0, import_node_fs3.existsSync)(files.toml) || (0, import_node_fs3.existsSync)(files.local);
|
|
203
322
|
}
|
|
204
323
|
function detectFamily(rootPath) {
|
|
205
324
|
if (familyExists(rootPath, "sideboard")) return "sideboard";
|
|
@@ -218,7 +337,7 @@ function loadAnyLocal(rootPath) {
|
|
|
218
337
|
loadLocalToml(rootPath, "sideboard")
|
|
219
338
|
);
|
|
220
339
|
}
|
|
221
|
-
function
|
|
340
|
+
function normPath2(p) {
|
|
222
341
|
return p.replace(/\/+$/, "");
|
|
223
342
|
}
|
|
224
343
|
function loadRepoSettings(repoPath) {
|
|
@@ -232,11 +351,11 @@ function loadRepoSettings(repoPath) {
|
|
|
232
351
|
}
|
|
233
352
|
function loadWorkspaceSettings(worktreePath, repoPath) {
|
|
234
353
|
const wtFamily = detectFamily(worktreePath);
|
|
235
|
-
const repoFamily = repoPath &&
|
|
354
|
+
const repoFamily = repoPath && normPath2(repoPath) !== normPath2(worktreePath) ? detectFamily(repoPath) : null;
|
|
236
355
|
const wtToml = wtFamily ? loadCommittedToml(worktreePath, wtFamily) : null;
|
|
237
356
|
const repoToml = repoPath && repoFamily ? loadCommittedToml(repoPath, repoFamily) : null;
|
|
238
357
|
let merged = wtToml ?? repoToml;
|
|
239
|
-
if (repoPath &&
|
|
358
|
+
if (repoPath && normPath2(repoPath) !== normPath2(worktreePath)) {
|
|
240
359
|
merged = mergeSettings(merged, loadAnyLocal(repoPath));
|
|
241
360
|
}
|
|
242
361
|
merged = mergeSettings(merged, loadAnyLocal(worktreePath));
|
|
@@ -246,29 +365,31 @@ function settingsSourceLabel(rootPath) {
|
|
|
246
365
|
const family = detectFamily(rootPath);
|
|
247
366
|
if (!family) return null;
|
|
248
367
|
const files = familyFiles(rootPath, family);
|
|
249
|
-
if ((0,
|
|
368
|
+
if ((0, import_node_fs3.existsSync)(files.toml) && (0, import_node_fs3.existsSync)(files.local)) {
|
|
250
369
|
return `.${family}/settings.toml + local`;
|
|
251
370
|
}
|
|
252
|
-
if ((0,
|
|
371
|
+
if ((0, import_node_fs3.existsSync)(files.local)) return `.${family}/settings.local.toml`;
|
|
253
372
|
return `.${family}/settings.toml`;
|
|
254
373
|
}
|
|
255
374
|
function workspaceSettingsSourceLabel(worktreePath, repoPath) {
|
|
256
375
|
const wt = settingsSourceLabel(worktreePath);
|
|
257
376
|
if (wt) return `${wt} (worktree)`;
|
|
258
|
-
if (repoPath &&
|
|
377
|
+
if (repoPath && normPath2(repoPath) !== normPath2(worktreePath)) {
|
|
259
378
|
const repo = settingsSourceLabel(repoPath);
|
|
260
379
|
if (repo) return `${repo} (main repo)`;
|
|
261
380
|
}
|
|
262
381
|
return null;
|
|
263
382
|
}
|
|
264
|
-
var
|
|
383
|
+
var import_node_fs3, import_node_os, import_node_path3, import_smol_toml;
|
|
265
384
|
var init_settings = __esm({
|
|
266
385
|
"src/hook/settings.ts"() {
|
|
267
386
|
"use strict";
|
|
268
|
-
|
|
387
|
+
import_node_fs3 = require("fs");
|
|
269
388
|
import_node_os = require("os");
|
|
270
|
-
|
|
389
|
+
import_node_path3 = require("path");
|
|
271
390
|
import_smol_toml = require("smol-toml");
|
|
391
|
+
init_convention_setup();
|
|
392
|
+
init_cursor_worktrees();
|
|
272
393
|
}
|
|
273
394
|
});
|
|
274
395
|
|
|
@@ -289,89 +410,89 @@ __export(paths_exports, {
|
|
|
289
410
|
});
|
|
290
411
|
function appDataDir() {
|
|
291
412
|
const override = process.env.SIDEBOARD_APP_DATA?.trim();
|
|
292
|
-
const base = override ? override : process.platform === "darwin" ? (0,
|
|
293
|
-
(0,
|
|
413
|
+
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");
|
|
414
|
+
(0, import_node_fs4.mkdirSync)(base, { recursive: true });
|
|
294
415
|
return base;
|
|
295
416
|
}
|
|
296
417
|
function threadsDir() {
|
|
297
|
-
const dir = (0,
|
|
298
|
-
(0,
|
|
418
|
+
const dir = (0, import_node_path5.join)(appDataDir(), "threads");
|
|
419
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
299
420
|
return dir;
|
|
300
421
|
}
|
|
301
422
|
function locksDir() {
|
|
302
|
-
const dir = (0,
|
|
303
|
-
(0,
|
|
423
|
+
const dir = (0, import_node_path5.join)(appDataDir(), "locks");
|
|
424
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
304
425
|
return dir;
|
|
305
426
|
}
|
|
306
427
|
function sideboardHomeDir() {
|
|
307
|
-
const dir = (0,
|
|
308
|
-
(0,
|
|
428
|
+
const dir = (0, import_node_path5.join)((0, import_node_os2.homedir)(), "sideboard");
|
|
429
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
309
430
|
return dir;
|
|
310
431
|
}
|
|
311
432
|
function sideboardReposDir() {
|
|
312
|
-
const dir = (0,
|
|
313
|
-
(0,
|
|
433
|
+
const dir = (0, import_node_path5.join)(sideboardHomeDir(), "repos");
|
|
434
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
314
435
|
return dir;
|
|
315
436
|
}
|
|
316
437
|
function sideboardWorkspacesDir() {
|
|
317
|
-
const dir = (0,
|
|
318
|
-
(0,
|
|
438
|
+
const dir = (0, import_node_path5.join)(sideboardHomeDir(), "workspaces");
|
|
439
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
319
440
|
return dir;
|
|
320
441
|
}
|
|
321
442
|
function repoSlug(repoPath) {
|
|
322
|
-
return (0,
|
|
443
|
+
return (0, import_node_path4.basename)(repoPath.replace(/\/$/, "")) || "repo";
|
|
323
444
|
}
|
|
324
445
|
function worktreesRoot(repoPath) {
|
|
325
446
|
const settings = loadRepoSettings(repoPath);
|
|
326
447
|
if (settings?.worktreesRoot) {
|
|
327
|
-
(0,
|
|
448
|
+
(0, import_node_fs4.mkdirSync)(settings.worktreesRoot, { recursive: true });
|
|
328
449
|
return settings.worktreesRoot;
|
|
329
450
|
}
|
|
330
|
-
const dir = (0,
|
|
331
|
-
(0,
|
|
451
|
+
const dir = (0, import_node_path5.join)(sideboardWorkspacesDir(), repoSlug(repoPath));
|
|
452
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
332
453
|
return dir;
|
|
333
454
|
}
|
|
334
455
|
function threadFilePath(id) {
|
|
335
|
-
return (0,
|
|
456
|
+
return (0, import_node_path5.join)(threadsDir(), `${id}.json`);
|
|
336
457
|
}
|
|
337
458
|
function threadLockPath(id) {
|
|
338
|
-
return (0,
|
|
459
|
+
return (0, import_node_path5.join)(locksDir(), `${id}.lock`);
|
|
339
460
|
}
|
|
340
461
|
function globalAgentCwd() {
|
|
341
|
-
const dir = (0,
|
|
342
|
-
(0,
|
|
462
|
+
const dir = (0, import_node_path5.join)(appDataDir(), "global");
|
|
463
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
343
464
|
return dir;
|
|
344
465
|
}
|
|
345
|
-
var
|
|
466
|
+
var import_node_path4, import_node_os2, import_node_path5, import_node_fs4;
|
|
346
467
|
var init_paths = __esm({
|
|
347
468
|
"src/store/paths.ts"() {
|
|
348
469
|
"use strict";
|
|
349
|
-
|
|
470
|
+
import_node_path4 = require("path");
|
|
350
471
|
import_node_os2 = require("os");
|
|
351
|
-
|
|
352
|
-
|
|
472
|
+
import_node_path5 = require("path");
|
|
473
|
+
import_node_fs4 = require("fs");
|
|
353
474
|
init_settings();
|
|
354
475
|
}
|
|
355
476
|
});
|
|
356
477
|
|
|
357
478
|
// src/store/private-file.ts
|
|
358
479
|
function writePrivateFile(path, contents) {
|
|
359
|
-
(0,
|
|
360
|
-
(0,
|
|
480
|
+
(0, import_node_fs5.mkdirSync)((0, import_node_path6.dirname)(path), { recursive: true });
|
|
481
|
+
(0, import_node_fs5.writeFileSync)(path, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
|
|
361
482
|
chmodOwnerOnly(path);
|
|
362
483
|
}
|
|
363
484
|
function chmodOwnerOnly(path) {
|
|
364
485
|
try {
|
|
365
|
-
(0,
|
|
486
|
+
(0, import_node_fs5.chmodSync)(path, PRIVATE_FILE_MODE);
|
|
366
487
|
} catch {
|
|
367
488
|
}
|
|
368
489
|
}
|
|
369
|
-
var
|
|
490
|
+
var import_node_fs5, import_node_path6, PRIVATE_FILE_MODE;
|
|
370
491
|
var init_private_file = __esm({
|
|
371
492
|
"src/store/private-file.ts"() {
|
|
372
493
|
"use strict";
|
|
373
|
-
|
|
374
|
-
|
|
494
|
+
import_node_fs5 = require("fs");
|
|
495
|
+
import_node_path6 = require("path");
|
|
375
496
|
PRIVATE_FILE_MODE = 384;
|
|
376
497
|
}
|
|
377
498
|
});
|
|
@@ -457,11 +578,11 @@ function decryptEnvelope(envelope, key) {
|
|
|
457
578
|
return JSON.parse(plaintext.toString("utf8"));
|
|
458
579
|
}
|
|
459
580
|
function readSecureJson(path) {
|
|
460
|
-
if (!(0,
|
|
581
|
+
if (!(0, import_node_fs6.existsSync)(path)) return null;
|
|
461
582
|
chmodOwnerOnly(path);
|
|
462
583
|
let parsed;
|
|
463
584
|
try {
|
|
464
|
-
parsed = JSON.parse((0,
|
|
585
|
+
parsed = JSON.parse((0, import_node_fs6.readFileSync)(path, "utf8"));
|
|
465
586
|
} catch {
|
|
466
587
|
return null;
|
|
467
588
|
}
|
|
@@ -481,20 +602,20 @@ function writeSecureJson(path, value) {
|
|
|
481
602
|
`);
|
|
482
603
|
}
|
|
483
604
|
function isSecureFileEncrypted(path) {
|
|
484
|
-
if (!(0,
|
|
605
|
+
if (!(0, import_node_fs6.existsSync)(path)) return false;
|
|
485
606
|
try {
|
|
486
|
-
return isEnvelope(JSON.parse((0,
|
|
607
|
+
return isEnvelope(JSON.parse((0, import_node_fs6.readFileSync)(path, "utf8")));
|
|
487
608
|
} catch {
|
|
488
609
|
return false;
|
|
489
610
|
}
|
|
490
611
|
}
|
|
491
|
-
var import_node_child_process, import_node_crypto,
|
|
612
|
+
var import_node_child_process, import_node_crypto, import_node_fs6, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, ALG, injectedKey;
|
|
492
613
|
var init_secure_file = __esm({
|
|
493
614
|
"src/store/secure-file.ts"() {
|
|
494
615
|
"use strict";
|
|
495
616
|
import_node_child_process = require("child_process");
|
|
496
617
|
import_node_crypto = require("crypto");
|
|
497
|
-
|
|
618
|
+
import_node_fs6 = require("fs");
|
|
498
619
|
init_private_file();
|
|
499
620
|
KEYCHAIN_SERVICE = "ai.sideboard.app";
|
|
500
621
|
KEYCHAIN_ACCOUNT = "secret-vault-v1";
|
|
@@ -598,7 +719,7 @@ function createEmptyThread(partial) {
|
|
|
598
719
|
}
|
|
599
720
|
async function withThreadLock(id, fn) {
|
|
600
721
|
const lockPath = threadLockPath(id);
|
|
601
|
-
(0,
|
|
722
|
+
(0, import_node_fs7.writeFileSync)(lockPath, "", { flag: "a" });
|
|
602
723
|
let release;
|
|
603
724
|
try {
|
|
604
725
|
release = await import_proper_lockfile.default.lock(lockPath, {
|
|
@@ -612,26 +733,26 @@ async function withThreadLock(id, fn) {
|
|
|
612
733
|
}
|
|
613
734
|
function readThread(id) {
|
|
614
735
|
const path = threadFilePath(id);
|
|
615
|
-
if (!(0,
|
|
616
|
-
const raw = (0,
|
|
736
|
+
if (!(0, import_node_fs7.existsSync)(path)) return null;
|
|
737
|
+
const raw = (0, import_node_fs7.readFileSync)(path, "utf8");
|
|
617
738
|
return normalizeThread(JSON.parse(raw));
|
|
618
739
|
}
|
|
619
740
|
function writeThread(thread) {
|
|
620
741
|
const path = threadFilePath(idPath(thread.id));
|
|
621
742
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
622
743
|
const next = { ...thread, updatedAt: nowIso() };
|
|
623
|
-
(0,
|
|
624
|
-
(0,
|
|
744
|
+
(0, import_node_fs7.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
|
|
745
|
+
(0, import_node_fs7.renameSync)(tmp, path);
|
|
625
746
|
}
|
|
626
747
|
function idPath(id) {
|
|
627
748
|
return id;
|
|
628
749
|
}
|
|
629
750
|
function listThreads(opts) {
|
|
630
|
-
const files = (0,
|
|
751
|
+
const files = (0, import_node_fs7.readdirSync)(threadsDir()).filter((f) => f.endsWith(".json"));
|
|
631
752
|
const threads = files.map((f) => {
|
|
632
753
|
try {
|
|
633
754
|
return normalizeThread(
|
|
634
|
-
JSON.parse((0,
|
|
755
|
+
JSON.parse((0, import_node_fs7.readFileSync)(threadFilePath(f.replace(/\.json$/, "")), "utf8"))
|
|
635
756
|
);
|
|
636
757
|
} catch {
|
|
637
758
|
return null;
|
|
@@ -642,11 +763,11 @@ function listThreads(opts) {
|
|
|
642
763
|
}
|
|
643
764
|
function deleteThreadRecord(id) {
|
|
644
765
|
const path = threadFilePath(id);
|
|
645
|
-
if ((0,
|
|
766
|
+
if ((0, import_node_fs7.existsSync)(path)) (0, import_node_fs7.unlinkSync)(path);
|
|
646
767
|
const lock = threadLockPath(id);
|
|
647
|
-
if ((0,
|
|
768
|
+
if ((0, import_node_fs7.existsSync)(lock)) {
|
|
648
769
|
try {
|
|
649
|
-
(0,
|
|
770
|
+
(0, import_node_fs7.unlinkSync)(lock);
|
|
650
771
|
} catch {
|
|
651
772
|
}
|
|
652
773
|
}
|
|
@@ -670,12 +791,12 @@ function findThreadByRef(ref) {
|
|
|
670
791
|
const all = listThreads({ includeArchived: true });
|
|
671
792
|
return all.find((t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref) ?? null;
|
|
672
793
|
}
|
|
673
|
-
var import_node_crypto2,
|
|
794
|
+
var import_node_crypto2, import_node_fs7, import_proper_lockfile;
|
|
674
795
|
var init_thread_store = __esm({
|
|
675
796
|
"src/store/thread-store.ts"() {
|
|
676
797
|
"use strict";
|
|
677
798
|
import_node_crypto2 = require("crypto");
|
|
678
|
-
|
|
799
|
+
import_node_fs7 = require("fs");
|
|
679
800
|
import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
|
|
680
801
|
init_thinking_effort();
|
|
681
802
|
init_paths();
|
|
@@ -1734,7 +1855,7 @@ var init_gh_errors = __esm({
|
|
|
1734
1855
|
|
|
1735
1856
|
// src/store/secret-vault.ts
|
|
1736
1857
|
function secretVaultPath() {
|
|
1737
|
-
return (0,
|
|
1858
|
+
return (0, import_node_path10.join)(appDataDir(), "secrets.json");
|
|
1738
1859
|
}
|
|
1739
1860
|
function loadSecretVault() {
|
|
1740
1861
|
const parsed = readSecureJson(secretVaultPath());
|
|
@@ -1778,11 +1899,11 @@ function normalizeVault(raw) {
|
|
|
1778
1899
|
}
|
|
1779
1900
|
return out;
|
|
1780
1901
|
}
|
|
1781
|
-
var
|
|
1902
|
+
var import_node_path10;
|
|
1782
1903
|
var init_secret_vault = __esm({
|
|
1783
1904
|
"src/store/secret-vault.ts"() {
|
|
1784
1905
|
"use strict";
|
|
1785
|
-
|
|
1906
|
+
import_node_path10 = require("path");
|
|
1786
1907
|
init_paths();
|
|
1787
1908
|
init_secure_file();
|
|
1788
1909
|
}
|
|
@@ -1883,10 +2004,10 @@ function toPublicAppSettings(settings) {
|
|
|
1883
2004
|
};
|
|
1884
2005
|
}
|
|
1885
2006
|
function appSettingsPath() {
|
|
1886
|
-
return (0,
|
|
2007
|
+
return (0, import_node_path11.join)(appDataDir(), "settings.json");
|
|
1887
2008
|
}
|
|
1888
2009
|
function claudeUserSettingsPath() {
|
|
1889
|
-
return (0,
|
|
2010
|
+
return (0, import_node_path11.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
|
|
1890
2011
|
}
|
|
1891
2012
|
function normalizeClaude(raw) {
|
|
1892
2013
|
if (!raw || typeof raw !== "object") return {};
|
|
@@ -2129,10 +2250,10 @@ function normalizeSettings(raw) {
|
|
|
2129
2250
|
}
|
|
2130
2251
|
function readSettingsFile() {
|
|
2131
2252
|
const path = appSettingsPath();
|
|
2132
|
-
if (!(0,
|
|
2253
|
+
if (!(0, import_node_fs10.existsSync)(path)) return { ...EMPTY_SETTINGS };
|
|
2133
2254
|
try {
|
|
2134
2255
|
chmodOwnerOnly(path);
|
|
2135
|
-
const parsed = JSON.parse((0,
|
|
2256
|
+
const parsed = JSON.parse((0, import_node_fs10.readFileSync)(path, "utf8"));
|
|
2136
2257
|
return normalizeSettings(parsed);
|
|
2137
2258
|
} catch {
|
|
2138
2259
|
return { ...EMPTY_SETTINGS };
|
|
@@ -2692,14 +2813,14 @@ function childEnvWithAppSettings(extra) {
|
|
|
2692
2813
|
function harnessEnvKey(harness) {
|
|
2693
2814
|
return HARNESS_ENV_KEYS[harness];
|
|
2694
2815
|
}
|
|
2695
|
-
var import_node_crypto3,
|
|
2816
|
+
var import_node_crypto3, import_node_fs10, import_node_os3, import_node_path11, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
|
|
2696
2817
|
var init_app_settings = __esm({
|
|
2697
2818
|
"src/store/app-settings.ts"() {
|
|
2698
2819
|
"use strict";
|
|
2699
2820
|
import_node_crypto3 = require("crypto");
|
|
2700
|
-
|
|
2821
|
+
import_node_fs10 = require("fs");
|
|
2701
2822
|
import_node_os3 = require("os");
|
|
2702
|
-
|
|
2823
|
+
import_node_path11 = require("path");
|
|
2703
2824
|
init_thinking_effort();
|
|
2704
2825
|
init_nested_electron_env();
|
|
2705
2826
|
init_paths();
|
|
@@ -2749,17 +2870,17 @@ var init_app_settings = __esm({
|
|
|
2749
2870
|
|
|
2750
2871
|
// src/agents/path.ts
|
|
2751
2872
|
function prependPathDir(env, dir) {
|
|
2752
|
-
if (!dir || !(0,
|
|
2873
|
+
if (!dir || !(0, import_node_fs11.existsSync)(dir)) return;
|
|
2753
2874
|
const current = env.PATH ?? "";
|
|
2754
|
-
const parts = current.split(
|
|
2875
|
+
const parts = current.split(import_node_path12.delimiter).filter(Boolean);
|
|
2755
2876
|
if (parts.includes(dir)) {
|
|
2756
2877
|
env.PATH = current;
|
|
2757
2878
|
return;
|
|
2758
2879
|
}
|
|
2759
|
-
env.PATH = [dir, ...parts].join(
|
|
2880
|
+
env.PATH = [dir, ...parts].join(import_node_path12.delimiter);
|
|
2760
2881
|
}
|
|
2761
2882
|
function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os4.homedir)()) {
|
|
2762
|
-
return (0,
|
|
2883
|
+
return (0, import_node_path12.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
|
|
2763
2884
|
}
|
|
2764
2885
|
function isConductorBundledCli(filePath) {
|
|
2765
2886
|
const p = (filePath ?? "").replace(/\\/g, "/");
|
|
@@ -2768,21 +2889,21 @@ function isConductorBundledCli(filePath) {
|
|
|
2768
2889
|
function ensureAgentPath(env = process.env) {
|
|
2769
2890
|
const home = env.HOME || env.USERPROFILE || (0, import_node_os4.homedir)();
|
|
2770
2891
|
const current = env.PATH ?? "";
|
|
2771
|
-
const parts = current.split(
|
|
2892
|
+
const parts = current.split(import_node_path12.delimiter).filter(Boolean);
|
|
2772
2893
|
const seen = new Set(parts);
|
|
2773
2894
|
const extras = [
|
|
2774
|
-
...EXTRA_BIN_DIRS.map((rel) => (0,
|
|
2895
|
+
...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path12.join)(home, rel)),
|
|
2775
2896
|
"/opt/homebrew/bin",
|
|
2776
2897
|
"/usr/local/bin",
|
|
2777
2898
|
// Keep after Homebrew/npm so a user-installed CLI still wins.
|
|
2778
2899
|
conductorBundledBinDir(home)
|
|
2779
2900
|
];
|
|
2780
2901
|
for (const dir of extras.reverse()) {
|
|
2781
|
-
if (!dir || seen.has(dir) || !(0,
|
|
2902
|
+
if (!dir || seen.has(dir) || !(0, import_node_fs11.existsSync)(dir)) continue;
|
|
2782
2903
|
parts.unshift(dir);
|
|
2783
2904
|
seen.add(dir);
|
|
2784
2905
|
}
|
|
2785
|
-
const next = parts.join(
|
|
2906
|
+
const next = parts.join(import_node_path12.delimiter);
|
|
2786
2907
|
env.PATH = next;
|
|
2787
2908
|
return next;
|
|
2788
2909
|
}
|
|
@@ -2796,7 +2917,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
|
|
|
2796
2917
|
stdio: ["ignore", "pipe", "ignore"]
|
|
2797
2918
|
}).trim().split(/\r?\n/).find(Boolean);
|
|
2798
2919
|
if (prefix) {
|
|
2799
|
-
const binDir = process.platform === "win32" ? prefix : (0,
|
|
2920
|
+
const binDir = process.platform === "win32" ? prefix : (0, import_node_path12.join)(prefix, "bin");
|
|
2800
2921
|
prependPathDir(env, binDir);
|
|
2801
2922
|
}
|
|
2802
2923
|
} catch {
|
|
@@ -2824,14 +2945,14 @@ function withExportedPath(command, pathValue) {
|
|
|
2824
2945
|
if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
|
|
2825
2946
|
return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
|
|
2826
2947
|
}
|
|
2827
|
-
var
|
|
2948
|
+
var import_node_fs11, import_node_child_process2, import_node_os4, import_node_path12, EXTRA_BIN_DIRS;
|
|
2828
2949
|
var init_path = __esm({
|
|
2829
2950
|
"src/agents/path.ts"() {
|
|
2830
2951
|
"use strict";
|
|
2831
|
-
|
|
2952
|
+
import_node_fs11 = require("fs");
|
|
2832
2953
|
import_node_child_process2 = require("child_process");
|
|
2833
2954
|
import_node_os4 = require("os");
|
|
2834
|
-
|
|
2955
|
+
import_node_path12 = require("path");
|
|
2835
2956
|
EXTRA_BIN_DIRS = [
|
|
2836
2957
|
".local/bin",
|
|
2837
2958
|
".cargo/bin",
|
|
@@ -2859,7 +2980,7 @@ __export(run_exports, {
|
|
|
2859
2980
|
async function run(file, args, opts) {
|
|
2860
2981
|
ensureAgentPath();
|
|
2861
2982
|
try {
|
|
2862
|
-
const result = await (0,
|
|
2983
|
+
const result = await (0, import_execa2.execa)(file, args, {
|
|
2863
2984
|
cwd: opts?.cwd,
|
|
2864
2985
|
env: { ...process.env, ...opts?.env },
|
|
2865
2986
|
reject: opts?.reject ?? true,
|
|
@@ -2923,11 +3044,11 @@ async function resolveGhAuthToken(cwd) {
|
|
|
2923
3044
|
const token = result.stdout.trim();
|
|
2924
3045
|
return token || null;
|
|
2925
3046
|
}
|
|
2926
|
-
var
|
|
3047
|
+
var import_execa2;
|
|
2927
3048
|
var init_run = __esm({
|
|
2928
3049
|
"src/git/run.ts"() {
|
|
2929
3050
|
"use strict";
|
|
2930
|
-
|
|
3051
|
+
import_execa2 = require("execa");
|
|
2931
3052
|
init_path();
|
|
2932
3053
|
}
|
|
2933
3054
|
});
|
|
@@ -3052,7 +3173,7 @@ function formatGitAuthModeDirective(mode) {
|
|
|
3052
3173
|
default:
|
|
3053
3174
|
return [
|
|
3054
3175
|
"Git authentication (Account \u2192 GitHub mode: auto):",
|
|
3055
|
-
"- This process rewrites GitHub SSH remotes to HTTPS and authenticates with `GH_TOKEN` from `gh` so git/ssh never prompt the macOS Keychain (required for
|
|
3176
|
+
"- This process rewrites GitHub SSH remotes to HTTPS and authenticates with `GH_TOKEN` from `gh` so git/ssh never prompt the macOS Keychain (required for unattended orchestrator turns).",
|
|
3056
3177
|
"- Do not switch remotes to SSH. Push with `git push -u origin HEAD`.",
|
|
3057
3178
|
"- If HTTPS auth fails, tell the user to run `gh auth login` on this Mac or set Account \u2192 GitHub to a PAT \u2014 do not wait for a Keychain dialog."
|
|
3058
3179
|
].join("\n");
|
|
@@ -4122,8 +4243,8 @@ function isLocalPrFetchBranch(ref) {
|
|
|
4122
4243
|
}
|
|
4123
4244
|
async function createThreadWorktree(opts) {
|
|
4124
4245
|
let branchName = `thread/${opts.slug}`;
|
|
4125
|
-
const worktreePath = (0,
|
|
4126
|
-
if ((0,
|
|
4246
|
+
const worktreePath = (0, import_node_path13.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
4247
|
+
if ((0, import_node_fs12.existsSync)(worktreePath)) {
|
|
4127
4248
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
4128
4249
|
}
|
|
4129
4250
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -4192,8 +4313,8 @@ ${add.stdout}`;
|
|
|
4192
4313
|
async function createExistingBranchWorktree(opts) {
|
|
4193
4314
|
const branchName = opts.branchName.trim();
|
|
4194
4315
|
if (!branchName) throw new Error("branch name required");
|
|
4195
|
-
const worktreePath = (0,
|
|
4196
|
-
if ((0,
|
|
4316
|
+
const worktreePath = (0, import_node_path13.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
4317
|
+
if ((0, import_node_fs12.existsSync)(worktreePath)) {
|
|
4197
4318
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
4198
4319
|
}
|
|
4199
4320
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -4481,10 +4602,10 @@ function sameRepoPath(a, b) {
|
|
|
4481
4602
|
return normalizeWorktreePath(a) === normalizeWorktreePath(b);
|
|
4482
4603
|
}
|
|
4483
4604
|
function listLocalThreadBranchSlugs(repoPath) {
|
|
4484
|
-
const refsDir = (0,
|
|
4485
|
-
if (!(0,
|
|
4605
|
+
const refsDir = (0, import_node_path13.join)(repoPath, ".git", "refs", "heads", "thread");
|
|
4606
|
+
if (!(0, import_node_fs12.existsSync)(refsDir)) return [];
|
|
4486
4607
|
try {
|
|
4487
|
-
return (0,
|
|
4608
|
+
return (0, import_node_fs12.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
|
|
4488
4609
|
} catch {
|
|
4489
4610
|
return [];
|
|
4490
4611
|
}
|
|
@@ -4492,8 +4613,8 @@ function listLocalThreadBranchSlugs(repoPath) {
|
|
|
4492
4613
|
function collectTakenTeamSlugs(repoPath) {
|
|
4493
4614
|
const taken = /* @__PURE__ */ new Set();
|
|
4494
4615
|
const root = worktreesRoot(repoPath);
|
|
4495
|
-
if ((0,
|
|
4496
|
-
for (const entry of (0,
|
|
4616
|
+
if ((0, import_node_fs12.existsSync)(root)) {
|
|
4617
|
+
for (const entry of (0, import_node_fs12.readdirSync)(root, { withFileTypes: true })) {
|
|
4497
4618
|
if (entry.isDirectory() && entry.name !== ".DS_Store") {
|
|
4498
4619
|
taken.add(normalizeTakenSlug(entry.name));
|
|
4499
4620
|
}
|
|
@@ -4514,18 +4635,18 @@ function allocateTeamSlug(repoPath) {
|
|
|
4514
4635
|
const taken = collectTakenTeamSlugs(repoPath);
|
|
4515
4636
|
for (let attempt = 0; attempt < 32; attempt++) {
|
|
4516
4637
|
const team = allocateTeamName(taken);
|
|
4517
|
-
const path = (0,
|
|
4518
|
-
if (!(0,
|
|
4638
|
+
const path = (0, import_node_path13.join)(worktreesRoot(repoPath), team.slug);
|
|
4639
|
+
if (!(0, import_node_fs12.existsSync)(path)) return team;
|
|
4519
4640
|
taken.add(team.slug);
|
|
4520
4641
|
}
|
|
4521
4642
|
throw new Error("No available soccer team worktree directories left");
|
|
4522
4643
|
}
|
|
4523
|
-
var
|
|
4644
|
+
var import_node_fs12, import_node_path13;
|
|
4524
4645
|
var init_worktree = __esm({
|
|
4525
4646
|
"src/git/worktree.ts"() {
|
|
4526
4647
|
"use strict";
|
|
4527
|
-
|
|
4528
|
-
|
|
4648
|
+
import_node_fs12 = require("fs");
|
|
4649
|
+
import_node_path13 = require("path");
|
|
4529
4650
|
init_paths();
|
|
4530
4651
|
init_thread_store();
|
|
4531
4652
|
init_teams();
|
|
@@ -4667,7 +4788,7 @@ function coordinatorTurnReminder(opts) {
|
|
|
4667
4788
|
function ensureGlobalCoordinatorCwd(opts) {
|
|
4668
4789
|
const dir = globalAgentCwd();
|
|
4669
4790
|
try {
|
|
4670
|
-
(0,
|
|
4791
|
+
(0, import_node_fs13.mkdirSync)(dir, { recursive: true });
|
|
4671
4792
|
} catch {
|
|
4672
4793
|
return dir;
|
|
4673
4794
|
}
|
|
@@ -4675,7 +4796,7 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
4675
4796
|
let orchId = opts?.orchestratorThreadId?.trim() || "";
|
|
4676
4797
|
if (!orchId) {
|
|
4677
4798
|
try {
|
|
4678
|
-
const existing = (0,
|
|
4799
|
+
const existing = (0, import_node_fs13.readFileSync)((0, import_node_path14.join)(dir, "AGENTS.md"), "utf8");
|
|
4679
4800
|
const m = existing.match(
|
|
4680
4801
|
/YOUR orchestration thread id is `([0-9a-f-]{36})`/i
|
|
4681
4802
|
);
|
|
@@ -4717,9 +4838,9 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
4717
4838
|
"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."
|
|
4718
4839
|
].join("\n");
|
|
4719
4840
|
try {
|
|
4720
|
-
(0,
|
|
4841
|
+
(0, import_node_fs13.writeFileSync)((0, import_node_path14.join)(dir, "CLAUDE.md"), `${body}
|
|
4721
4842
|
`, "utf8");
|
|
4722
|
-
(0,
|
|
4843
|
+
(0, import_node_fs13.writeFileSync)((0, import_node_path14.join)(dir, "AGENTS.md"), `${body}
|
|
4723
4844
|
`, "utf8");
|
|
4724
4845
|
} catch {
|
|
4725
4846
|
}
|
|
@@ -4751,12 +4872,12 @@ function coordinatorSystemPrompt(opts) {
|
|
|
4751
4872
|
formatWorkspaceInventory(opts.workspaces)
|
|
4752
4873
|
].join("\n");
|
|
4753
4874
|
}
|
|
4754
|
-
var
|
|
4875
|
+
var import_node_fs13, import_node_path14, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
|
|
4755
4876
|
var init_coordinator_prompt = __esm({
|
|
4756
4877
|
"src/orchestrator/coordinator-prompt.ts"() {
|
|
4757
4878
|
"use strict";
|
|
4758
|
-
|
|
4759
|
-
|
|
4879
|
+
import_node_fs13 = require("fs");
|
|
4880
|
+
import_node_path14 = require("path");
|
|
4760
4881
|
init_worktree();
|
|
4761
4882
|
init_app_settings();
|
|
4762
4883
|
init_paths();
|
|
@@ -4777,7 +4898,7 @@ var init_coordinator_prompt = __esm({
|
|
|
4777
4898
|
"Workspaces:",
|
|
4778
4899
|
"- add_workspace / remove_workspace \u2014 register or unregister a git repo",
|
|
4779
4900
|
"Worktree threads (chats):",
|
|
4780
|
-
"- 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)",
|
|
4901
|
+
"- 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)",
|
|
4781
4902
|
"- 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.",
|
|
4782
4903
|
"- 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.",
|
|
4783
4904
|
"- 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",
|
|
@@ -4785,7 +4906,7 @@ var init_coordinator_prompt = __esm({
|
|
|
4785
4906
|
"- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
|
|
4786
4907
|
"- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
|
|
4787
4908
|
"Setup / run:",
|
|
4788
|
-
"- run_setup \u2014 re-run worktree setup",
|
|
4909
|
+
"- run_setup \u2014 re-run worktree setup (already runs automatically on create when a script exists)",
|
|
4789
4910
|
"- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
|
|
4790
4911
|
"Inspect / review / PRs:",
|
|
4791
4912
|
"- get_diff \u2014 compact diff summary",
|
|
@@ -5054,32 +5175,32 @@ var init_global_workspace = __esm({
|
|
|
5054
5175
|
|
|
5055
5176
|
// src/brightsy/config.ts
|
|
5056
5177
|
function brightsyConfigPath() {
|
|
5057
|
-
return (0,
|
|
5178
|
+
return (0, import_node_path15.join)((0, import_node_os5.homedir)(), ".brightsy", "config.json");
|
|
5058
5179
|
}
|
|
5059
5180
|
function loadBrightsyConfig() {
|
|
5060
5181
|
const path = brightsyConfigPath();
|
|
5061
|
-
if (!(0,
|
|
5182
|
+
if (!(0, import_node_fs14.existsSync)(path)) {
|
|
5062
5183
|
throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
|
|
5063
5184
|
}
|
|
5064
|
-
const raw = JSON.parse((0,
|
|
5185
|
+
const raw = JSON.parse((0, import_node_fs14.readFileSync)(path, "utf8"));
|
|
5065
5186
|
if (!raw.access_token || !raw.account_id) {
|
|
5066
5187
|
throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
|
|
5067
5188
|
}
|
|
5068
5189
|
return raw;
|
|
5069
5190
|
}
|
|
5070
5191
|
function saveBrightsyConfig(cfg) {
|
|
5071
|
-
(0,
|
|
5192
|
+
(0, import_node_fs14.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
|
|
5072
5193
|
`, {
|
|
5073
5194
|
mode: 384
|
|
5074
5195
|
});
|
|
5075
5196
|
}
|
|
5076
|
-
var
|
|
5197
|
+
var import_node_fs14, import_node_os5, import_node_path15;
|
|
5077
5198
|
var init_config = __esm({
|
|
5078
5199
|
"src/brightsy/config.ts"() {
|
|
5079
5200
|
"use strict";
|
|
5080
|
-
|
|
5201
|
+
import_node_fs14 = require("fs");
|
|
5081
5202
|
import_node_os5 = require("os");
|
|
5082
|
-
|
|
5203
|
+
import_node_path15 = require("path");
|
|
5083
5204
|
}
|
|
5084
5205
|
});
|
|
5085
5206
|
|
|
@@ -5094,22 +5215,22 @@ var init_accounts = __esm({
|
|
|
5094
5215
|
|
|
5095
5216
|
// src/brightsy/connected-teams.ts
|
|
5096
5217
|
function storePath4() {
|
|
5097
|
-
return (0,
|
|
5218
|
+
return (0, import_node_path16.join)(appDataDir(), "brightsy-teams.json");
|
|
5098
5219
|
}
|
|
5099
5220
|
function readStore4() {
|
|
5100
5221
|
const path = storePath4();
|
|
5101
|
-
if (!(0,
|
|
5222
|
+
if (!(0, import_node_fs15.existsSync)(path)) return [];
|
|
5102
5223
|
try {
|
|
5103
|
-
const parsed = JSON.parse((0,
|
|
5224
|
+
const parsed = JSON.parse((0, import_node_fs15.readFileSync)(path, "utf8"));
|
|
5104
5225
|
return Array.isArray(parsed.teams) ? parsed.teams : [];
|
|
5105
5226
|
} catch {
|
|
5106
5227
|
return [];
|
|
5107
5228
|
}
|
|
5108
5229
|
}
|
|
5109
5230
|
function writeStore2(teams) {
|
|
5110
|
-
(0,
|
|
5231
|
+
(0, import_node_fs15.mkdirSync)(appDataDir(), { recursive: true });
|
|
5111
5232
|
const path = storePath4();
|
|
5112
|
-
(0,
|
|
5233
|
+
(0, import_node_fs15.writeFileSync)(path, `${JSON.stringify({ teams }, null, 2)}
|
|
5113
5234
|
`, {
|
|
5114
5235
|
mode: 384
|
|
5115
5236
|
});
|
|
@@ -5221,12 +5342,12 @@ function brightsyMcpServerName(slug) {
|
|
|
5221
5342
|
const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
|
|
5222
5343
|
return `brightsy_${cleaned || "team"}`;
|
|
5223
5344
|
}
|
|
5224
|
-
var
|
|
5345
|
+
var import_node_fs15, import_node_path16;
|
|
5225
5346
|
var init_connected_teams = __esm({
|
|
5226
5347
|
"src/brightsy/connected-teams.ts"() {
|
|
5227
5348
|
"use strict";
|
|
5228
|
-
|
|
5229
|
-
|
|
5349
|
+
import_node_fs15 = require("fs");
|
|
5350
|
+
import_node_path16 = require("path");
|
|
5230
5351
|
init_paths();
|
|
5231
5352
|
init_accounts();
|
|
5232
5353
|
init_config();
|
|
@@ -5553,11 +5674,11 @@ async function syncCliForTarget(accountId) {
|
|
|
5553
5674
|
}
|
|
5554
5675
|
applyConnectedTeamToCli(team);
|
|
5555
5676
|
}
|
|
5556
|
-
var
|
|
5677
|
+
var import_node_fs16, brightsyAdapter;
|
|
5557
5678
|
var init_brightsy = __esm({
|
|
5558
5679
|
"src/agents/brightsy.ts"() {
|
|
5559
5680
|
"use strict";
|
|
5560
|
-
|
|
5681
|
+
import_node_fs16 = require("fs");
|
|
5561
5682
|
init_run();
|
|
5562
5683
|
init_connected_teams();
|
|
5563
5684
|
init_config();
|
|
@@ -5572,7 +5693,7 @@ var init_brightsy = __esm({
|
|
|
5572
5693
|
async detect() {
|
|
5573
5694
|
const brightsy = resolveAgentExecutable("brightsy");
|
|
5574
5695
|
if (brightsy !== "brightsy") {
|
|
5575
|
-
if (!(0,
|
|
5696
|
+
if (!(0, import_node_fs16.existsSync)(brightsy)) {
|
|
5576
5697
|
return {
|
|
5577
5698
|
agent: "brightsy",
|
|
5578
5699
|
installed: false,
|
|
@@ -5822,35 +5943,35 @@ function corePackageDir() {
|
|
|
5822
5943
|
try {
|
|
5823
5944
|
const url = import_meta.url;
|
|
5824
5945
|
if (typeof url === "string" && url.length > 0) {
|
|
5825
|
-
return (0,
|
|
5946
|
+
return (0, import_node_path17.dirname)((0, import_node_url.fileURLToPath)(url));
|
|
5826
5947
|
}
|
|
5827
5948
|
} catch {
|
|
5828
5949
|
}
|
|
5829
5950
|
try {
|
|
5830
|
-
const req = (0, import_node_module.createRequire)((0,
|
|
5831
|
-
return (0,
|
|
5951
|
+
const req = (0, import_node_module.createRequire)((0, import_node_path17.join)(process.cwd(), "package.json"));
|
|
5952
|
+
return (0, import_node_path17.dirname)(req.resolve("@sideboard-ai/core"));
|
|
5832
5953
|
} catch {
|
|
5833
5954
|
return process.cwd();
|
|
5834
5955
|
}
|
|
5835
5956
|
}
|
|
5836
5957
|
function findSideboardMcpJsEntry() {
|
|
5837
5958
|
const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
|
|
5838
|
-
if (override && (0,
|
|
5959
|
+
if (override && (0, import_node_fs17.existsSync)(override)) return override;
|
|
5839
5960
|
let dir = corePackageDir();
|
|
5840
5961
|
for (let i = 0; i < 10; i++) {
|
|
5841
5962
|
const candidates = [
|
|
5842
|
-
(0,
|
|
5843
|
-
(0,
|
|
5844
|
-
(0,
|
|
5845
|
-
(0,
|
|
5846
|
-
(0,
|
|
5847
|
-
(0,
|
|
5848
|
-
(0,
|
|
5963
|
+
(0, import_node_path17.join)(dir, "mcp/run-stdio.js"),
|
|
5964
|
+
(0, import_node_path17.join)(dir, "mcp/run-stdio.cjs"),
|
|
5965
|
+
(0, import_node_path17.join)(dir, "dist/mcp/run-stdio.js"),
|
|
5966
|
+
(0, import_node_path17.join)(dir, "dist/mcp/run-stdio.cjs"),
|
|
5967
|
+
(0, import_node_path17.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
5968
|
+
(0, import_node_path17.join)(dir, "packages/cli/dist/index.js"),
|
|
5969
|
+
(0, import_node_path17.join)(dir, "cli/dist/index.js")
|
|
5849
5970
|
];
|
|
5850
5971
|
for (const p of candidates) {
|
|
5851
|
-
if ((0,
|
|
5972
|
+
if ((0, import_node_fs17.existsSync)(p)) return p;
|
|
5852
5973
|
}
|
|
5853
|
-
const parent = (0,
|
|
5974
|
+
const parent = (0, import_node_path17.dirname)(dir);
|
|
5854
5975
|
if (parent === dir) break;
|
|
5855
5976
|
dir = parent;
|
|
5856
5977
|
}
|
|
@@ -5973,19 +6094,19 @@ function writeMcpServersConfig(servers) {
|
|
|
5973
6094
|
...s.env ? { env: s.env } : {}
|
|
5974
6095
|
};
|
|
5975
6096
|
}
|
|
5976
|
-
const dir = (0,
|
|
5977
|
-
const cfgPath = (0,
|
|
5978
|
-
(0,
|
|
6097
|
+
const dir = (0, import_node_fs17.mkdtempSync)((0, import_node_path17.join)((0, import_node_os6.tmpdir)(), "sideboard-mcp-"));
|
|
6098
|
+
const cfgPath = (0, import_node_path17.join)(dir, "mcp.json");
|
|
6099
|
+
(0, import_node_fs17.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
|
|
5979
6100
|
return cfgPath;
|
|
5980
6101
|
}
|
|
5981
|
-
var
|
|
6102
|
+
var import_node_fs17, import_node_module, import_node_os6, import_node_path17, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
|
|
5982
6103
|
var init_injected_mcp = __esm({
|
|
5983
6104
|
"src/agents/injected-mcp.ts"() {
|
|
5984
6105
|
"use strict";
|
|
5985
|
-
|
|
6106
|
+
import_node_fs17 = require("fs");
|
|
5986
6107
|
import_node_module = require("module");
|
|
5987
6108
|
import_node_os6 = require("os");
|
|
5988
|
-
|
|
6109
|
+
import_node_path17 = require("path");
|
|
5989
6110
|
import_node_url = require("url");
|
|
5990
6111
|
init_run();
|
|
5991
6112
|
init_config();
|
|
@@ -6173,11 +6294,11 @@ function parseIssuesJson(raw) {
|
|
|
6173
6294
|
}
|
|
6174
6295
|
return [];
|
|
6175
6296
|
}
|
|
6176
|
-
var
|
|
6297
|
+
var import_node_fs18, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
|
|
6177
6298
|
var init_claude = __esm({
|
|
6178
6299
|
"src/agents/claude.ts"() {
|
|
6179
6300
|
"use strict";
|
|
6180
|
-
|
|
6301
|
+
import_node_fs18 = require("fs");
|
|
6181
6302
|
init_run();
|
|
6182
6303
|
init_app_settings();
|
|
6183
6304
|
init_claude_mcp();
|
|
@@ -6206,7 +6327,7 @@ var init_claude = __esm({
|
|
|
6206
6327
|
async detect() {
|
|
6207
6328
|
const claude = resolveClaudeExecutable();
|
|
6208
6329
|
if (claude !== "claude") {
|
|
6209
|
-
if (!(0,
|
|
6330
|
+
if (!(0, import_node_fs18.existsSync)(claude)) {
|
|
6210
6331
|
return {
|
|
6211
6332
|
agent: "claude",
|
|
6212
6333
|
installed: false,
|
|
@@ -6443,7 +6564,7 @@ async function listCodexModels() {
|
|
|
6443
6564
|
if (codex === "codex") {
|
|
6444
6565
|
const which = await run("which", ["codex"], { reject: false });
|
|
6445
6566
|
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
6446
|
-
} else if (!(0,
|
|
6567
|
+
} else if (!(0, import_node_fs19.existsSync)(codex)) {
|
|
6447
6568
|
return FALLBACK_CODEX_MODELS;
|
|
6448
6569
|
}
|
|
6449
6570
|
const listed = await run(codex, ["debug", "models"], { reject: false });
|
|
@@ -6478,12 +6599,12 @@ function usageFromCodex(usage) {
|
|
|
6478
6599
|
}
|
|
6479
6600
|
function codexConfigHasNetworkAccess() {
|
|
6480
6601
|
const candidates = [
|
|
6481
|
-
(0,
|
|
6482
|
-
(0,
|
|
6602
|
+
(0, import_node_path18.join)((0, import_node_os7.homedir)(), ".codex", "config.toml"),
|
|
6603
|
+
(0, import_node_path18.join)((0, import_node_os7.homedir)(), ".config", "codex", "config.toml")
|
|
6483
6604
|
];
|
|
6484
6605
|
for (const path of candidates) {
|
|
6485
|
-
if (!(0,
|
|
6486
|
-
const text3 = (0,
|
|
6606
|
+
if (!(0, import_node_fs19.existsSync)(path)) continue;
|
|
6607
|
+
const text3 = (0, import_node_fs19.readFileSync)(path, "utf8");
|
|
6487
6608
|
if (/network_access\s*=\s*true/.test(text3)) return true;
|
|
6488
6609
|
}
|
|
6489
6610
|
return false;
|
|
@@ -6515,21 +6636,21 @@ function asRecord(value) {
|
|
|
6515
6636
|
return void 0;
|
|
6516
6637
|
}
|
|
6517
6638
|
function codexLooksAuthenticated() {
|
|
6518
|
-
const authPath = (0,
|
|
6519
|
-
if (!(0,
|
|
6639
|
+
const authPath = (0, import_node_path18.join)((0, import_node_os7.homedir)(), ".codex", "auth.json");
|
|
6640
|
+
if (!(0, import_node_fs19.existsSync)(authPath)) return false;
|
|
6520
6641
|
try {
|
|
6521
|
-
return (0,
|
|
6642
|
+
return (0, import_node_fs19.statSync)(authPath).size > 2;
|
|
6522
6643
|
} catch {
|
|
6523
6644
|
return false;
|
|
6524
6645
|
}
|
|
6525
6646
|
}
|
|
6526
|
-
var
|
|
6647
|
+
var import_node_fs19, import_node_os7, import_node_path18, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
6527
6648
|
var init_codex = __esm({
|
|
6528
6649
|
"src/agents/codex.ts"() {
|
|
6529
6650
|
"use strict";
|
|
6530
|
-
|
|
6651
|
+
import_node_fs19 = require("fs");
|
|
6531
6652
|
import_node_os7 = require("os");
|
|
6532
|
-
|
|
6653
|
+
import_node_path18 = require("path");
|
|
6533
6654
|
init_run();
|
|
6534
6655
|
init_app_settings();
|
|
6535
6656
|
init_global_workspace();
|
|
@@ -6554,7 +6675,7 @@ var init_codex = __esm({
|
|
|
6554
6675
|
async detect() {
|
|
6555
6676
|
const codex = resolveAgentExecutable("codex");
|
|
6556
6677
|
if (codex !== "codex") {
|
|
6557
|
-
if (!(0,
|
|
6678
|
+
if (!(0, import_node_fs19.existsSync)(codex)) {
|
|
6558
6679
|
return {
|
|
6559
6680
|
agent: "codex",
|
|
6560
6681
|
installed: false,
|
|
@@ -6988,11 +7109,11 @@ function entryDir() {
|
|
|
6988
7109
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
6989
7110
|
if (cjsDir) return cjsDir;
|
|
6990
7111
|
try {
|
|
6991
|
-
return (0,
|
|
7112
|
+
return (0, import_node_path19.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
6992
7113
|
} catch {
|
|
6993
7114
|
try {
|
|
6994
7115
|
const req = (0, import_node_module2.createRequire)(process.cwd() + "/");
|
|
6995
|
-
return (0,
|
|
7116
|
+
return (0, import_node_path19.dirname)(req.resolve("@sideboard-ai/core"));
|
|
6996
7117
|
} catch {
|
|
6997
7118
|
return process.cwd();
|
|
6998
7119
|
}
|
|
@@ -7001,27 +7122,27 @@ function entryDir() {
|
|
|
7001
7122
|
function cursorRunnerPath() {
|
|
7002
7123
|
const root = entryDir();
|
|
7003
7124
|
const candidates = [
|
|
7004
|
-
(0,
|
|
7005
|
-
(0,
|
|
7125
|
+
(0, import_node_path19.join)(root, "agents", "cursor-runner.js"),
|
|
7126
|
+
(0, import_node_path19.join)(root, "agents", "cursor-runner.cjs"),
|
|
7006
7127
|
// If somehow resolved from package root instead of dist/
|
|
7007
|
-
(0,
|
|
7008
|
-
(0,
|
|
7128
|
+
(0, import_node_path19.join)(root, "dist", "agents", "cursor-runner.js"),
|
|
7129
|
+
(0, import_node_path19.join)(root, "dist", "agents", "cursor-runner.cjs"),
|
|
7009
7130
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
7010
|
-
(0,
|
|
7011
|
-
(0,
|
|
7131
|
+
(0, import_node_path19.join)(root, "cursor-runner.ts"),
|
|
7132
|
+
(0, import_node_path19.join)(root, "src", "agents", "cursor-runner.ts")
|
|
7012
7133
|
];
|
|
7013
7134
|
for (const candidate of candidates) {
|
|
7014
|
-
if ((0,
|
|
7135
|
+
if ((0, import_node_fs20.existsSync)(candidate)) return candidate;
|
|
7015
7136
|
}
|
|
7016
7137
|
return candidates[0];
|
|
7017
7138
|
}
|
|
7018
|
-
var
|
|
7139
|
+
var import_node_fs20, import_node_module2, import_node_path19, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
|
|
7019
7140
|
var init_cursor = __esm({
|
|
7020
7141
|
"src/agents/cursor.ts"() {
|
|
7021
7142
|
"use strict";
|
|
7022
|
-
|
|
7143
|
+
import_node_fs20 = require("fs");
|
|
7023
7144
|
import_node_module2 = require("module");
|
|
7024
|
-
|
|
7145
|
+
import_node_path19 = require("path");
|
|
7025
7146
|
import_node_url2 = require("url");
|
|
7026
7147
|
import_sdk = require("@cursor/sdk");
|
|
7027
7148
|
init_run();
|
|
@@ -7150,7 +7271,7 @@ async function listOpencodeModels() {
|
|
|
7150
7271
|
if (opencode === "opencode") {
|
|
7151
7272
|
const which = await run("which", ["opencode"], { reject: false });
|
|
7152
7273
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
7153
|
-
} else if (!(0,
|
|
7274
|
+
} else if (!(0, import_node_fs21.existsSync)(opencode)) {
|
|
7154
7275
|
return FALLBACK_OPENCODE_MODELS;
|
|
7155
7276
|
}
|
|
7156
7277
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -7180,11 +7301,11 @@ function usageFromOpencode(tokens) {
|
|
|
7180
7301
|
cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
|
|
7181
7302
|
};
|
|
7182
7303
|
}
|
|
7183
|
-
var
|
|
7304
|
+
var import_node_fs21, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
|
|
7184
7305
|
var init_opencode = __esm({
|
|
7185
7306
|
"src/agents/opencode.ts"() {
|
|
7186
7307
|
"use strict";
|
|
7187
|
-
|
|
7308
|
+
import_node_fs21 = require("fs");
|
|
7188
7309
|
init_run();
|
|
7189
7310
|
init_app_settings();
|
|
7190
7311
|
init_global_workspace();
|
|
@@ -7210,7 +7331,7 @@ var init_opencode = __esm({
|
|
|
7210
7331
|
async detect() {
|
|
7211
7332
|
const opencode = resolveAgentExecutable("opencode");
|
|
7212
7333
|
if (opencode !== "opencode") {
|
|
7213
|
-
if (!(0,
|
|
7334
|
+
if (!(0, import_node_fs21.existsSync)(opencode)) {
|
|
7214
7335
|
return {
|
|
7215
7336
|
agent: "opencode",
|
|
7216
7337
|
installed: false,
|
|
@@ -7947,38 +8068,38 @@ __export(workspaces_exports, {
|
|
|
7947
8068
|
syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
|
|
7948
8069
|
});
|
|
7949
8070
|
function workspacesFile() {
|
|
7950
|
-
return (0,
|
|
8071
|
+
return (0, import_node_path22.join)(appDataDir(), "workspaces.json");
|
|
7951
8072
|
}
|
|
7952
8073
|
function removedWorkspacesFile() {
|
|
7953
|
-
return (0,
|
|
8074
|
+
return (0, import_node_path22.join)(appDataDir(), "removed-workspaces.json");
|
|
7954
8075
|
}
|
|
7955
8076
|
function readAll() {
|
|
7956
8077
|
const path = workspacesFile();
|
|
7957
|
-
if (!(0,
|
|
8078
|
+
if (!(0, import_node_fs24.existsSync)(path)) return [];
|
|
7958
8079
|
try {
|
|
7959
|
-
const raw = JSON.parse((0,
|
|
8080
|
+
const raw = JSON.parse((0, import_node_fs24.readFileSync)(path, "utf8"));
|
|
7960
8081
|
return Array.isArray(raw) ? raw : [];
|
|
7961
8082
|
} catch {
|
|
7962
8083
|
return [];
|
|
7963
8084
|
}
|
|
7964
8085
|
}
|
|
7965
8086
|
function writeAll(list) {
|
|
7966
|
-
(0,
|
|
7967
|
-
(0,
|
|
8087
|
+
(0, import_node_fs24.mkdirSync)(appDataDir(), { recursive: true });
|
|
8088
|
+
(0, import_node_fs24.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
|
|
7968
8089
|
}
|
|
7969
8090
|
function readRemoved() {
|
|
7970
8091
|
const path = removedWorkspacesFile();
|
|
7971
|
-
if (!(0,
|
|
8092
|
+
if (!(0, import_node_fs24.existsSync)(path)) return /* @__PURE__ */ new Set();
|
|
7972
8093
|
try {
|
|
7973
|
-
const raw = JSON.parse((0,
|
|
8094
|
+
const raw = JSON.parse((0, import_node_fs24.readFileSync)(path, "utf8"));
|
|
7974
8095
|
return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
|
|
7975
8096
|
} catch {
|
|
7976
8097
|
return /* @__PURE__ */ new Set();
|
|
7977
8098
|
}
|
|
7978
8099
|
}
|
|
7979
8100
|
function writeRemoved(paths) {
|
|
7980
|
-
(0,
|
|
7981
|
-
(0,
|
|
8101
|
+
(0, import_node_fs24.mkdirSync)(appDataDir(), { recursive: true });
|
|
8102
|
+
(0, import_node_fs24.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
|
|
7982
8103
|
}
|
|
7983
8104
|
function rememberRemoved(repoPath) {
|
|
7984
8105
|
const next = readRemoved();
|
|
@@ -8001,7 +8122,7 @@ function listWorkspaces() {
|
|
|
8001
8122
|
async function addWorkspace(repoPath) {
|
|
8002
8123
|
const root = await resolveRepoRoot(repoPath);
|
|
8003
8124
|
if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
|
|
8004
|
-
if (!(0,
|
|
8125
|
+
if (!(0, import_node_fs24.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
|
|
8005
8126
|
forgetRemoved(root);
|
|
8006
8127
|
await ensureGhPreferOrigin(root);
|
|
8007
8128
|
const current = readAll();
|
|
@@ -8009,7 +8130,7 @@ async function addWorkspace(repoPath) {
|
|
|
8009
8130
|
if (existing) return existing;
|
|
8010
8131
|
const next = {
|
|
8011
8132
|
path: root,
|
|
8012
|
-
name: (0,
|
|
8133
|
+
name: (0, import_node_path22.basename)(root),
|
|
8013
8134
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8014
8135
|
};
|
|
8015
8136
|
writeAll([...current, next]);
|
|
@@ -8031,10 +8152,10 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
8031
8152
|
if (!path || path === "/" || isGlobalRepoPath(path) || byPath.has(path) || removed.has(path)) {
|
|
8032
8153
|
continue;
|
|
8033
8154
|
}
|
|
8034
|
-
if (!(0,
|
|
8155
|
+
if (!(0, import_node_fs24.existsSync)(path)) continue;
|
|
8035
8156
|
const ws = {
|
|
8036
8157
|
path,
|
|
8037
|
-
name: (0,
|
|
8158
|
+
name: (0, import_node_path22.basename)(path),
|
|
8038
8159
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8039
8160
|
};
|
|
8040
8161
|
byPath.set(path, ws);
|
|
@@ -8044,12 +8165,12 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
8044
8165
|
if (dirty) writeAll(next);
|
|
8045
8166
|
return next.sort((a, b) => a.name.localeCompare(b.name));
|
|
8046
8167
|
}
|
|
8047
|
-
var
|
|
8168
|
+
var import_node_fs24, import_node_path22;
|
|
8048
8169
|
var init_workspaces = __esm({
|
|
8049
8170
|
"src/store/workspaces.ts"() {
|
|
8050
8171
|
"use strict";
|
|
8051
|
-
|
|
8052
|
-
|
|
8172
|
+
import_node_fs24 = require("fs");
|
|
8173
|
+
import_node_path22 = require("path");
|
|
8053
8174
|
init_paths();
|
|
8054
8175
|
init_global_workspace();
|
|
8055
8176
|
init_worktree();
|
|
@@ -8126,40 +8247,40 @@ __export(plan_file_exports, {
|
|
|
8126
8247
|
writePlanFile: () => writePlanFile
|
|
8127
8248
|
});
|
|
8128
8249
|
function ensureAttachmentsGitignore2(worktreePath) {
|
|
8129
|
-
const gitignoreAbs = (0,
|
|
8130
|
-
if ((0,
|
|
8131
|
-
(0,
|
|
8132
|
-
(0,
|
|
8250
|
+
const gitignoreAbs = (0, import_node_path30.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
8251
|
+
if ((0, import_node_fs34.existsSync)(gitignoreAbs)) return;
|
|
8252
|
+
(0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(gitignoreAbs), { recursive: true });
|
|
8253
|
+
(0, import_node_fs34.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
8133
8254
|
}
|
|
8134
8255
|
function planFileAbs(worktreePath) {
|
|
8135
|
-
return (0,
|
|
8256
|
+
return (0, import_node_path30.join)(worktreePath, PLAN_FILE_REL);
|
|
8136
8257
|
}
|
|
8137
8258
|
function readTextIfPresent2(abs) {
|
|
8138
|
-
if (!(0,
|
|
8259
|
+
if (!(0, import_node_fs34.existsSync)(abs)) return null;
|
|
8139
8260
|
try {
|
|
8140
|
-
const content = (0,
|
|
8261
|
+
const content = (0, import_node_fs34.readFileSync)(abs, "utf8");
|
|
8141
8262
|
return content.trim() ? content : null;
|
|
8142
8263
|
} catch {
|
|
8143
8264
|
return null;
|
|
8144
8265
|
}
|
|
8145
8266
|
}
|
|
8146
8267
|
function readPlanFile(worktreePath) {
|
|
8147
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
8268
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path30.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path30.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
8148
8269
|
}
|
|
8149
8270
|
function writePlanFile(worktreePath, content) {
|
|
8150
8271
|
ensureAttachmentsGitignore2(worktreePath);
|
|
8151
8272
|
const abs = planFileAbs(worktreePath);
|
|
8152
|
-
(0,
|
|
8273
|
+
(0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(abs), { recursive: true });
|
|
8153
8274
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
8154
|
-
(0,
|
|
8275
|
+
(0, import_node_fs34.writeFileSync)(abs, body, "utf8");
|
|
8155
8276
|
return PLAN_FILE_REL;
|
|
8156
8277
|
}
|
|
8157
|
-
var
|
|
8278
|
+
var import_node_fs34, import_node_path30;
|
|
8158
8279
|
var init_plan_file = __esm({
|
|
8159
8280
|
"src/plan/plan-file.ts"() {
|
|
8160
8281
|
"use strict";
|
|
8161
|
-
|
|
8162
|
-
|
|
8282
|
+
import_node_fs34 = require("fs");
|
|
8283
|
+
import_node_path30 = require("path");
|
|
8163
8284
|
init_workspace_scratch();
|
|
8164
8285
|
init_plan_present();
|
|
8165
8286
|
init_plan_present();
|
|
@@ -8180,7 +8301,7 @@ function setCaffeinateHoldHooks(next) {
|
|
|
8180
8301
|
hooks = next;
|
|
8181
8302
|
}
|
|
8182
8303
|
function caffeinateHoldPath() {
|
|
8183
|
-
return (0,
|
|
8304
|
+
return (0, import_node_path31.join)(appDataDir(), "caffeinate-hold.json");
|
|
8184
8305
|
}
|
|
8185
8306
|
function processAlive(pid) {
|
|
8186
8307
|
if (hooks.processAlive) return hooks.processAlive(pid);
|
|
@@ -8214,9 +8335,9 @@ function uniqueIds(ids) {
|
|
|
8214
8335
|
}
|
|
8215
8336
|
function readHold() {
|
|
8216
8337
|
const path = caffeinateHoldPath();
|
|
8217
|
-
if (!(0,
|
|
8338
|
+
if (!(0, import_node_fs35.existsSync)(path)) return null;
|
|
8218
8339
|
try {
|
|
8219
|
-
const parsed = JSON.parse((0,
|
|
8340
|
+
const parsed = JSON.parse((0, import_node_fs35.readFileSync)(path, "utf8"));
|
|
8220
8341
|
if (typeof parsed?.pid === "number" && parsed.pid > 0) {
|
|
8221
8342
|
return {
|
|
8222
8343
|
pid: parsed.pid,
|
|
@@ -8238,7 +8359,7 @@ function writeHold(pid, threadIds) {
|
|
|
8238
8359
|
}
|
|
8239
8360
|
function clearHold() {
|
|
8240
8361
|
try {
|
|
8241
|
-
(0,
|
|
8362
|
+
(0, import_node_fs35.unlinkSync)(caffeinateHoldPath());
|
|
8242
8363
|
} catch {
|
|
8243
8364
|
}
|
|
8244
8365
|
}
|
|
@@ -8323,13 +8444,13 @@ function releaseCaffeinateHoldForThread(threadId) {
|
|
|
8323
8444
|
}
|
|
8324
8445
|
return setCaffeinateHold(false, { threadId: id });
|
|
8325
8446
|
}
|
|
8326
|
-
var import_node_child_process4,
|
|
8447
|
+
var import_node_child_process4, import_node_fs35, import_node_path31, hooks;
|
|
8327
8448
|
var init_caffeinate_hold = __esm({
|
|
8328
8449
|
"src/store/caffeinate-hold.ts"() {
|
|
8329
8450
|
"use strict";
|
|
8330
8451
|
import_node_child_process4 = require("child_process");
|
|
8331
|
-
|
|
8332
|
-
|
|
8452
|
+
import_node_fs35 = require("fs");
|
|
8453
|
+
import_node_path31 = require("path");
|
|
8333
8454
|
init_paths();
|
|
8334
8455
|
init_private_file();
|
|
8335
8456
|
hooks = {};
|
|
@@ -8344,10 +8465,10 @@ __export(cursor_recover_exports, {
|
|
|
8344
8465
|
function recoverFinishedCursorRun(opts) {
|
|
8345
8466
|
const agentId = opts.agentId.trim();
|
|
8346
8467
|
if (!agentId) return null;
|
|
8347
|
-
const runsPath = (0,
|
|
8348
|
-
if (!(0,
|
|
8468
|
+
const runsPath = (0, import_node_path32.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
|
|
8469
|
+
if (!(0, import_node_fs36.existsSync)(runsPath)) return null;
|
|
8349
8470
|
try {
|
|
8350
|
-
const lines = (0,
|
|
8471
|
+
const lines = (0, import_node_fs36.readFileSync)(runsPath, "utf8").split("\n");
|
|
8351
8472
|
let best = null;
|
|
8352
8473
|
for (const line of lines) {
|
|
8353
8474
|
const trimmed = line.trim();
|
|
@@ -8373,12 +8494,12 @@ function recoverFinishedCursorRun(opts) {
|
|
|
8373
8494
|
return null;
|
|
8374
8495
|
}
|
|
8375
8496
|
}
|
|
8376
|
-
var
|
|
8497
|
+
var import_node_fs36, import_node_path32;
|
|
8377
8498
|
var init_cursor_recover = __esm({
|
|
8378
8499
|
"src/agents/cursor-recover.ts"() {
|
|
8379
8500
|
"use strict";
|
|
8380
|
-
|
|
8381
|
-
|
|
8501
|
+
import_node_fs36 = require("fs");
|
|
8502
|
+
import_node_path32 = require("path");
|
|
8382
8503
|
init_paths();
|
|
8383
8504
|
}
|
|
8384
8505
|
});
|
|
@@ -8390,14 +8511,14 @@ init_nested_electron_env();
|
|
|
8390
8511
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
8391
8512
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
8392
8513
|
var import_zod3 = require("zod");
|
|
8393
|
-
var
|
|
8514
|
+
var import_node_path33 = require("path");
|
|
8394
8515
|
|
|
8395
8516
|
// src/orchestrator/orchestrator.ts
|
|
8396
8517
|
var import_node_events = require("events");
|
|
8397
8518
|
|
|
8398
8519
|
// src/slack/outbound-watch.ts
|
|
8399
|
-
var
|
|
8400
|
-
var
|
|
8520
|
+
var import_node_fs9 = require("fs");
|
|
8521
|
+
var import_node_path9 = require("path");
|
|
8401
8522
|
init_paths();
|
|
8402
8523
|
init_private_file();
|
|
8403
8524
|
init_secure_file();
|
|
@@ -8440,19 +8561,19 @@ async function slackApi(token, method, params, fetchImpl) {
|
|
|
8440
8561
|
}
|
|
8441
8562
|
|
|
8442
8563
|
// src/slack/reply-target.ts
|
|
8443
|
-
var
|
|
8444
|
-
var
|
|
8564
|
+
var import_node_fs8 = require("fs");
|
|
8565
|
+
var import_node_path7 = require("path");
|
|
8445
8566
|
init_paths();
|
|
8446
8567
|
init_private_file();
|
|
8447
8568
|
init_secure_file();
|
|
8448
8569
|
function storePath() {
|
|
8449
|
-
return (0,
|
|
8570
|
+
return (0, import_node_path7.join)(appDataDir(), "slack-reply-to.json");
|
|
8450
8571
|
}
|
|
8451
8572
|
function readStore() {
|
|
8452
8573
|
const path = storePath();
|
|
8453
|
-
if (!(0,
|
|
8574
|
+
if (!(0, import_node_fs8.existsSync)(path)) return {};
|
|
8454
8575
|
try {
|
|
8455
|
-
const parsed = isSecureFileEncrypted(path) ? readSecureJson(path) : JSON.parse((0,
|
|
8576
|
+
const parsed = isSecureFileEncrypted(path) ? readSecureJson(path) : JSON.parse((0, import_node_fs8.readFileSync)(path, "utf8"));
|
|
8456
8577
|
return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
|
|
8457
8578
|
} catch {
|
|
8458
8579
|
return {};
|
|
@@ -8463,11 +8584,11 @@ function getSlackReplyTarget(threadId) {
|
|
|
8463
8584
|
}
|
|
8464
8585
|
|
|
8465
8586
|
// src/slack/workspaces.ts
|
|
8466
|
-
var
|
|
8587
|
+
var import_node_path8 = require("path");
|
|
8467
8588
|
init_paths();
|
|
8468
8589
|
init_secure_file();
|
|
8469
8590
|
function storePath2() {
|
|
8470
|
-
return (0,
|
|
8591
|
+
return (0, import_node_path8.join)(appDataDir(), "slack-workspaces.json");
|
|
8471
8592
|
}
|
|
8472
8593
|
function readStore2() {
|
|
8473
8594
|
try {
|
|
@@ -8537,7 +8658,7 @@ var POLL_INTERVAL_MS = 12e3;
|
|
|
8537
8658
|
var lastPollMs = 0;
|
|
8538
8659
|
var nameCache = /* @__PURE__ */ new Map();
|
|
8539
8660
|
function storePath3() {
|
|
8540
|
-
return (0,
|
|
8661
|
+
return (0, import_node_path9.join)(appDataDir(), "slack-outbound-watch.json");
|
|
8541
8662
|
}
|
|
8542
8663
|
function watchId(teamId, channelId, ts) {
|
|
8543
8664
|
return `${teamId}:${channelId}:${ts}`;
|
|
@@ -8567,9 +8688,9 @@ function tsNewer(a, b) {
|
|
|
8567
8688
|
}
|
|
8568
8689
|
function readStore3() {
|
|
8569
8690
|
const path = storePath3();
|
|
8570
|
-
if (!(0,
|
|
8691
|
+
if (!(0, import_node_fs9.existsSync)(path)) return [];
|
|
8571
8692
|
try {
|
|
8572
|
-
const parsed = isSecureFileEncrypted(path) ? readSecureJson(path) : JSON.parse((0,
|
|
8693
|
+
const parsed = isSecureFileEncrypted(path) ? readSecureJson(path) : JSON.parse((0, import_node_fs9.readFileSync)(path, "utf8"));
|
|
8573
8694
|
return Array.isArray(parsed?.watches) ? parsed.watches : [];
|
|
8574
8695
|
} catch {
|
|
8575
8696
|
return [];
|
|
@@ -8901,12 +9022,12 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
8901
9022
|
}
|
|
8902
9023
|
|
|
8903
9024
|
// src/orchestrator/orchestrator.ts
|
|
8904
|
-
var
|
|
9025
|
+
var import_node_fs37 = require("fs");
|
|
8905
9026
|
init_error_detail();
|
|
8906
9027
|
|
|
8907
9028
|
// src/agents/spawn.ts
|
|
8908
|
-
var
|
|
8909
|
-
var
|
|
9029
|
+
var import_node_readline2 = require("readline");
|
|
9030
|
+
var import_execa3 = require("execa");
|
|
8910
9031
|
init_worktree();
|
|
8911
9032
|
init_git_auth_mode();
|
|
8912
9033
|
init_app_settings();
|
|
@@ -9182,7 +9303,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
9182
9303
|
const detail = err instanceof Error ? err.message : String(err);
|
|
9183
9304
|
console.warn(`[sideboard] git auth env failed (${thread.worktreePath}): ${detail}`);
|
|
9184
9305
|
}
|
|
9185
|
-
const child = (0,
|
|
9306
|
+
const child = (0, import_execa3.execa)(cmd.file, cmd.args, {
|
|
9186
9307
|
cwd: cmd.cwd,
|
|
9187
9308
|
env,
|
|
9188
9309
|
reject: false,
|
|
@@ -9202,7 +9323,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
9202
9323
|
let usage = null;
|
|
9203
9324
|
const consume = (stream, kind) => {
|
|
9204
9325
|
if (!stream) return;
|
|
9205
|
-
const rl = (0,
|
|
9326
|
+
const rl = (0, import_node_readline2.createInterface)({ input: stream, crlfDelay: Infinity });
|
|
9206
9327
|
rl.on("line", (line) => {
|
|
9207
9328
|
if (kind === "stderr") {
|
|
9208
9329
|
onEvent({ type: "stderr", data: line });
|
|
@@ -9387,13 +9508,15 @@ function shouldAutoArchiveOnPrMerge(opts) {
|
|
|
9387
9508
|
}
|
|
9388
9509
|
|
|
9389
9510
|
// src/hook/conductor.ts
|
|
9390
|
-
var
|
|
9511
|
+
var import_node_fs22 = require("fs");
|
|
9391
9512
|
var import_node_net = require("net");
|
|
9392
|
-
var
|
|
9393
|
-
var
|
|
9394
|
-
var
|
|
9513
|
+
var import_node_path20 = require("path");
|
|
9514
|
+
var import_execa4 = require("execa");
|
|
9515
|
+
var import_node_readline3 = require("readline");
|
|
9395
9516
|
init_settings();
|
|
9396
9517
|
init_nested_electron_env();
|
|
9518
|
+
init_convention_setup();
|
|
9519
|
+
init_cursor_worktrees();
|
|
9397
9520
|
init_git_auth_mode();
|
|
9398
9521
|
init_nested_electron_env();
|
|
9399
9522
|
var PORT_RANGE_SIZE = 10;
|
|
@@ -9402,9 +9525,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
9402
9525
|
return new RegExp(`^${escaped}$`).test(name);
|
|
9403
9526
|
}
|
|
9404
9527
|
function readWorktreeInclude(repoPath) {
|
|
9405
|
-
const path = (0,
|
|
9406
|
-
if (!(0,
|
|
9407
|
-
return (0,
|
|
9528
|
+
const path = (0, import_node_path20.join)(repoPath, ".worktreeinclude");
|
|
9529
|
+
if (!(0, import_node_fs22.existsSync)(path)) return [];
|
|
9530
|
+
return (0, import_node_fs22.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
9408
9531
|
}
|
|
9409
9532
|
function resolveFilesToCopy(repoPath) {
|
|
9410
9533
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -9414,10 +9537,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
9414
9537
|
if (settings?.fileIncludeGlobs?.length) {
|
|
9415
9538
|
const matched = [];
|
|
9416
9539
|
try {
|
|
9417
|
-
for (const entry of (0,
|
|
9540
|
+
for (const entry of (0, import_node_fs22.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
9418
9541
|
if (!entry.isFile()) continue;
|
|
9419
9542
|
for (const glob of settings.fileIncludeGlobs) {
|
|
9420
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
9543
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path20.basename)(glob), entry.name)) {
|
|
9421
9544
|
matched.push(entry.name);
|
|
9422
9545
|
break;
|
|
9423
9546
|
}
|
|
@@ -9429,7 +9552,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
9429
9552
|
}
|
|
9430
9553
|
const defaults = [];
|
|
9431
9554
|
try {
|
|
9432
|
-
for (const entry of (0,
|
|
9555
|
+
for (const entry of (0, import_node_fs22.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
9433
9556
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
9434
9557
|
defaults.push(entry.name);
|
|
9435
9558
|
}
|
|
@@ -9443,11 +9566,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
9443
9566
|
const patterns = resolveFilesToCopy(repoPath);
|
|
9444
9567
|
const copied = [];
|
|
9445
9568
|
for (const rel of patterns) {
|
|
9446
|
-
const src = (0,
|
|
9447
|
-
if (!(0,
|
|
9448
|
-
const dest = (0,
|
|
9449
|
-
(0,
|
|
9450
|
-
(0,
|
|
9569
|
+
const src = (0, import_node_path20.join)(repoPath, rel);
|
|
9570
|
+
if (!(0, import_node_fs22.existsSync)(src)) continue;
|
|
9571
|
+
const dest = (0, import_node_path20.join)(worktreePath, rel);
|
|
9572
|
+
(0, import_node_fs22.mkdirSync)((0, import_node_path20.dirname)(dest), { recursive: true });
|
|
9573
|
+
(0, import_node_fs22.copyFileSync)(src, dest);
|
|
9451
9574
|
copied.push(rel);
|
|
9452
9575
|
}
|
|
9453
9576
|
return copied;
|
|
@@ -9457,7 +9580,7 @@ async function captureLoginEnv() {
|
|
|
9457
9580
|
if (cachedLoginEnv) return { ...cachedLoginEnv };
|
|
9458
9581
|
const shell = process.env.SHELL?.trim() || (process.platform === "darwin" ? "/bin/zsh" : "/bin/bash");
|
|
9459
9582
|
try {
|
|
9460
|
-
const result = await (0,
|
|
9583
|
+
const result = await (0, import_execa4.execa)(shell, ["-l", "-c", "env -0"], {
|
|
9461
9584
|
reject: false,
|
|
9462
9585
|
timeout: 5e3
|
|
9463
9586
|
});
|
|
@@ -9483,7 +9606,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
9483
9606
|
const env = stripNestedElectronEnv({
|
|
9484
9607
|
...baseEnv ?? process.env
|
|
9485
9608
|
});
|
|
9486
|
-
const name = opts.workspaceName ?? (0,
|
|
9609
|
+
const name = opts.workspaceName ?? (0, import_node_path20.basename)(opts.worktreePath);
|
|
9487
9610
|
const ports = opts.ports ?? [];
|
|
9488
9611
|
const primary = ports[0];
|
|
9489
9612
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -9510,7 +9633,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
9510
9633
|
}
|
|
9511
9634
|
function pipeLines(stream, onLine) {
|
|
9512
9635
|
if (!stream || !onLine) return;
|
|
9513
|
-
const rl = (0,
|
|
9636
|
+
const rl = (0, import_node_readline3.createInterface)({ input: stream });
|
|
9514
9637
|
rl.on("line", onLine);
|
|
9515
9638
|
}
|
|
9516
9639
|
function killScriptTree(child, ports = []) {
|
|
@@ -9518,7 +9641,7 @@ function killScriptTree(child, ports = []) {
|
|
|
9518
9641
|
if (pid) {
|
|
9519
9642
|
try {
|
|
9520
9643
|
if (process.platform === "win32") {
|
|
9521
|
-
void (0,
|
|
9644
|
+
void (0, import_execa4.execa)("taskkill", ["/pid", String(pid), "/T", "/F"], { reject: false });
|
|
9522
9645
|
} else {
|
|
9523
9646
|
process.kill(-pid, "SIGTERM");
|
|
9524
9647
|
setTimeout(() => {
|
|
@@ -9538,7 +9661,7 @@ function killScriptTree(child, ports = []) {
|
|
|
9538
9661
|
for (const port of ports) {
|
|
9539
9662
|
if (!Number.isFinite(port) || port <= 0) continue;
|
|
9540
9663
|
if (process.platform === "win32") {
|
|
9541
|
-
void (0,
|
|
9664
|
+
void (0, import_execa4.execa)(
|
|
9542
9665
|
"powershell",
|
|
9543
9666
|
[
|
|
9544
9667
|
"-NoProfile",
|
|
@@ -9548,7 +9671,7 @@ function killScriptTree(child, ports = []) {
|
|
|
9548
9671
|
{ reject: false }
|
|
9549
9672
|
);
|
|
9550
9673
|
} else {
|
|
9551
|
-
void (0,
|
|
9674
|
+
void (0, import_execa4.execa)(
|
|
9552
9675
|
"zsh",
|
|
9553
9676
|
["-lc", `pids=$(lsof -tiTCP:${port} -sTCP:LISTEN 2>/dev/null); [ -n "$pids" ] && kill -TERM $pids 2>/dev/null; true`],
|
|
9554
9677
|
{ reject: false }
|
|
@@ -9573,7 +9696,7 @@ async function spawnWorkspaceScript(command, opts) {
|
|
|
9573
9696
|
} catch {
|
|
9574
9697
|
}
|
|
9575
9698
|
const shell = process.platform === "darwin" ? "zsh" : "bash";
|
|
9576
|
-
const child = (0,
|
|
9699
|
+
const child = (0, import_execa4.execa)(shell, ["-lc", command], {
|
|
9577
9700
|
cwd: opts.worktreePath,
|
|
9578
9701
|
reject: false,
|
|
9579
9702
|
env,
|
|
@@ -9591,6 +9714,14 @@ async function spawnWorkspaceScript(command, opts) {
|
|
|
9591
9714
|
child
|
|
9592
9715
|
};
|
|
9593
9716
|
}
|
|
9717
|
+
async function attachAbort(handle, signal) {
|
|
9718
|
+
if (signal) {
|
|
9719
|
+
const onAbort = () => handle.kill();
|
|
9720
|
+
if (signal.aborted) onAbort();
|
|
9721
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
9722
|
+
}
|
|
9723
|
+
return handle.done;
|
|
9724
|
+
}
|
|
9594
9725
|
async function runSetupScript(repoPath, worktreePath, onLine, opts) {
|
|
9595
9726
|
const settings = loadWorkspaceSettings(worktreePath, repoPath);
|
|
9596
9727
|
if (!settings?.setup) return { ran: false, exitCode: null, source: null };
|
|
@@ -9600,12 +9731,7 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
|
|
|
9600
9731
|
defaultBranch: opts?.defaultBranch,
|
|
9601
9732
|
onLine
|
|
9602
9733
|
});
|
|
9603
|
-
|
|
9604
|
-
const onAbort = () => handle.kill();
|
|
9605
|
-
if (opts.signal.aborted) onAbort();
|
|
9606
|
-
else opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
9607
|
-
}
|
|
9608
|
-
const exitCode = await handle.done;
|
|
9734
|
+
const exitCode = await attachAbort(handle, opts?.signal);
|
|
9609
9735
|
return {
|
|
9610
9736
|
ran: true,
|
|
9611
9737
|
exitCode,
|
|
@@ -9613,6 +9739,34 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
|
|
|
9613
9739
|
kill: handle.kill
|
|
9614
9740
|
};
|
|
9615
9741
|
}
|
|
9742
|
+
async function runConventionSetup(repoPath, worktreePath, onLine, opts) {
|
|
9743
|
+
const found = findConventionSetup(worktreePath, repoPath);
|
|
9744
|
+
if (!found) return { ran: false, exitCode: null, source: null };
|
|
9745
|
+
onLine?.(`[setup] ${found.source}`);
|
|
9746
|
+
const handle = await spawnWorkspaceScript(found.command, {
|
|
9747
|
+
worktreePath,
|
|
9748
|
+
repoPath,
|
|
9749
|
+
defaultBranch: opts?.defaultBranch,
|
|
9750
|
+
onLine
|
|
9751
|
+
});
|
|
9752
|
+
const exitCode = await attachAbort(handle, opts?.signal);
|
|
9753
|
+
return {
|
|
9754
|
+
ran: true,
|
|
9755
|
+
exitCode,
|
|
9756
|
+
source: found.source,
|
|
9757
|
+
kill: handle.kill
|
|
9758
|
+
};
|
|
9759
|
+
}
|
|
9760
|
+
async function runWorkspaceSetup(repoPath, worktreePath, onLine, opts) {
|
|
9761
|
+
let setup = await runSetupScript(repoPath, worktreePath, onLine, opts);
|
|
9762
|
+
if (!setup.ran) {
|
|
9763
|
+
setup = await runCursorWorktreeSetup(repoPath, worktreePath, onLine);
|
|
9764
|
+
}
|
|
9765
|
+
if (!setup.ran) {
|
|
9766
|
+
setup = await runConventionSetup(repoPath, worktreePath, onLine, opts);
|
|
9767
|
+
}
|
|
9768
|
+
return setup;
|
|
9769
|
+
}
|
|
9616
9770
|
async function runArchiveScript(repoPath, worktreePath, onLine) {
|
|
9617
9771
|
const settings = loadWorkspaceSettings(worktreePath, repoPath);
|
|
9618
9772
|
if (!settings?.archive) return { ran: false, exitCode: null };
|
|
@@ -9705,75 +9859,9 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
9705
9859
|
};
|
|
9706
9860
|
}
|
|
9707
9861
|
|
|
9708
|
-
// src/hook/cursor-worktrees.ts
|
|
9709
|
-
var import_node_fs21 = require("fs");
|
|
9710
|
-
var import_node_path19 = require("path");
|
|
9711
|
-
var import_execa4 = require("execa");
|
|
9712
|
-
var import_node_readline3 = require("readline");
|
|
9713
|
-
function loadCursorWorktreesJson(rootPath) {
|
|
9714
|
-
const path = (0, import_node_path19.join)(rootPath, ".cursor", "worktrees.json");
|
|
9715
|
-
if (!(0, import_node_fs21.existsSync)(path)) return null;
|
|
9716
|
-
try {
|
|
9717
|
-
return JSON.parse((0, import_node_fs21.readFileSync)(path, "utf8"));
|
|
9718
|
-
} catch {
|
|
9719
|
-
return null;
|
|
9720
|
-
}
|
|
9721
|
-
}
|
|
9722
|
-
function resolveSetupSpec(config) {
|
|
9723
|
-
if (process.platform === "win32") {
|
|
9724
|
-
return config["setup-worktree-windows"] ?? config["setup-worktree"] ?? null;
|
|
9725
|
-
}
|
|
9726
|
-
return config["setup-worktree-unix"] ?? config["setup-worktree"] ?? null;
|
|
9727
|
-
}
|
|
9728
|
-
async function runCursorWorktreeSetup(repoPath, worktreePath, onLine) {
|
|
9729
|
-
const fromWorktree = loadCursorWorktreesJson(worktreePath);
|
|
9730
|
-
const fromRepo = worktreePath !== repoPath ? loadCursorWorktreesJson(repoPath) : null;
|
|
9731
|
-
const config = fromWorktree ?? fromRepo;
|
|
9732
|
-
if (!config) return { ran: false, exitCode: null, source: null };
|
|
9733
|
-
const spec = resolveSetupSpec(config);
|
|
9734
|
-
if (!spec) return { ran: false, exitCode: null, source: null };
|
|
9735
|
-
const sourceLabel = fromWorktree ? ".cursor/worktrees.json (worktree)" : ".cursor/worktrees.json (main repo)";
|
|
9736
|
-
const env = {
|
|
9737
|
-
...process.env,
|
|
9738
|
-
ROOT_WORKTREE_PATH: repoPath
|
|
9739
|
-
};
|
|
9740
|
-
if (process.platform === "win32") {
|
|
9741
|
-
env.ROOT_WORKTREE_PATH = repoPath;
|
|
9742
|
-
}
|
|
9743
|
-
const commands = Array.isArray(spec) ? spec : [spec.endsWith(".sh") || spec.endsWith(".ps1") ? (0, import_node_path19.join)(
|
|
9744
|
-
fromWorktree ? worktreePath : repoPath,
|
|
9745
|
-
".cursor",
|
|
9746
|
-
spec
|
|
9747
|
-
) : spec];
|
|
9748
|
-
let lastExit = 0;
|
|
9749
|
-
for (const command of commands) {
|
|
9750
|
-
const isScriptPath = typeof spec === "string" && (spec.endsWith(".sh") || spec.endsWith(".ps1"));
|
|
9751
|
-
const shell = process.platform === "win32" ? "powershell" : "bash";
|
|
9752
|
-
const args = process.platform === "win32" ? isScriptPath ? ["-File", command] : ["-Command", command] : isScriptPath ? [command] : ["-lc", command];
|
|
9753
|
-
onLine?.(`[cursor setup] ${command}`);
|
|
9754
|
-
const child = (0, import_execa4.execa)(shell, args, {
|
|
9755
|
-
cwd: worktreePath,
|
|
9756
|
-
reject: false,
|
|
9757
|
-
env
|
|
9758
|
-
});
|
|
9759
|
-
if (child.stdout && onLine) {
|
|
9760
|
-
const rl = (0, import_node_readline3.createInterface)({ input: child.stdout });
|
|
9761
|
-
rl.on("line", onLine);
|
|
9762
|
-
}
|
|
9763
|
-
if (child.stderr && onLine) {
|
|
9764
|
-
const rl = (0, import_node_readline3.createInterface)({ input: child.stderr });
|
|
9765
|
-
rl.on("line", onLine);
|
|
9766
|
-
}
|
|
9767
|
-
const result = await child;
|
|
9768
|
-
lastExit = result.exitCode ?? null;
|
|
9769
|
-
if (lastExit !== 0 && lastExit !== null) break;
|
|
9770
|
-
}
|
|
9771
|
-
return { ran: true, exitCode: lastExit, source: sourceLabel };
|
|
9772
|
-
}
|
|
9773
|
-
|
|
9774
9862
|
// src/git/orphan-cleanup.ts
|
|
9775
|
-
var
|
|
9776
|
-
var
|
|
9863
|
+
var import_node_fs23 = require("fs");
|
|
9864
|
+
var import_node_path21 = require("path");
|
|
9777
9865
|
init_worktree();
|
|
9778
9866
|
init_thread_store();
|
|
9779
9867
|
init_paths();
|
|
@@ -9788,9 +9876,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
9788
9876
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
9789
9877
|
);
|
|
9790
9878
|
const homeRoot = sideboardWorkspacesDir();
|
|
9791
|
-
if ((0,
|
|
9879
|
+
if ((0, import_node_fs23.existsSync)(homeRoot)) {
|
|
9792
9880
|
try {
|
|
9793
|
-
for (const entry of (0,
|
|
9881
|
+
for (const entry of (0, import_node_fs23.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
9794
9882
|
if (!entry.isDirectory()) continue;
|
|
9795
9883
|
void entry;
|
|
9796
9884
|
}
|
|
@@ -9800,7 +9888,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
9800
9888
|
const orphans = [];
|
|
9801
9889
|
const seen = /* @__PURE__ */ new Set();
|
|
9802
9890
|
for (const repoPath of repos) {
|
|
9803
|
-
if (!repoPath || !(0,
|
|
9891
|
+
if (!repoPath || !(0, import_node_fs23.existsSync)(repoPath)) continue;
|
|
9804
9892
|
try {
|
|
9805
9893
|
const wts = await listWorktrees(repoPath);
|
|
9806
9894
|
for (const wt of wts) {
|
|
@@ -9811,7 +9899,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
9811
9899
|
seen.add(path);
|
|
9812
9900
|
let mtimeMs = 0;
|
|
9813
9901
|
try {
|
|
9814
|
-
mtimeMs = (0,
|
|
9902
|
+
mtimeMs = (0, import_node_fs23.statSync)(path).mtimeMs;
|
|
9815
9903
|
} catch {
|
|
9816
9904
|
mtimeMs = 0;
|
|
9817
9905
|
}
|
|
@@ -9821,16 +9909,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
9821
9909
|
}
|
|
9822
9910
|
try {
|
|
9823
9911
|
const root = worktreesRoot(repoPath);
|
|
9824
|
-
if ((0,
|
|
9825
|
-
for (const entry of (0,
|
|
9912
|
+
if ((0, import_node_fs23.existsSync)(root)) {
|
|
9913
|
+
for (const entry of (0, import_node_fs23.readdirSync)(root, { withFileTypes: true })) {
|
|
9826
9914
|
if (!entry.isDirectory()) continue;
|
|
9827
|
-
const path = (0,
|
|
9915
|
+
const path = (0, import_node_path21.join)(root, entry.name).replace(/\/$/, "");
|
|
9828
9916
|
if (known.has(path) || seen.has(path)) continue;
|
|
9829
|
-
if (!(0,
|
|
9917
|
+
if (!(0, import_node_fs23.existsSync)((0, import_node_path21.join)(path, ".git"))) continue;
|
|
9830
9918
|
seen.add(path);
|
|
9831
9919
|
let mtimeMs = 0;
|
|
9832
9920
|
try {
|
|
9833
|
-
mtimeMs = (0,
|
|
9921
|
+
mtimeMs = (0, import_node_fs23.statSync)(path).mtimeMs;
|
|
9834
9922
|
} catch {
|
|
9835
9923
|
mtimeMs = Date.now();
|
|
9836
9924
|
}
|
|
@@ -9967,8 +10055,8 @@ async function applyThreadIntoMain(thread, opts) {
|
|
|
9967
10055
|
}
|
|
9968
10056
|
|
|
9969
10057
|
// src/git/clone-repo.ts
|
|
9970
|
-
var
|
|
9971
|
-
var
|
|
10058
|
+
var import_node_fs25 = require("fs");
|
|
10059
|
+
var import_node_path23 = require("path");
|
|
9972
10060
|
var import_execa6 = require("execa");
|
|
9973
10061
|
init_paths();
|
|
9974
10062
|
init_workspaces();
|
|
@@ -9978,12 +10066,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
9978
10066
|
if (!url) throw new Error("Clone URL is required");
|
|
9979
10067
|
let name = opts.name?.trim();
|
|
9980
10068
|
if (!name) {
|
|
9981
|
-
const leaf = (0,
|
|
10069
|
+
const leaf = (0, import_node_path23.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
9982
10070
|
name = leaf || "repo";
|
|
9983
10071
|
}
|
|
9984
10072
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
9985
|
-
const dest = (0,
|
|
9986
|
-
if ((0,
|
|
10073
|
+
const dest = (0, import_node_path23.join)(sideboardReposDir(), name);
|
|
10074
|
+
if ((0, import_node_fs25.existsSync)(dest)) {
|
|
9987
10075
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
9988
10076
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
9989
10077
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -10003,7 +10091,7 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
10003
10091
|
init_thread_store();
|
|
10004
10092
|
|
|
10005
10093
|
// src/threads/create.ts
|
|
10006
|
-
var
|
|
10094
|
+
var import_node_fs26 = require("fs");
|
|
10007
10095
|
|
|
10008
10096
|
// src/detect/detect.ts
|
|
10009
10097
|
init_agents();
|
|
@@ -10048,7 +10136,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
10048
10136
|
});
|
|
10049
10137
|
await requireAgent(resolved.agent);
|
|
10050
10138
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
10051
|
-
if (!(0,
|
|
10139
|
+
if (!(0, import_node_fs26.existsSync)(repoPath)) {
|
|
10052
10140
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
10053
10141
|
}
|
|
10054
10142
|
let sourceRef = input.sourceRef;
|
|
@@ -10511,8 +10599,8 @@ function forkChatTab(input) {
|
|
|
10511
10599
|
|
|
10512
10600
|
// src/review/request-review.ts
|
|
10513
10601
|
var import_node_crypto5 = require("crypto");
|
|
10514
|
-
var
|
|
10515
|
-
var
|
|
10602
|
+
var import_node_fs27 = require("fs");
|
|
10603
|
+
var import_node_path24 = require("path");
|
|
10516
10604
|
init_global_workspace();
|
|
10517
10605
|
init_thread_store();
|
|
10518
10606
|
|
|
@@ -10660,22 +10748,22 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
10660
10748
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
10661
10749
|
}
|
|
10662
10750
|
function readTextIfPresent(abs) {
|
|
10663
|
-
if (!(0,
|
|
10751
|
+
if (!(0, import_node_fs27.existsSync)(abs)) return null;
|
|
10664
10752
|
try {
|
|
10665
|
-
const content = (0,
|
|
10753
|
+
const content = (0, import_node_fs27.readFileSync)(abs, "utf8");
|
|
10666
10754
|
return content.trim() ? content : null;
|
|
10667
10755
|
} catch {
|
|
10668
10756
|
return null;
|
|
10669
10757
|
}
|
|
10670
10758
|
}
|
|
10671
10759
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
10672
|
-
const gitignoreAbs = (0,
|
|
10673
|
-
if ((0,
|
|
10674
|
-
(0,
|
|
10675
|
-
(0,
|
|
10760
|
+
const gitignoreAbs = (0, import_node_path24.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
10761
|
+
if ((0, import_node_fs27.existsSync)(gitignoreAbs)) return;
|
|
10762
|
+
(0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(gitignoreAbs), { recursive: true });
|
|
10763
|
+
(0, import_node_fs27.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
10676
10764
|
}
|
|
10677
10765
|
function resolveReviewGuidelines(worktreePath) {
|
|
10678
|
-
const repoAbs = (0,
|
|
10766
|
+
const repoAbs = (0, import_node_path24.join)(worktreePath, REPO_REVIEW_PATH);
|
|
10679
10767
|
const repoContent = readTextIfPresent(repoAbs);
|
|
10680
10768
|
if (repoContent) {
|
|
10681
10769
|
return {
|
|
@@ -10685,7 +10773,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
10685
10773
|
source: "repo"
|
|
10686
10774
|
};
|
|
10687
10775
|
}
|
|
10688
|
-
const localAbs = (0,
|
|
10776
|
+
const localAbs = (0, import_node_path24.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
10689
10777
|
const localContent = readTextIfPresent(localAbs);
|
|
10690
10778
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
10691
10779
|
return {
|
|
@@ -10695,7 +10783,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
10695
10783
|
source: "local"
|
|
10696
10784
|
};
|
|
10697
10785
|
}
|
|
10698
|
-
const legacyAbs = (0,
|
|
10786
|
+
const legacyAbs = (0, import_node_path24.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
10699
10787
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
10700
10788
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
10701
10789
|
return {
|
|
@@ -10706,8 +10794,8 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
10706
10794
|
};
|
|
10707
10795
|
}
|
|
10708
10796
|
ensureAttachmentsGitignore(worktreePath);
|
|
10709
|
-
(0,
|
|
10710
|
-
(0,
|
|
10797
|
+
(0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(localAbs), { recursive: true });
|
|
10798
|
+
(0, import_node_fs27.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
|
|
10711
10799
|
return {
|
|
10712
10800
|
path: REVIEW_REQUEST_PATH,
|
|
10713
10801
|
name: REVIEW_REQUEST_NAME,
|
|
@@ -10907,20 +10995,20 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
|
|
|
10907
10995
|
|
|
10908
10996
|
// src/threads/adopt.ts
|
|
10909
10997
|
var import_node_child_process3 = require("child_process");
|
|
10910
|
-
var
|
|
10998
|
+
var import_node_fs28 = require("fs");
|
|
10911
10999
|
var import_node_os8 = require("os");
|
|
10912
|
-
var
|
|
11000
|
+
var import_node_path25 = require("path");
|
|
10913
11001
|
var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
|
|
10914
11002
|
init_worktree();
|
|
10915
11003
|
init_thread_store();
|
|
10916
|
-
var CONDUCTOR_APP_SUPPORT = (0,
|
|
11004
|
+
var CONDUCTOR_APP_SUPPORT = (0, import_node_path25.join)(
|
|
10917
11005
|
process.env.HOME ?? "",
|
|
10918
11006
|
"Library",
|
|
10919
11007
|
"Application Support",
|
|
10920
11008
|
"com.conductor.app"
|
|
10921
11009
|
);
|
|
10922
|
-
var CONDUCTOR_DB = (0,
|
|
10923
|
-
var CURSOR_SDK_STORE = (0,
|
|
11010
|
+
var CONDUCTOR_DB = (0, import_node_path25.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
11011
|
+
var CURSOR_SDK_STORE = (0, import_node_path25.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
10924
11012
|
function mapAgentType(raw) {
|
|
10925
11013
|
if (!raw) return null;
|
|
10926
11014
|
const v = raw.toLowerCase();
|
|
@@ -10932,21 +11020,21 @@ function mapAgentType(raw) {
|
|
|
10932
11020
|
return null;
|
|
10933
11021
|
}
|
|
10934
11022
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
10935
|
-
if (!workspacePath || !(0,
|
|
11023
|
+
if (!workspacePath || !(0, import_node_fs28.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
10936
11024
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
10937
11025
|
let best = null;
|
|
10938
11026
|
let hashes;
|
|
10939
11027
|
try {
|
|
10940
|
-
hashes = (0,
|
|
11028
|
+
hashes = (0, import_node_fs28.readdirSync)(CURSOR_SDK_STORE);
|
|
10941
11029
|
} catch {
|
|
10942
11030
|
return null;
|
|
10943
11031
|
}
|
|
10944
11032
|
for (const hash of hashes) {
|
|
10945
|
-
const agentsFile = (0,
|
|
10946
|
-
if (!(0,
|
|
11033
|
+
const agentsFile = (0, import_node_path25.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
11034
|
+
if (!(0, import_node_fs28.existsSync)(agentsFile)) continue;
|
|
10947
11035
|
let text3;
|
|
10948
11036
|
try {
|
|
10949
|
-
text3 = (0,
|
|
11037
|
+
text3 = (0, import_node_fs28.readFileSync)(agentsFile, "utf8");
|
|
10950
11038
|
} catch {
|
|
10951
11039
|
continue;
|
|
10952
11040
|
}
|
|
@@ -10970,7 +11058,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
10970
11058
|
return best?.agentId ?? null;
|
|
10971
11059
|
}
|
|
10972
11060
|
async function adoptThread(input) {
|
|
10973
|
-
if (!(0,
|
|
11061
|
+
if (!(0, import_node_fs28.existsSync)(input.worktreePath)) {
|
|
10974
11062
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
10975
11063
|
}
|
|
10976
11064
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -10994,18 +11082,18 @@ async function adoptThread(input) {
|
|
|
10994
11082
|
return thread;
|
|
10995
11083
|
}
|
|
10996
11084
|
function listConductorWorkspaces() {
|
|
10997
|
-
if (!(0,
|
|
11085
|
+
if (!(0, import_node_fs28.existsSync)(CONDUCTOR_DB)) {
|
|
10998
11086
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
10999
11087
|
}
|
|
11000
|
-
const tmp = (0,
|
|
11001
|
-
const snapshot = (0,
|
|
11088
|
+
const tmp = (0, import_node_fs28.mkdtempSync)((0, import_node_path25.join)((0, import_node_os8.tmpdir)(), "sideboard-conductor-"));
|
|
11089
|
+
const snapshot = (0, import_node_path25.join)(tmp, "conductor.db");
|
|
11002
11090
|
try {
|
|
11003
|
-
(0,
|
|
11091
|
+
(0, import_node_fs28.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
11004
11092
|
for (const suffix of ["-wal", "-shm"]) {
|
|
11005
11093
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
11006
|
-
if ((0,
|
|
11094
|
+
if ((0, import_node_fs28.existsSync)(src)) {
|
|
11007
11095
|
try {
|
|
11008
|
-
(0,
|
|
11096
|
+
(0, import_node_fs28.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
11009
11097
|
} catch {
|
|
11010
11098
|
}
|
|
11011
11099
|
}
|
|
@@ -11081,22 +11169,22 @@ function listConductorWorkspaces() {
|
|
|
11081
11169
|
db.close();
|
|
11082
11170
|
}
|
|
11083
11171
|
} finally {
|
|
11084
|
-
(0,
|
|
11172
|
+
(0, import_node_fs28.rmSync)(tmp, { recursive: true, force: true });
|
|
11085
11173
|
}
|
|
11086
11174
|
}
|
|
11087
11175
|
function importConductorWorkspace(workspaceId) {
|
|
11088
|
-
if (!(0,
|
|
11176
|
+
if (!(0, import_node_fs28.existsSync)(CONDUCTOR_DB)) {
|
|
11089
11177
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
11090
11178
|
}
|
|
11091
|
-
const tmp = (0,
|
|
11092
|
-
const snapshot = (0,
|
|
11179
|
+
const tmp = (0, import_node_fs28.mkdtempSync)((0, import_node_path25.join)((0, import_node_os8.tmpdir)(), "sideboard-conductor-"));
|
|
11180
|
+
const snapshot = (0, import_node_path25.join)(tmp, "conductor.db");
|
|
11093
11181
|
try {
|
|
11094
|
-
(0,
|
|
11182
|
+
(0, import_node_fs28.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
11095
11183
|
for (const suffix of ["-wal", "-shm"]) {
|
|
11096
11184
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
11097
|
-
if ((0,
|
|
11185
|
+
if ((0, import_node_fs28.existsSync)(src)) {
|
|
11098
11186
|
try {
|
|
11099
|
-
(0,
|
|
11187
|
+
(0, import_node_fs28.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
11100
11188
|
} catch {
|
|
11101
11189
|
}
|
|
11102
11190
|
}
|
|
@@ -11114,7 +11202,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
11114
11202
|
).get(workspaceId);
|
|
11115
11203
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
11116
11204
|
const worktreePath = String(row.workspacePath);
|
|
11117
|
-
if (!(0,
|
|
11205
|
+
if (!(0, import_node_fs28.existsSync)(worktreePath)) {
|
|
11118
11206
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
11119
11207
|
}
|
|
11120
11208
|
let sessionId = null;
|
|
@@ -11177,7 +11265,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
11177
11265
|
db.close();
|
|
11178
11266
|
}
|
|
11179
11267
|
} finally {
|
|
11180
|
-
(0,
|
|
11268
|
+
(0, import_node_fs28.rmSync)(tmp, { recursive: true, force: true });
|
|
11181
11269
|
}
|
|
11182
11270
|
}
|
|
11183
11271
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
@@ -11185,7 +11273,7 @@ async function importConductorWorkspaceAsync(workspaceId) {
|
|
|
11185
11273
|
}
|
|
11186
11274
|
|
|
11187
11275
|
// src/threads/stack-layers.ts
|
|
11188
|
-
var
|
|
11276
|
+
var import_node_fs29 = require("fs");
|
|
11189
11277
|
init_run();
|
|
11190
11278
|
init_stack();
|
|
11191
11279
|
init_worktree();
|
|
@@ -11253,7 +11341,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
11253
11341
|
let createdWorktree = false;
|
|
11254
11342
|
const trees = await listWorktrees(repoPath);
|
|
11255
11343
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
11256
|
-
if (checkedOut?.path && (0,
|
|
11344
|
+
if (checkedOut?.path && (0, import_node_fs29.existsSync)(checkedOut.path)) {
|
|
11257
11345
|
if (input.reuseExistingWorktree !== false) {
|
|
11258
11346
|
worktreePath = checkedOut.path;
|
|
11259
11347
|
} else {
|
|
@@ -11395,7 +11483,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
11395
11483
|
async function createPrStack(input, onSetupLine) {
|
|
11396
11484
|
await requireAgent(input.agent);
|
|
11397
11485
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
11398
|
-
if (!(0,
|
|
11486
|
+
if (!(0, import_node_fs29.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
11399
11487
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
11400
11488
|
const status = await detectGhStack(repoPath);
|
|
11401
11489
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -11462,7 +11550,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
11462
11550
|
}
|
|
11463
11551
|
}
|
|
11464
11552
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
11465
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
11553
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs29.existsSync)(bootstrap.worktreePath)) {
|
|
11466
11554
|
try {
|
|
11467
11555
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
11468
11556
|
deleteBranch: bootstrap.branchName
|
|
@@ -11477,12 +11565,12 @@ async function createPrStack(input, onSetupLine) {
|
|
|
11477
11565
|
init_worktree();
|
|
11478
11566
|
|
|
11479
11567
|
// src/diff/diff.ts
|
|
11480
|
-
var
|
|
11481
|
-
var
|
|
11568
|
+
var import_node_fs30 = require("fs");
|
|
11569
|
+
var import_node_path26 = require("path");
|
|
11482
11570
|
init_run();
|
|
11483
11571
|
init_worktree();
|
|
11484
11572
|
async function inspectGitWorktree(worktreePath) {
|
|
11485
|
-
if (!worktreePath || !(0,
|
|
11573
|
+
if (!worktreePath || !(0, import_node_fs30.existsSync)(worktreePath)) return "missing_worktree";
|
|
11486
11574
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
11487
11575
|
reject: false
|
|
11488
11576
|
});
|
|
@@ -11490,7 +11578,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
11490
11578
|
return "ok";
|
|
11491
11579
|
}
|
|
11492
11580
|
async function initializeGitRepository(worktreePath) {
|
|
11493
|
-
if (!worktreePath || !(0,
|
|
11581
|
+
if (!worktreePath || !(0, import_node_fs30.existsSync)(worktreePath)) {
|
|
11494
11582
|
throw new Error("Worktree not found");
|
|
11495
11583
|
}
|
|
11496
11584
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -11625,11 +11713,11 @@ new file mode 100644
|
|
|
11625
11713
|
};
|
|
11626
11714
|
}
|
|
11627
11715
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
11628
|
-
const abs = (0,
|
|
11716
|
+
const abs = (0, import_node_path26.join)(worktreePath, path);
|
|
11629
11717
|
try {
|
|
11630
|
-
const st = (0,
|
|
11718
|
+
const st = (0, import_node_fs30.statSync)(abs);
|
|
11631
11719
|
if (st.isFile() && st.size > maxHunk) {
|
|
11632
|
-
const buf = (0,
|
|
11720
|
+
const buf = (0, import_node_fs30.readFileSync)(abs).subarray(0, maxHunk);
|
|
11633
11721
|
return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
|
|
11634
11722
|
}
|
|
11635
11723
|
} catch {
|
|
@@ -12130,8 +12218,8 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
|
12130
12218
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
12131
12219
|
assertSafeRelativePath(relativePath);
|
|
12132
12220
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
12133
|
-
const abs = (0,
|
|
12134
|
-
const st = (0,
|
|
12221
|
+
const abs = (0, import_node_path26.join)(worktreePath, relativePath);
|
|
12222
|
+
const st = (0, import_node_fs30.statSync)(abs);
|
|
12135
12223
|
if (!st.isFile()) {
|
|
12136
12224
|
throw new Error(`Not a file: ${relativePath}`);
|
|
12137
12225
|
}
|
|
@@ -12140,7 +12228,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
12140
12228
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
12141
12229
|
);
|
|
12142
12230
|
}
|
|
12143
|
-
const buf = (0,
|
|
12231
|
+
const buf = (0, import_node_fs30.readFileSync)(abs);
|
|
12144
12232
|
return {
|
|
12145
12233
|
path: relativePath,
|
|
12146
12234
|
contentBase64: buf.toString("base64"),
|
|
@@ -12150,12 +12238,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
12150
12238
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
12151
12239
|
assertSafeRelativePath(relativePath);
|
|
12152
12240
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
12153
|
-
const abs = (0,
|
|
12154
|
-
const st = (0,
|
|
12241
|
+
const abs = (0, import_node_path26.join)(worktreePath, relativePath);
|
|
12242
|
+
const st = (0, import_node_fs30.statSync)(abs);
|
|
12155
12243
|
if (!st.isFile()) {
|
|
12156
12244
|
throw new Error(`Not a file: ${relativePath}`);
|
|
12157
12245
|
}
|
|
12158
|
-
const buf = (0,
|
|
12246
|
+
const buf = (0, import_node_fs30.readFileSync)(abs);
|
|
12159
12247
|
if (isImageRelativePath(relativePath)) {
|
|
12160
12248
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
12161
12249
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -12198,9 +12286,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
12198
12286
|
}
|
|
12199
12287
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
12200
12288
|
assertSafeRelativePath(relativePath);
|
|
12201
|
-
const abs = (0,
|
|
12202
|
-
(0,
|
|
12203
|
-
(0,
|
|
12289
|
+
const abs = (0, import_node_path26.join)(worktreePath, relativePath);
|
|
12290
|
+
(0, import_node_fs30.mkdirSync)((0, import_node_path26.dirname)(abs), { recursive: true });
|
|
12291
|
+
(0, import_node_fs30.writeFileSync)(abs, content, "utf8");
|
|
12204
12292
|
return { path: relativePath };
|
|
12205
12293
|
}
|
|
12206
12294
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -12304,9 +12392,9 @@ async function confirmLand(thread, opts) {
|
|
|
12304
12392
|
}
|
|
12305
12393
|
|
|
12306
12394
|
// src/skills/discover.ts
|
|
12307
|
-
var
|
|
12395
|
+
var import_node_fs31 = require("fs");
|
|
12308
12396
|
var import_node_os9 = require("os");
|
|
12309
|
-
var
|
|
12397
|
+
var import_node_path27 = require("path");
|
|
12310
12398
|
function toCommand(name) {
|
|
12311
12399
|
return name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
12312
12400
|
}
|
|
@@ -12338,7 +12426,7 @@ function parseFrontmatter(content) {
|
|
|
12338
12426
|
}
|
|
12339
12427
|
function readSkill(skillMd, source) {
|
|
12340
12428
|
try {
|
|
12341
|
-
const content = (0,
|
|
12429
|
+
const content = (0, import_node_fs31.readFileSync)(skillMd, "utf8");
|
|
12342
12430
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
12343
12431
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
12344
12432
|
const name = fmName || dirName;
|
|
@@ -12357,19 +12445,19 @@ function readSkill(skillMd, source) {
|
|
|
12357
12445
|
}
|
|
12358
12446
|
}
|
|
12359
12447
|
function scanSkillsDir(dir, source, out) {
|
|
12360
|
-
if (!(0,
|
|
12448
|
+
if (!(0, import_node_fs31.existsSync)(dir)) return;
|
|
12361
12449
|
let entries;
|
|
12362
12450
|
try {
|
|
12363
|
-
entries = (0,
|
|
12451
|
+
entries = (0, import_node_fs31.readdirSync)(dir);
|
|
12364
12452
|
} catch {
|
|
12365
12453
|
return;
|
|
12366
12454
|
}
|
|
12367
12455
|
for (const entry of entries) {
|
|
12368
12456
|
if (entry.startsWith(".")) continue;
|
|
12369
|
-
const skillMd = (0,
|
|
12370
|
-
if (!(0,
|
|
12457
|
+
const skillMd = (0, import_node_path27.join)(dir, entry, "SKILL.md");
|
|
12458
|
+
if (!(0, import_node_fs31.existsSync)(skillMd)) continue;
|
|
12371
12459
|
try {
|
|
12372
|
-
if (!(0,
|
|
12460
|
+
if (!(0, import_node_fs31.statSync)(skillMd).isFile()) continue;
|
|
12373
12461
|
} catch {
|
|
12374
12462
|
continue;
|
|
12375
12463
|
}
|
|
@@ -12378,24 +12466,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
12378
12466
|
}
|
|
12379
12467
|
}
|
|
12380
12468
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
12381
|
-
if (!(0,
|
|
12469
|
+
if (!(0, import_node_fs31.existsSync)(pluginsRoot)) return;
|
|
12382
12470
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
12383
12471
|
if (depth > 7) return;
|
|
12384
12472
|
let entries;
|
|
12385
12473
|
try {
|
|
12386
|
-
entries = (0,
|
|
12474
|
+
entries = (0, import_node_fs31.readdirSync)(dir);
|
|
12387
12475
|
} catch {
|
|
12388
12476
|
return;
|
|
12389
12477
|
}
|
|
12390
12478
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
12391
|
-
const skill = readSkill((0,
|
|
12479
|
+
const skill = readSkill((0, import_node_path27.join)(dir, "SKILL.md"), "cli");
|
|
12392
12480
|
if (skill) out.push(skill);
|
|
12393
12481
|
}
|
|
12394
12482
|
for (const entry of entries) {
|
|
12395
12483
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
12396
|
-
const full = (0,
|
|
12484
|
+
const full = (0, import_node_path27.join)(dir, entry);
|
|
12397
12485
|
try {
|
|
12398
|
-
if (!(0,
|
|
12486
|
+
if (!(0, import_node_fs31.statSync)(full).isDirectory()) continue;
|
|
12399
12487
|
} catch {
|
|
12400
12488
|
continue;
|
|
12401
12489
|
}
|
|
@@ -12413,17 +12501,17 @@ function discoverSkills(worktreePath) {
|
|
|
12413
12501
|
const home = (0, import_node_os9.homedir)();
|
|
12414
12502
|
const collected = [];
|
|
12415
12503
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
12416
|
-
scanSkillsDir((0,
|
|
12504
|
+
scanSkillsDir((0, import_node_path27.join)(worktreePath, rel), "workspace", collected);
|
|
12417
12505
|
}
|
|
12418
12506
|
for (const abs of [
|
|
12419
|
-
(0,
|
|
12420
|
-
(0,
|
|
12421
|
-
(0,
|
|
12422
|
-
(0,
|
|
12507
|
+
(0, import_node_path27.join)(home, ".claude/skills"),
|
|
12508
|
+
(0, import_node_path27.join)(home, ".cursor/skills"),
|
|
12509
|
+
(0, import_node_path27.join)(home, ".sideboard/skills"),
|
|
12510
|
+
(0, import_node_path27.join)(home, ".brightsy/skills")
|
|
12423
12511
|
]) {
|
|
12424
12512
|
scanSkillsDir(abs, "user", collected);
|
|
12425
12513
|
}
|
|
12426
|
-
scanClaudePluginSkills((0,
|
|
12514
|
+
scanClaudePluginSkills((0, import_node_path27.join)(home, ".claude/plugins"), collected);
|
|
12427
12515
|
const rank = { workspace: 0, user: 1, cli: 2 };
|
|
12428
12516
|
const byCommand = /* @__PURE__ */ new Map();
|
|
12429
12517
|
for (const skill of collected) {
|
|
@@ -12435,7 +12523,7 @@ function discoverSkills(worktreePath) {
|
|
|
12435
12523
|
return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
|
|
12436
12524
|
}
|
|
12437
12525
|
function readSkillBody(skillPath, maxChars = 12e3) {
|
|
12438
|
-
const raw = (0,
|
|
12526
|
+
const raw = (0, import_node_fs31.readFileSync)(skillPath, "utf8");
|
|
12439
12527
|
if (raw.startsWith("---")) {
|
|
12440
12528
|
const end = raw.indexOf("\n---", 3);
|
|
12441
12529
|
if (end >= 0) {
|
|
@@ -12528,8 +12616,8 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
|
|
|
12528
12616
|
}
|
|
12529
12617
|
|
|
12530
12618
|
// src/composer/stage-files.ts
|
|
12531
|
-
var
|
|
12532
|
-
var
|
|
12619
|
+
var import_node_fs32 = require("fs");
|
|
12620
|
+
var import_node_path28 = require("path");
|
|
12533
12621
|
var import_node_crypto7 = require("crypto");
|
|
12534
12622
|
init_workspace_scratch();
|
|
12535
12623
|
var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
@@ -12555,7 +12643,7 @@ var IMAGE_MIME_BY_EXT = {
|
|
|
12555
12643
|
var MAX_INLINE_BYTES = 4e5;
|
|
12556
12644
|
var MAX_PREVIEW_BYTES = 5e6;
|
|
12557
12645
|
function fileExtension(filePath) {
|
|
12558
|
-
const base = (0,
|
|
12646
|
+
const base = (0, import_node_path28.basename)(filePath).toLowerCase();
|
|
12559
12647
|
return base.includes(".") ? base.split(".").pop() || "" : "";
|
|
12560
12648
|
}
|
|
12561
12649
|
function isImageFilePath(filePath) {
|
|
@@ -12565,22 +12653,22 @@ function imageMimeType(filePath) {
|
|
|
12565
12653
|
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
12566
12654
|
}
|
|
12567
12655
|
function ensureAttachmentsDir(worktreePath) {
|
|
12568
|
-
const dir = (0,
|
|
12569
|
-
(0,
|
|
12570
|
-
const gi = (0,
|
|
12571
|
-
if (!(0,
|
|
12572
|
-
(0,
|
|
12656
|
+
const dir = (0, import_node_path28.join)(worktreePath, ATTACHMENTS_DIR);
|
|
12657
|
+
(0, import_node_fs32.mkdirSync)(dir, { recursive: true });
|
|
12658
|
+
const gi = (0, import_node_path28.join)(dir, ".gitignore");
|
|
12659
|
+
if (!(0, import_node_fs32.existsSync)(gi)) {
|
|
12660
|
+
(0, import_node_fs32.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
|
|
12573
12661
|
}
|
|
12574
12662
|
return dir;
|
|
12575
12663
|
}
|
|
12576
12664
|
function uniqueAttachmentName(dir, originalName) {
|
|
12577
12665
|
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
12578
|
-
if (!(0,
|
|
12579
|
-
const ext = (0,
|
|
12666
|
+
if (!(0, import_node_fs32.existsSync)((0, import_node_path28.join)(dir, safe))) return safe;
|
|
12667
|
+
const ext = (0, import_node_path28.extname)(safe);
|
|
12580
12668
|
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
12581
12669
|
for (let i = 1; i < 1e4; i++) {
|
|
12582
12670
|
const candidate = `${stem}-${i}${ext}`;
|
|
12583
|
-
if (!(0,
|
|
12671
|
+
if (!(0, import_node_fs32.existsSync)((0, import_node_path28.join)(dir, candidate))) return candidate;
|
|
12584
12672
|
}
|
|
12585
12673
|
return `${stem}-${(0, import_node_crypto7.randomUUID)()}${ext}`;
|
|
12586
12674
|
}
|
|
@@ -12636,15 +12724,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
|
12636
12724
|
const dir = ensureAttachmentsDir(worktreePath);
|
|
12637
12725
|
const out = [];
|
|
12638
12726
|
for (const abs of absolutePaths) {
|
|
12639
|
-
const originalName = (0,
|
|
12727
|
+
const originalName = (0, import_node_path28.basename)(abs);
|
|
12640
12728
|
try {
|
|
12641
|
-
const st = (0,
|
|
12729
|
+
const st = (0, import_node_fs32.statSync)(abs);
|
|
12642
12730
|
if (!st.isFile()) continue;
|
|
12643
12731
|
const name = uniqueAttachmentName(dir, originalName);
|
|
12644
|
-
const destAbs = (0,
|
|
12645
|
-
(0,
|
|
12732
|
+
const destAbs = (0, import_node_path28.join)(dir, name);
|
|
12733
|
+
(0, import_node_fs32.copyFileSync)(abs, destAbs);
|
|
12646
12734
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
12647
|
-
const buf = (0,
|
|
12735
|
+
const buf = (0, import_node_fs32.readFileSync)(destAbs);
|
|
12648
12736
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
12649
12737
|
} catch (err) {
|
|
12650
12738
|
out.push({
|
|
@@ -12666,8 +12754,8 @@ function stageBuffersAsAttachments(worktreePath, buffers) {
|
|
|
12666
12754
|
try {
|
|
12667
12755
|
const buf = Buffer.from(item.dataBase64, "base64");
|
|
12668
12756
|
const name = uniqueAttachmentName(dir, originalName);
|
|
12669
|
-
const destAbs = (0,
|
|
12670
|
-
(0,
|
|
12757
|
+
const destAbs = (0, import_node_path28.join)(dir, name);
|
|
12758
|
+
(0, import_node_fs32.writeFileSync)(destAbs, buf);
|
|
12671
12759
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
12672
12760
|
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
12673
12761
|
} catch (err) {
|
|
@@ -12687,18 +12775,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
12687
12775
|
if (!rel || rel.includes("..") || rel.startsWith("/")) {
|
|
12688
12776
|
out.push({
|
|
12689
12777
|
id: (0, import_node_crypto7.randomUUID)(),
|
|
12690
|
-
name: (0,
|
|
12778
|
+
name: (0, import_node_path28.basename)(rel) || "file",
|
|
12691
12779
|
kind: "file",
|
|
12692
12780
|
content: `(invalid path: ${rel})`
|
|
12693
12781
|
});
|
|
12694
12782
|
continue;
|
|
12695
12783
|
}
|
|
12696
|
-
const name = (0,
|
|
12784
|
+
const name = (0, import_node_path28.basename)(rel);
|
|
12697
12785
|
try {
|
|
12698
|
-
const abs = (0,
|
|
12699
|
-
const st = (0,
|
|
12786
|
+
const abs = (0, import_node_path28.join)(worktreePath, rel);
|
|
12787
|
+
const st = (0, import_node_fs32.statSync)(abs);
|
|
12700
12788
|
if (!st.isFile()) continue;
|
|
12701
|
-
const buf = (0,
|
|
12789
|
+
const buf = (0, import_node_fs32.readFileSync)(abs);
|
|
12702
12790
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
12703
12791
|
} catch (err) {
|
|
12704
12792
|
out.push({
|
|
@@ -12713,11 +12801,11 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
12713
12801
|
}
|
|
12714
12802
|
|
|
12715
12803
|
// src/agents/instructions.ts
|
|
12716
|
-
var
|
|
12717
|
-
var
|
|
12804
|
+
var import_node_fs33 = require("fs");
|
|
12805
|
+
var import_node_path29 = require("path");
|
|
12718
12806
|
init_git_auth_mode();
|
|
12719
12807
|
init_worktree_labels();
|
|
12720
|
-
function
|
|
12808
|
+
function normPath3(p) {
|
|
12721
12809
|
return p.replace(/\/+$/, "");
|
|
12722
12810
|
}
|
|
12723
12811
|
function formatRenameBranchDirective(thread, opts) {
|
|
@@ -12738,8 +12826,8 @@ function formatRenameBranchDirective(thread, opts) {
|
|
|
12738
12826
|
return lines.join("\n");
|
|
12739
12827
|
}
|
|
12740
12828
|
function formatWorktreeDirective(thread, opts) {
|
|
12741
|
-
const worktree =
|
|
12742
|
-
const repo =
|
|
12829
|
+
const worktree = normPath3(thread.worktreePath);
|
|
12830
|
+
const repo = normPath3(thread.repoPath);
|
|
12743
12831
|
const dir = worktreeNameFromPath(thread.worktreePath);
|
|
12744
12832
|
const lines = [
|
|
12745
12833
|
"Sideboard workspace (mandatory):",
|
|
@@ -12988,7 +13076,7 @@ var Orchestrator = class {
|
|
|
12988
13076
|
}
|
|
12989
13077
|
continue;
|
|
12990
13078
|
}
|
|
12991
|
-
if (!(0,
|
|
13079
|
+
if (!(0, import_node_fs37.existsSync)(thread.worktreePath)) {
|
|
12992
13080
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
12993
13081
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
12994
13082
|
continue;
|
|
@@ -13163,14 +13251,7 @@ var Orchestrator = class {
|
|
|
13163
13251
|
return thread;
|
|
13164
13252
|
}
|
|
13165
13253
|
async finishCreateThread(threadId, prompt) {
|
|
13166
|
-
|
|
13167
|
-
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
13168
|
-
if (autoRunAfterSetupEnabled2()) {
|
|
13169
|
-
try {
|
|
13170
|
-
await this.startDev(threadId);
|
|
13171
|
-
} catch {
|
|
13172
|
-
}
|
|
13173
|
-
}
|
|
13254
|
+
const setup = this.runSetupAfterCreate(threadId);
|
|
13174
13255
|
if (prompt) {
|
|
13175
13256
|
try {
|
|
13176
13257
|
await this.send(threadId, prompt);
|
|
@@ -13181,6 +13262,14 @@ var Orchestrator = class {
|
|
|
13181
13262
|
});
|
|
13182
13263
|
}
|
|
13183
13264
|
}
|
|
13265
|
+
await setup;
|
|
13266
|
+
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
13267
|
+
if (autoRunAfterSetupEnabled2()) {
|
|
13268
|
+
try {
|
|
13269
|
+
await this.startDev(threadId);
|
|
13270
|
+
} catch {
|
|
13271
|
+
}
|
|
13272
|
+
}
|
|
13184
13273
|
}
|
|
13185
13274
|
/** Run workspace setup after a new worktree is created (no-op if none configured). */
|
|
13186
13275
|
async runSetupAfterCreate(threadId) {
|
|
@@ -13878,7 +13967,7 @@ var Orchestrator = class {
|
|
|
13878
13967
|
});
|
|
13879
13968
|
this.emit({ type: "setup_started", threadId: thread.id });
|
|
13880
13969
|
try {
|
|
13881
|
-
|
|
13970
|
+
const setup = await runWorkspaceSetup(
|
|
13882
13971
|
thread.repoPath,
|
|
13883
13972
|
thread.worktreePath,
|
|
13884
13973
|
(line) => {
|
|
@@ -13886,18 +13975,9 @@ var Orchestrator = class {
|
|
|
13886
13975
|
},
|
|
13887
13976
|
{ signal: abort.signal }
|
|
13888
13977
|
);
|
|
13889
|
-
if (!setup.ran) {
|
|
13890
|
-
setup = await runCursorWorktreeSetup(
|
|
13891
|
-
thread.repoPath,
|
|
13892
|
-
thread.worktreePath,
|
|
13893
|
-
(line) => {
|
|
13894
|
-
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
13895
|
-
}
|
|
13896
|
-
);
|
|
13897
|
-
}
|
|
13898
13978
|
if (!setup.ran) {
|
|
13899
13979
|
throw new Error(
|
|
13900
|
-
"No setup script in .sideboard/settings.toml, .conductor/settings.toml,
|
|
13980
|
+
"No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)"
|
|
13901
13981
|
);
|
|
13902
13982
|
}
|
|
13903
13983
|
if (setup.exitCode !== 0 && setup.exitCode !== null) {
|
|
@@ -14205,7 +14285,7 @@ var Orchestrator = class {
|
|
|
14205
14285
|
this.emit({ type: "status_changed", threadId: t.id, status: t.status });
|
|
14206
14286
|
}
|
|
14207
14287
|
for (const id of result.createdThreadIds) {
|
|
14208
|
-
|
|
14288
|
+
void this.runSetupAfterCreate(id);
|
|
14209
14289
|
}
|
|
14210
14290
|
return { stack: result.stack, threads: result.threads };
|
|
14211
14291
|
}
|
|
@@ -14222,7 +14302,7 @@ var Orchestrator = class {
|
|
|
14222
14302
|
status: result.thread.status
|
|
14223
14303
|
});
|
|
14224
14304
|
if (result.createdWorktree) {
|
|
14225
|
-
|
|
14305
|
+
void this.runSetupAfterCreate(result.thread.id);
|
|
14226
14306
|
}
|
|
14227
14307
|
return { stack: result.stack, thread: result.thread };
|
|
14228
14308
|
}
|
|
@@ -14237,7 +14317,7 @@ var Orchestrator = class {
|
|
|
14237
14317
|
this.emit({ type: "status_changed", threadId: t.id, status: t.status });
|
|
14238
14318
|
}
|
|
14239
14319
|
for (const id of result.createdThreadIds) {
|
|
14240
|
-
|
|
14320
|
+
void this.runSetupAfterCreate(id);
|
|
14241
14321
|
}
|
|
14242
14322
|
return { stack: result.stack, threads: result.threads };
|
|
14243
14323
|
}
|
|
@@ -14248,7 +14328,7 @@ var Orchestrator = class {
|
|
|
14248
14328
|
this.emit({ type: "status_changed", threadId: t.id, status: t.status });
|
|
14249
14329
|
}
|
|
14250
14330
|
for (const id of result.createdThreadIds) {
|
|
14251
|
-
|
|
14331
|
+
void this.runSetupAfterCreate(id);
|
|
14252
14332
|
}
|
|
14253
14333
|
return { stack: result.stack, threads: result.threads };
|
|
14254
14334
|
}
|
|
@@ -14379,7 +14459,7 @@ var Orchestrator = class {
|
|
|
14379
14459
|
async forkThreadWorktree(input) {
|
|
14380
14460
|
const thread = await forkThreadWorktree(input);
|
|
14381
14461
|
this.emit({ type: "status_changed", threadId: thread.id, status: thread.status });
|
|
14382
|
-
|
|
14462
|
+
void this.runSetupAfterCreate(thread.id);
|
|
14383
14463
|
return thread;
|
|
14384
14464
|
}
|
|
14385
14465
|
renameThread(threadRef, title) {
|
|
@@ -14482,7 +14562,7 @@ var Orchestrator = class {
|
|
|
14482
14562
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
14483
14563
|
return restored2;
|
|
14484
14564
|
}
|
|
14485
|
-
if (!(0,
|
|
14565
|
+
if (!(0, import_node_fs37.existsSync)(thread.worktreePath)) {
|
|
14486
14566
|
const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
|
|
14487
14567
|
const { execa: execa7 } = await import("execa");
|
|
14488
14568
|
const slug = thread.worktreePath.split("/").pop();
|
|
@@ -15713,7 +15793,7 @@ async function startMcpServer() {
|
|
|
15713
15793
|
async () => {
|
|
15714
15794
|
const threads = orch.getThreads(true);
|
|
15715
15795
|
const lines = threads.map((t) => {
|
|
15716
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
15796
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path33.basename)(t.repoPath) || t.repoPath;
|
|
15717
15797
|
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}` : ""}`;
|
|
15718
15798
|
});
|
|
15719
15799
|
return {
|
|
@@ -15924,7 +16004,7 @@ async function startMcpServer() {
|
|
|
15924
16004
|
);
|
|
15925
16005
|
server.tool(
|
|
15926
16006
|
"create_thread",
|
|
15927
|
-
`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.`,
|
|
16007
|
+
`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.`,
|
|
15928
16008
|
{
|
|
15929
16009
|
sourceType: import_zod3.z.enum(["branch", "pr", "ticket"]),
|
|
15930
16010
|
sourceRef: import_zod3.z.string(),
|
|
@@ -16442,7 +16522,7 @@ async function startMcpServer() {
|
|
|
16442
16522
|
);
|
|
16443
16523
|
server.tool(
|
|
16444
16524
|
"run_setup",
|
|
16445
|
-
"Re-run workspace setup (Sideboard/Conductor settings
|
|
16525
|
+
"Re-run workspace setup (Sideboard/Conductor settings, .cursor/worktrees.json, or script/setup). New worktrees already run this automatically.",
|
|
16446
16526
|
{ ref: import_zod3.z.string() },
|
|
16447
16527
|
async ({ ref }) => {
|
|
16448
16528
|
const result = await orch.runSetup(ref);
|