@sideboard-ai/core 0.1.216 → 0.1.218
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{abletime-QGGYL2G4.js → abletime-BF253OZT.js} +5 -4
- package/dist/{abletime-GDZLZRMY.js → abletime-D6773P33.js} +5 -5
- package/dist/{abletime-oauth-F335TWKY.js → abletime-oauth-H4672PRH.js} +4 -3
- package/dist/{abletime-oauth-3X3BAPTF.js → abletime-oauth-KQPVVBKA.js} +4 -4
- package/dist/{abletime-rest-PLJVY3H3.js → abletime-rest-DAFPXZ7H.js} +4 -4
- package/dist/{abletime-rest-LAGTPAJL.js → abletime-rest-OPEVV3XC.js} +4 -3
- package/dist/agents/cursor-runner.js +5 -5
- package/dist/{agents-WBDDLRBY.js → agents-NWJ7DFJD.js} +8 -7
- package/dist/{agents-HETHRRZJ.js → agents-YABJUV3V.js} +9 -9
- package/dist/{app-settings-XCRNCEEE.js → app-settings-5RQMQKSB.js} +2 -1
- package/dist/{app-settings-2TN3WLZV.js → app-settings-V2BBCX2H.js} +2 -2
- package/dist/{chunk-MN6YUD4O.js → chunk-3NWUHXU3.js} +3 -3
- package/dist/{chunk-G4TANQC3.js → chunk-646I442S.js} +5 -5
- package/dist/{chunk-FNQNJOHY.js → chunk-ABOBTSO6.js} +4 -1
- package/dist/{chunk-YVE4PXCJ.js → chunk-CLI5DVU4.js} +2 -2
- package/dist/{chunk-7MTVRNP4.js → chunk-FSIJGLSV.js} +1173 -1186
- package/dist/{chunk-LS6TSOCE.js → chunk-HSYE5ID6.js} +5 -5
- package/dist/{chunk-UFHNSFAS.js → chunk-HVUVQXZ2.js} +5 -1
- package/dist/{chunk-SALM35KD.js → chunk-IILG7DPX.js} +5 -5
- package/dist/{chunk-D2IKXMF3.js → chunk-JWBPSD7Q.js} +453 -289
- package/dist/{chunk-NI243N27.js → chunk-KTZESHYH.js} +15 -7
- package/dist/{chunk-KFD2OXCE.js → chunk-MW57SKKR.js} +19 -6
- package/dist/{chunk-XYKVRRC2.js → chunk-NFWPDEN4.js} +15 -7
- package/dist/{chunk-FNGXKY5W.js → chunk-OPYBLX4V.js} +19 -6
- package/dist/{chunk-QQKDGPUI.js → chunk-PO4M4JAJ.js} +1 -1
- package/dist/{chunk-2M5B7YNY.js → chunk-RRW2XWAY.js} +2 -2
- package/dist/{chunk-REZRGCKV.js → chunk-SOGGKYFV.js} +3 -3
- package/dist/{chunk-C32SBNA3.js → chunk-SRFFIFW6.js} +457 -294
- package/dist/{chunk-3OHR73VK.js → chunk-SVXIJ2IC.js} +1 -1
- package/dist/{chunk-SYFVUF2C.js → chunk-SZJZEFTY.js} +1 -1
- package/dist/{chunk-42IULNIY.js → chunk-THLVCXLF.js} +3 -3
- package/dist/{chunk-JZHRZ3DR.js → chunk-TQBUXKIB.js} +5 -5
- package/dist/chunk-WWUABK6B.js +56 -0
- package/dist/{chunk-DFTVZEZY.js → chunk-XRHTRXZN.js} +1051 -1050
- package/dist/{chunk-BTC2D6LS.js → chunk-Y5JES2VV.js} +3 -51
- package/dist/{connected-teams-WK47ATT7.js → connected-teams-LX5DLL2I.js} +3 -2
- package/dist/{connected-teams-PU4AMFNA.js → connected-teams-PQETXUWV.js} +3 -2
- package/dist/{coordinator-prompt-FQX6ALAI.js → coordinator-prompt-5V7GEPBG.js} +6 -6
- package/dist/{coordinator-prompt-LE2GQZ2X.js → coordinator-prompt-J4QSNTKE.js} +6 -5
- package/dist/{global-workspace-6P236KKG.js → global-workspace-4TEMLESD.js} +6 -6
- package/dist/{global-workspace-KT3FRHZL.js → global-workspace-XPTFHMKL.js} +6 -5
- package/dist/index.cjs +1027 -821
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +22 -18
- package/dist/mcp/run-stdio.cjs +1838 -1651
- package/dist/mcp/run-stdio.js +16 -14
- package/dist/{orchestrator-WVZPTHBV.js → orchestrator-HKW3VLGX.js} +10 -10
- package/dist/{orchestrator-MI7A5DQZ.js → orchestrator-SWRTYFHX.js} +9 -8
- package/dist/{run-EBWL2Q4N.js → run-QDZCTP4Y.js} +2 -1
- package/dist/{run-CAGKZLHA.js → run-UEQM4JMZ.js} +2 -1
- package/dist/{workspaces-KM7KTLVO.js → workspaces-2HQP654Q.js} +6 -5
- package/dist/{workspaces-R5LJCJRB.js → workspaces-BCBBMMXB.js} +6 -6
- package/dist/{worktree-MDMTCAHX.js → worktree-7V67XTEO.js} +5 -5
- package/dist/{worktree-VXRI7LYM.js → worktree-I573UOPD.js} +5 -4
- package/dist/{worktree-exclude-N5X5I422.js → worktree-exclude-K7QK4RI5.js} +3 -2
- package/dist/{worktree-exclude-X54WSOXM.js → worktree-exclude-L32WEBX6.js} +3 -2
- package/package.json +1 -1
- package/dist/{chunk-L5CIEBLR.js → chunk-EWHJNJHV.js} +3 -3
package/dist/index.cjs
CHANGED
|
@@ -6890,7 +6890,7 @@ async function run(file, args, opts) {
|
|
|
6890
6890
|
try {
|
|
6891
6891
|
const result = await (0, import_execa2.execa)(file, args, {
|
|
6892
6892
|
cwd: opts?.cwd,
|
|
6893
|
-
env: { ...process.env, ...opts?.env },
|
|
6893
|
+
env: { ...stripNestedElectronEnv(process.env), ...opts?.env },
|
|
6894
6894
|
reject: opts?.reject ?? true,
|
|
6895
6895
|
...opts?.timeoutMs != null ? { timeout: opts.timeoutMs } : {}
|
|
6896
6896
|
});
|
|
@@ -6987,6 +6987,7 @@ var init_run = __esm({
|
|
|
6987
6987
|
"use strict";
|
|
6988
6988
|
import_execa2 = require("execa");
|
|
6989
6989
|
init_path();
|
|
6990
|
+
init_nested_electron_env();
|
|
6990
6991
|
init_github_agent_auth();
|
|
6991
6992
|
init_stale_lock();
|
|
6992
6993
|
}
|
|
@@ -8079,7 +8080,14 @@ function slugify(input) {
|
|
|
8079
8080
|
}
|
|
8080
8081
|
async function resolveRepoRoot(cwd) {
|
|
8081
8082
|
const { stdout } = await git(["rev-parse", "--show-toplevel"], cwd);
|
|
8082
|
-
|
|
8083
|
+
const toplevel = canonicalizeRepoPath(stdout.trim());
|
|
8084
|
+
try {
|
|
8085
|
+
const listed = await listWorktrees(cwd);
|
|
8086
|
+
const primary = listed[0]?.path;
|
|
8087
|
+
if (primary) return canonicalizeRepoPath(primary);
|
|
8088
|
+
} catch {
|
|
8089
|
+
}
|
|
8090
|
+
return toplevel;
|
|
8083
8091
|
}
|
|
8084
8092
|
function canonicalizeRepoPath(path2) {
|
|
8085
8093
|
try {
|
|
@@ -8099,7 +8107,8 @@ function parseGithubSlugFromRemoteUrl(url) {
|
|
|
8099
8107
|
}
|
|
8100
8108
|
async function slugFromGitRemote(repoPath, remote) {
|
|
8101
8109
|
const result = await git(["remote", "get-url", remote], repoPath, {
|
|
8102
|
-
reject: false
|
|
8110
|
+
reject: false,
|
|
8111
|
+
timeoutMs: 5e3
|
|
8103
8112
|
});
|
|
8104
8113
|
if (result.exitCode !== 0 || !result.stdout.trim()) return null;
|
|
8105
8114
|
return parseGithubSlugFromRemoteUrl(result.stdout);
|
|
@@ -8112,7 +8121,7 @@ async function resolveGithubRepoSlug(repoPath) {
|
|
|
8112
8121
|
const viaGh = await gh(
|
|
8113
8122
|
["repo", "view", "--json", "nameWithOwner", "--jq", ".nameWithOwner"],
|
|
8114
8123
|
repoPath,
|
|
8115
|
-
{ reject: false }
|
|
8124
|
+
{ reject: false, timeoutMs: 8e3 }
|
|
8116
8125
|
);
|
|
8117
8126
|
if (viaGh.exitCode === 0 && viaGh.stdout.trim()) {
|
|
8118
8127
|
return viaGh.stdout.trim();
|
|
@@ -9041,7 +9050,7 @@ async function listWorktrees(repoPath) {
|
|
|
9041
9050
|
const { stdout } = await git(
|
|
9042
9051
|
["worktree", "list", "--porcelain"],
|
|
9043
9052
|
repoPath,
|
|
9044
|
-
{ reject: false }
|
|
9053
|
+
{ reject: false, timeoutMs: 8e3 }
|
|
9045
9054
|
);
|
|
9046
9055
|
if (!stdout.trim()) return [];
|
|
9047
9056
|
const entries = [];
|
|
@@ -9520,6 +9529,18 @@ function listWorkspaces() {
|
|
|
9520
9529
|
if (valid.length !== all.length) writeAll2(valid);
|
|
9521
9530
|
return valid.sort((a, b) => a.name.localeCompare(b.name));
|
|
9522
9531
|
}
|
|
9532
|
+
function isLinkedWorktreeOf(path2, mainRepo) {
|
|
9533
|
+
if (!path2 || path2 === mainRepo) return false;
|
|
9534
|
+
const git2 = (0, import_node_path22.join)(path2, ".git");
|
|
9535
|
+
try {
|
|
9536
|
+
if (!(0, import_node_fs19.existsSync)(git2) || (0, import_node_fs19.statSync)(git2).isDirectory()) return false;
|
|
9537
|
+
const text7 = (0, import_node_fs19.readFileSync)(git2, "utf8");
|
|
9538
|
+
const needle = `${mainRepo.replace(/\/+$/, "")}/.git`;
|
|
9539
|
+
return text7.includes(needle);
|
|
9540
|
+
} catch {
|
|
9541
|
+
return false;
|
|
9542
|
+
}
|
|
9543
|
+
}
|
|
9523
9544
|
async function addWorkspace(repoPath) {
|
|
9524
9545
|
const root = await resolveRepoRoot(repoPath);
|
|
9525
9546
|
if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
|
|
@@ -9528,13 +9549,14 @@ async function addWorkspace(repoPath) {
|
|
|
9528
9549
|
await ensureGhPreferOrigin(root);
|
|
9529
9550
|
const current = readAll2();
|
|
9530
9551
|
const existing = current.find((w) => w.path === root);
|
|
9531
|
-
|
|
9532
|
-
|
|
9552
|
+
const withoutLinked = current.filter((w) => !isLinkedWorktreeOf(w.path, root));
|
|
9553
|
+
if (existing && withoutLinked.length === current.length) return existing;
|
|
9554
|
+
const next = existing ?? {
|
|
9533
9555
|
path: root,
|
|
9534
9556
|
name: (0, import_node_path22.basename)(root),
|
|
9535
9557
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9536
9558
|
};
|
|
9537
|
-
writeAll2([...
|
|
9559
|
+
writeAll2(existing ? withoutLinked : [...withoutLinked, next]);
|
|
9538
9560
|
return next;
|
|
9539
9561
|
}
|
|
9540
9562
|
function removeWorkspace(repoPath) {
|
|
@@ -10647,36 +10669,71 @@ var init_outbound_watch = __esm({
|
|
|
10647
10669
|
}
|
|
10648
10670
|
});
|
|
10649
10671
|
|
|
10672
|
+
// src/agents/turn-trace.ts
|
|
10673
|
+
function traceTurn(phase, extra) {
|
|
10674
|
+
try {
|
|
10675
|
+
const line = `${JSON.stringify({ t: (/* @__PURE__ */ new Date()).toISOString(), phase, ...extra })}
|
|
10676
|
+
`;
|
|
10677
|
+
(0, import_node_fs23.appendFileSync)((0, import_node_path27.join)(appDataDir(), "turn-spawn.log"), line);
|
|
10678
|
+
} catch {
|
|
10679
|
+
}
|
|
10680
|
+
}
|
|
10681
|
+
async function withTimeout(promise, ms, label) {
|
|
10682
|
+
let timer;
|
|
10683
|
+
try {
|
|
10684
|
+
return await Promise.race([
|
|
10685
|
+
promise,
|
|
10686
|
+
new Promise((_, reject) => {
|
|
10687
|
+
timer = setTimeout(
|
|
10688
|
+
() => reject(new Error(`${label} timed out after ${ms}ms`)),
|
|
10689
|
+
ms
|
|
10690
|
+
);
|
|
10691
|
+
})
|
|
10692
|
+
]);
|
|
10693
|
+
} finally {
|
|
10694
|
+
if (timer) clearTimeout(timer);
|
|
10695
|
+
}
|
|
10696
|
+
}
|
|
10697
|
+
var import_node_fs23, import_node_path27;
|
|
10698
|
+
var init_turn_trace = __esm({
|
|
10699
|
+
"src/agents/turn-trace.ts"() {
|
|
10700
|
+
"use strict";
|
|
10701
|
+
import_node_fs23 = require("fs");
|
|
10702
|
+
import_node_path27 = require("path");
|
|
10703
|
+
init_paths();
|
|
10704
|
+
}
|
|
10705
|
+
});
|
|
10706
|
+
|
|
10650
10707
|
// src/brightsy/config.ts
|
|
10651
10708
|
function brightsyConfigPath() {
|
|
10652
10709
|
const override = process.env.BRIGHTSY_CONFIG?.trim();
|
|
10653
10710
|
if (override) return override;
|
|
10654
|
-
return (0,
|
|
10711
|
+
return (0, import_node_path28.join)((0, import_node_os7.homedir)(), ".brightsy", "config.json");
|
|
10655
10712
|
}
|
|
10656
10713
|
function loadBrightsyConfig() {
|
|
10657
10714
|
const path2 = brightsyConfigPath();
|
|
10658
|
-
if (!(0,
|
|
10715
|
+
if (!(0, import_node_fs24.existsSync)(path2)) {
|
|
10659
10716
|
throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
|
|
10660
10717
|
}
|
|
10661
|
-
const raw = JSON.parse((0,
|
|
10718
|
+
const raw = JSON.parse((0, import_node_fs24.readFileSync)(path2, "utf8"));
|
|
10662
10719
|
if (!raw.access_token || !raw.account_id) {
|
|
10663
10720
|
throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
|
|
10664
10721
|
}
|
|
10665
10722
|
return raw;
|
|
10666
10723
|
}
|
|
10667
10724
|
function saveBrightsyConfig(cfg) {
|
|
10668
|
-
(0,
|
|
10725
|
+
(0, import_node_fs24.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
|
|
10669
10726
|
`, {
|
|
10670
10727
|
mode: 384
|
|
10671
10728
|
});
|
|
10672
10729
|
}
|
|
10673
|
-
var
|
|
10730
|
+
var import_node_fs24, import_node_os7, import_node_path28;
|
|
10674
10731
|
var init_config = __esm({
|
|
10675
10732
|
"src/brightsy/config.ts"() {
|
|
10676
10733
|
"use strict";
|
|
10677
|
-
|
|
10734
|
+
import_node_fs24 = require("fs");
|
|
10678
10735
|
import_node_os7 = require("os");
|
|
10679
|
-
|
|
10736
|
+
import_node_path28 = require("path");
|
|
10680
10737
|
}
|
|
10681
10738
|
});
|
|
10682
10739
|
|
|
@@ -10903,22 +10960,22 @@ __export(connected_teams_exports, {
|
|
|
10903
10960
|
listConnectedBrightsyTeams: () => listConnectedBrightsyTeams
|
|
10904
10961
|
});
|
|
10905
10962
|
function storePath4() {
|
|
10906
|
-
return (0,
|
|
10963
|
+
return (0, import_node_path29.join)(appDataDir(), "brightsy-teams.json");
|
|
10907
10964
|
}
|
|
10908
10965
|
function readStore4() {
|
|
10909
10966
|
const path2 = storePath4();
|
|
10910
|
-
if (!(0,
|
|
10967
|
+
if (!(0, import_node_fs25.existsSync)(path2)) return [];
|
|
10911
10968
|
try {
|
|
10912
|
-
const parsed = JSON.parse((0,
|
|
10969
|
+
const parsed = JSON.parse((0, import_node_fs25.readFileSync)(path2, "utf8"));
|
|
10913
10970
|
return Array.isArray(parsed.teams) ? parsed.teams : [];
|
|
10914
10971
|
} catch {
|
|
10915
10972
|
return [];
|
|
10916
10973
|
}
|
|
10917
10974
|
}
|
|
10918
10975
|
function writeStore3(teams) {
|
|
10919
|
-
(0,
|
|
10976
|
+
(0, import_node_fs25.mkdirSync)(appDataDir(), { recursive: true });
|
|
10920
10977
|
const path2 = storePath4();
|
|
10921
|
-
(0,
|
|
10978
|
+
(0, import_node_fs25.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
|
|
10922
10979
|
`, {
|
|
10923
10980
|
mode: 384
|
|
10924
10981
|
});
|
|
@@ -11074,12 +11131,12 @@ function brightsyMcpServerName(slug) {
|
|
|
11074
11131
|
const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
|
|
11075
11132
|
return `brightsy_${cleaned || "team"}`;
|
|
11076
11133
|
}
|
|
11077
|
-
var
|
|
11134
|
+
var import_node_fs25, import_node_path29;
|
|
11078
11135
|
var init_connected_teams = __esm({
|
|
11079
11136
|
"src/brightsy/connected-teams.ts"() {
|
|
11080
11137
|
"use strict";
|
|
11081
|
-
|
|
11082
|
-
|
|
11138
|
+
import_node_fs25 = require("fs");
|
|
11139
|
+
import_node_path29 = require("path");
|
|
11083
11140
|
init_paths();
|
|
11084
11141
|
init_accounts();
|
|
11085
11142
|
init_config();
|
|
@@ -11444,11 +11501,11 @@ async function syncCliForTarget(accountId) {
|
|
|
11444
11501
|
}
|
|
11445
11502
|
applyConnectedTeamToCli(team);
|
|
11446
11503
|
}
|
|
11447
|
-
var
|
|
11504
|
+
var import_node_fs26, brightsyAdapter;
|
|
11448
11505
|
var init_brightsy = __esm({
|
|
11449
11506
|
"src/agents/brightsy.ts"() {
|
|
11450
11507
|
"use strict";
|
|
11451
|
-
|
|
11508
|
+
import_node_fs26 = require("fs");
|
|
11452
11509
|
init_run();
|
|
11453
11510
|
init_connected_teams();
|
|
11454
11511
|
init_config();
|
|
@@ -11463,7 +11520,7 @@ var init_brightsy = __esm({
|
|
|
11463
11520
|
async detect() {
|
|
11464
11521
|
const brightsy = resolveAgentExecutable("brightsy");
|
|
11465
11522
|
if (brightsy !== "brightsy") {
|
|
11466
|
-
if (!(0,
|
|
11523
|
+
if (!(0, import_node_fs26.existsSync)(brightsy)) {
|
|
11467
11524
|
return {
|
|
11468
11525
|
agent: "brightsy",
|
|
11469
11526
|
installed: false,
|
|
@@ -11571,6 +11628,11 @@ function mcpAllowTools(servers) {
|
|
|
11571
11628
|
}
|
|
11572
11629
|
return out;
|
|
11573
11630
|
}
|
|
11631
|
+
function mcpAllowToolsFromNames(names) {
|
|
11632
|
+
return mcpAllowTools(
|
|
11633
|
+
[...names].map((name) => name.trim()).filter(Boolean).map((name) => ({ name, connected: true, needsAuth: false }))
|
|
11634
|
+
);
|
|
11635
|
+
}
|
|
11574
11636
|
function mcpAuthWarnings(servers) {
|
|
11575
11637
|
const needing = servers.filter((s) => s.needsAuth).map((s) => s.name);
|
|
11576
11638
|
if (needing.length === 0) return [];
|
|
@@ -11639,7 +11701,7 @@ function splitPemCertificates(pem) {
|
|
|
11639
11701
|
}
|
|
11640
11702
|
function readExistingFile(path2) {
|
|
11641
11703
|
try {
|
|
11642
|
-
return (0,
|
|
11704
|
+
return (0, import_node_fs27.existsSync)(path2) ? (0, import_node_fs27.readFileSync)(path2, "utf8") : "";
|
|
11643
11705
|
} catch {
|
|
11644
11706
|
return "";
|
|
11645
11707
|
}
|
|
@@ -11671,13 +11733,13 @@ function collectSystemCaPem(io = {}) {
|
|
|
11671
11733
|
return "";
|
|
11672
11734
|
}
|
|
11673
11735
|
function systemCaBundlePath(io = {}) {
|
|
11674
|
-
return (0,
|
|
11736
|
+
return (0, import_node_path30.join)((io.appData ?? appDataDir)(), BUNDLE_NAME);
|
|
11675
11737
|
}
|
|
11676
11738
|
function bundleIsFresh(path2, now) {
|
|
11677
11739
|
try {
|
|
11678
|
-
if (!(0,
|
|
11679
|
-
if (splitPemCertificates((0,
|
|
11680
|
-
return now - (0,
|
|
11740
|
+
if (!(0, import_node_fs27.existsSync)(path2)) return false;
|
|
11741
|
+
if (splitPemCertificates((0, import_node_fs27.readFileSync)(path2, "utf8")).length === 0) return false;
|
|
11742
|
+
return now - (0, import_node_fs27.statSync)(path2).mtimeMs < BUNDLE_MAX_AGE_MS;
|
|
11681
11743
|
} catch {
|
|
11682
11744
|
return false;
|
|
11683
11745
|
}
|
|
@@ -11698,11 +11760,11 @@ function materializeSystemCaBundle(io = {}) {
|
|
|
11698
11760
|
if (bundleIsFresh(dest, now)) return dest;
|
|
11699
11761
|
const pem = collectSystemCaPem(io);
|
|
11700
11762
|
if (splitPemCertificates(pem).length === 0) {
|
|
11701
|
-
return (0,
|
|
11763
|
+
return (0, import_node_fs27.existsSync)(dest) && splitPemCertificates(readExistingFile(dest)).length > 0 ? dest : void 0;
|
|
11702
11764
|
}
|
|
11703
11765
|
try {
|
|
11704
|
-
(0,
|
|
11705
|
-
(0,
|
|
11766
|
+
(0, import_node_fs27.mkdirSync)((0, import_node_path30.dirname)(dest), { recursive: true });
|
|
11767
|
+
(0, import_node_fs27.writeFileSync)(dest, pem.endsWith("\n") ? pem : `${pem}
|
|
11706
11768
|
`, { mode: 384 });
|
|
11707
11769
|
return dest;
|
|
11708
11770
|
} catch {
|
|
@@ -11742,13 +11804,13 @@ function trustSystemCertificates(io = {}) {
|
|
|
11742
11804
|
return false;
|
|
11743
11805
|
}
|
|
11744
11806
|
}
|
|
11745
|
-
var import_node_child_process4,
|
|
11807
|
+
var import_node_child_process4, import_node_fs27, import_node_path30, import_node_tls, NODE_USE_SYSTEM_CA, NODE_EXTRA_CA_CERTS, BUNDLE_NAME, BUNDLE_MAX_AGE_MS, LINUX_CA_FILES, PEM_CERT_RE;
|
|
11746
11808
|
var init_system_ca = __esm({
|
|
11747
11809
|
"src/http/system-ca.ts"() {
|
|
11748
11810
|
"use strict";
|
|
11749
11811
|
import_node_child_process4 = require("child_process");
|
|
11750
|
-
|
|
11751
|
-
|
|
11812
|
+
import_node_fs27 = require("fs");
|
|
11813
|
+
import_node_path30 = require("path");
|
|
11752
11814
|
import_node_tls = __toESM(require("tls"), 1);
|
|
11753
11815
|
init_paths();
|
|
11754
11816
|
NODE_USE_SYSTEM_CA = "NODE_USE_SYSTEM_CA";
|
|
@@ -11774,43 +11836,43 @@ function electronResourcesPath() {
|
|
|
11774
11836
|
function packagedCursorRuntimeDir() {
|
|
11775
11837
|
const resources = electronResourcesPath();
|
|
11776
11838
|
if (!resources) return null;
|
|
11777
|
-
const dir = (0,
|
|
11778
|
-
if (!(0,
|
|
11839
|
+
const dir = (0, import_node_path31.join)(resources, "cursor-runtime");
|
|
11840
|
+
if (!(0, import_node_fs28.existsSync)((0, import_node_path31.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
|
|
11779
11841
|
return dir;
|
|
11780
11842
|
}
|
|
11781
11843
|
function packagedCursorRunnerPath() {
|
|
11782
11844
|
const dir = packagedCursorRuntimeDir();
|
|
11783
|
-
return dir ? (0,
|
|
11845
|
+
return dir ? (0, import_node_path31.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
|
|
11784
11846
|
}
|
|
11785
11847
|
function packagedMcpDir() {
|
|
11786
11848
|
const resources = electronResourcesPath();
|
|
11787
11849
|
if (!resources) return null;
|
|
11788
|
-
const dir = (0,
|
|
11789
|
-
if (!(0,
|
|
11850
|
+
const dir = (0, import_node_path31.join)(resources, "sideboard-mcp");
|
|
11851
|
+
if (!(0, import_node_fs28.existsSync)((0, import_node_path31.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
|
|
11790
11852
|
return dir;
|
|
11791
11853
|
}
|
|
11792
11854
|
function packagedMcpStdioPath() {
|
|
11793
11855
|
const dir = packagedMcpDir();
|
|
11794
|
-
return dir ? (0,
|
|
11856
|
+
return dir ? (0, import_node_path31.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
|
|
11795
11857
|
}
|
|
11796
11858
|
function packagedBundledNodePath() {
|
|
11797
11859
|
const resources = electronResourcesPath();
|
|
11798
11860
|
if (!resources) return null;
|
|
11799
|
-
const bin = (0,
|
|
11800
|
-
if (!(0,
|
|
11861
|
+
const bin = (0, import_node_path31.join)(resources, "node", "bin", "node");
|
|
11862
|
+
if (!(0, import_node_fs28.existsSync)(bin)) return null;
|
|
11801
11863
|
return bin;
|
|
11802
11864
|
}
|
|
11803
11865
|
function packagedCursorRipgrepCandidate(platformPkg, binName) {
|
|
11804
11866
|
const dir = packagedCursorRuntimeDir();
|
|
11805
11867
|
if (!dir) return null;
|
|
11806
|
-
return (0,
|
|
11868
|
+
return (0, import_node_path31.join)(dir, "node_modules", platformPkg, "bin", binName);
|
|
11807
11869
|
}
|
|
11808
|
-
var
|
|
11870
|
+
var import_node_fs28, import_node_path31;
|
|
11809
11871
|
var init_packaged_runtime = __esm({
|
|
11810
11872
|
"src/agents/packaged-runtime.ts"() {
|
|
11811
11873
|
"use strict";
|
|
11812
|
-
|
|
11813
|
-
|
|
11874
|
+
import_node_fs28 = require("fs");
|
|
11875
|
+
import_node_path31 = require("path");
|
|
11814
11876
|
}
|
|
11815
11877
|
});
|
|
11816
11878
|
|
|
@@ -11845,7 +11907,7 @@ function unpackedAsarPath(filePath) {
|
|
|
11845
11907
|
if (!isAsarPath(filePath)) return null;
|
|
11846
11908
|
const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
|
|
11847
11909
|
if (unpacked === filePath) return null;
|
|
11848
|
-
return (0,
|
|
11910
|
+
return (0, import_node_fs29.existsSync)(unpacked) ? unpacked : null;
|
|
11849
11911
|
}
|
|
11850
11912
|
function nodeReadableScriptPath(scriptPath) {
|
|
11851
11913
|
return unpackedAsarPath(scriptPath) ?? scriptPath;
|
|
@@ -11885,37 +11947,37 @@ function pickPreferredNode(candidates) {
|
|
|
11885
11947
|
return best;
|
|
11886
11948
|
}
|
|
11887
11949
|
function versionDirNodeBins(root, toBin) {
|
|
11888
|
-
if (!(0,
|
|
11950
|
+
if (!(0, import_node_fs29.existsSync)(root)) return [];
|
|
11889
11951
|
try {
|
|
11890
|
-
return (0,
|
|
11952
|
+
return (0, import_node_fs29.readdirSync)(root).map(toBin);
|
|
11891
11953
|
} catch {
|
|
11892
11954
|
return [];
|
|
11893
11955
|
}
|
|
11894
11956
|
}
|
|
11895
11957
|
function defaultNodeBinCandidates(home = (0, import_node_os8.homedir)()) {
|
|
11896
11958
|
const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
|
|
11897
|
-
(prefix) => PREFERRED_LTS_MAJORS.map((major) => (0,
|
|
11959
|
+
(prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path32.join)(prefix, "opt", `node@${major}`, "bin", "node"))
|
|
11898
11960
|
);
|
|
11899
11961
|
return [
|
|
11900
11962
|
...kegs,
|
|
11901
11963
|
"/opt/homebrew/bin/node",
|
|
11902
11964
|
"/usr/local/bin/node",
|
|
11903
|
-
(0,
|
|
11904
|
-
(0,
|
|
11905
|
-
(0,
|
|
11906
|
-
(0,
|
|
11907
|
-
(0,
|
|
11965
|
+
(0, import_node_path32.join)(home, ".local/share/fnm/aliases/default/bin/node"),
|
|
11966
|
+
(0, import_node_path32.join)(home, ".nvm/current/bin/node"),
|
|
11967
|
+
(0, import_node_path32.join)(home, ".volta/bin/node"),
|
|
11968
|
+
(0, import_node_path32.join)(home, ".asdf/shims/node"),
|
|
11969
|
+
(0, import_node_path32.join)(home, ".local/share/mise/shims/node"),
|
|
11908
11970
|
...versionDirNodeBins(
|
|
11909
|
-
(0,
|
|
11910
|
-
(name) => (0,
|
|
11971
|
+
(0, import_node_path32.join)(home, ".nvm", "versions", "node"),
|
|
11972
|
+
(name) => (0, import_node_path32.join)(home, ".nvm", "versions", "node", name, "bin", "node")
|
|
11911
11973
|
),
|
|
11912
11974
|
...versionDirNodeBins(
|
|
11913
|
-
(0,
|
|
11914
|
-
(name) => (0,
|
|
11975
|
+
(0, import_node_path32.join)(home, ".local/share/fnm", "node-versions"),
|
|
11976
|
+
(name) => (0, import_node_path32.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
|
|
11915
11977
|
),
|
|
11916
11978
|
...versionDirNodeBins(
|
|
11917
|
-
(0,
|
|
11918
|
-
(name) => (0,
|
|
11979
|
+
(0, import_node_path32.join)(home, ".volta", "tools", "image", "node"),
|
|
11980
|
+
(name) => (0, import_node_path32.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
|
|
11919
11981
|
)
|
|
11920
11982
|
];
|
|
11921
11983
|
}
|
|
@@ -11924,10 +11986,10 @@ function uniqueExistingNodeBins(paths) {
|
|
|
11924
11986
|
const out = [];
|
|
11925
11987
|
for (const raw of paths) {
|
|
11926
11988
|
const p = raw.trim();
|
|
11927
|
-
if (!p || !(0,
|
|
11989
|
+
if (!p || !(0, import_node_fs29.existsSync)(p) || isElectronLikeCommand(p)) continue;
|
|
11928
11990
|
let key = p;
|
|
11929
11991
|
try {
|
|
11930
|
-
key = (0,
|
|
11992
|
+
key = (0, import_node_fs29.realpathSync)(p);
|
|
11931
11993
|
} catch {
|
|
11932
11994
|
continue;
|
|
11933
11995
|
}
|
|
@@ -12007,13 +12069,13 @@ async function resolveNodeLaunch(scriptPath) {
|
|
|
12007
12069
|
env: { ELECTRON_RUN_AS_NODE: "1" }
|
|
12008
12070
|
};
|
|
12009
12071
|
}
|
|
12010
|
-
var
|
|
12072
|
+
var import_node_fs29, import_node_os8, import_node_path32, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
|
|
12011
12073
|
var init_node_launch = __esm({
|
|
12012
12074
|
"src/agents/node-launch.ts"() {
|
|
12013
12075
|
"use strict";
|
|
12014
|
-
|
|
12076
|
+
import_node_fs29 = require("fs");
|
|
12015
12077
|
import_node_os8 = require("os");
|
|
12016
|
-
|
|
12078
|
+
import_node_path32 = require("path");
|
|
12017
12079
|
init_nested_electron_env();
|
|
12018
12080
|
init_system_ca();
|
|
12019
12081
|
init_run();
|
|
@@ -12115,37 +12177,37 @@ function corePackageDir() {
|
|
|
12115
12177
|
try {
|
|
12116
12178
|
const url = import_meta.url;
|
|
12117
12179
|
if (typeof url === "string" && url.length > 0) {
|
|
12118
|
-
return (0,
|
|
12180
|
+
return (0, import_node_path33.dirname)((0, import_node_url.fileURLToPath)(url));
|
|
12119
12181
|
}
|
|
12120
12182
|
} catch {
|
|
12121
12183
|
}
|
|
12122
12184
|
try {
|
|
12123
|
-
const req = (0, import_node_module.createRequire)((0,
|
|
12124
|
-
return (0,
|
|
12185
|
+
const req = (0, import_node_module.createRequire)((0, import_node_path33.join)(process.cwd(), "package.json"));
|
|
12186
|
+
return (0, import_node_path33.dirname)(req.resolve("@sideboard-ai/core"));
|
|
12125
12187
|
} catch {
|
|
12126
12188
|
return process.cwd();
|
|
12127
12189
|
}
|
|
12128
12190
|
}
|
|
12129
12191
|
function findSideboardMcpJsEntry() {
|
|
12130
12192
|
const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
|
|
12131
|
-
if (override && (0,
|
|
12193
|
+
if (override && (0, import_node_fs30.existsSync)(override)) return override;
|
|
12132
12194
|
const packaged = packagedMcpStdioPath();
|
|
12133
12195
|
if (packaged) return packaged;
|
|
12134
12196
|
let dir = corePackageDir();
|
|
12135
12197
|
for (let i = 0; i < 10; i++) {
|
|
12136
12198
|
const candidates = [
|
|
12137
|
-
(0,
|
|
12138
|
-
(0,
|
|
12139
|
-
(0,
|
|
12140
|
-
(0,
|
|
12141
|
-
(0,
|
|
12142
|
-
(0,
|
|
12143
|
-
(0,
|
|
12199
|
+
(0, import_node_path33.join)(dir, "mcp/run-stdio.js"),
|
|
12200
|
+
(0, import_node_path33.join)(dir, "mcp/run-stdio.cjs"),
|
|
12201
|
+
(0, import_node_path33.join)(dir, "dist/mcp/run-stdio.js"),
|
|
12202
|
+
(0, import_node_path33.join)(dir, "dist/mcp/run-stdio.cjs"),
|
|
12203
|
+
(0, import_node_path33.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
12204
|
+
(0, import_node_path33.join)(dir, "packages/cli/dist/index.js"),
|
|
12205
|
+
(0, import_node_path33.join)(dir, "cli/dist/index.js")
|
|
12144
12206
|
];
|
|
12145
12207
|
for (const p of candidates) {
|
|
12146
|
-
if ((0,
|
|
12208
|
+
if ((0, import_node_fs30.existsSync)(p) && !isAsarPath(p)) return p;
|
|
12147
12209
|
}
|
|
12148
|
-
const parent = (0,
|
|
12210
|
+
const parent = (0, import_node_path33.dirname)(dir);
|
|
12149
12211
|
if (parent === dir) break;
|
|
12150
12212
|
dir = parent;
|
|
12151
12213
|
}
|
|
@@ -12292,22 +12354,22 @@ function writeMcpServersConfig(servers) {
|
|
|
12292
12354
|
...env ? { env } : {}
|
|
12293
12355
|
};
|
|
12294
12356
|
}
|
|
12295
|
-
const dir = (0,
|
|
12296
|
-
const cfgPath = (0,
|
|
12297
|
-
(0,
|
|
12357
|
+
const dir = (0, import_node_fs30.mkdtempSync)((0, import_node_path33.join)((0, import_node_os9.tmpdir)(), "sideboard-mcp-"));
|
|
12358
|
+
const cfgPath = (0, import_node_path33.join)(dir, "mcp.json");
|
|
12359
|
+
(0, import_node_fs30.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
|
|
12298
12360
|
return cfgPath;
|
|
12299
12361
|
}
|
|
12300
12362
|
async function writeInjectedMcpConfig(opts) {
|
|
12301
12363
|
return writeMcpServersConfig(await buildInjectedMcpServers(opts));
|
|
12302
12364
|
}
|
|
12303
|
-
var
|
|
12365
|
+
var import_node_fs30, import_node_module, import_node_os9, import_node_path33, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS, SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS, SIDEBOARD_ABLETIME_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
|
|
12304
12366
|
var init_injected_mcp = __esm({
|
|
12305
12367
|
"src/agents/injected-mcp.ts"() {
|
|
12306
12368
|
"use strict";
|
|
12307
|
-
|
|
12369
|
+
import_node_fs30 = require("fs");
|
|
12308
12370
|
import_node_module = require("module");
|
|
12309
12371
|
import_node_os9 = require("os");
|
|
12310
|
-
|
|
12372
|
+
import_node_path33 = require("path");
|
|
12311
12373
|
import_node_url = require("url");
|
|
12312
12374
|
init_run();
|
|
12313
12375
|
init_config();
|
|
@@ -12347,6 +12409,195 @@ var init_injected_mcp = __esm({
|
|
|
12347
12409
|
}
|
|
12348
12410
|
});
|
|
12349
12411
|
|
|
12412
|
+
// src/agents/user-mcp-config.ts
|
|
12413
|
+
function userCursorMcpConfigPath() {
|
|
12414
|
+
return (0, import_node_path34.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
|
|
12415
|
+
}
|
|
12416
|
+
function userClaudeMcpConfigPath() {
|
|
12417
|
+
return (0, import_node_path34.join)((0, import_node_os10.homedir)(), ".claude.json");
|
|
12418
|
+
}
|
|
12419
|
+
function asObject(value) {
|
|
12420
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
12421
|
+
return { ...value };
|
|
12422
|
+
}
|
|
12423
|
+
function stripElectronSpawnEnv(env) {
|
|
12424
|
+
if (!env) return void 0;
|
|
12425
|
+
const next = { ...env };
|
|
12426
|
+
delete next.ELECTRON_RUN_AS_NODE;
|
|
12427
|
+
delete next.ELECTRON_RUN_AS_NODE;
|
|
12428
|
+
return Object.keys(next).length > 0 ? next : void 0;
|
|
12429
|
+
}
|
|
12430
|
+
function mergeSideboardIntoMcpServersJson(existing, sideboard) {
|
|
12431
|
+
const root = asObject(existing);
|
|
12432
|
+
const servers = asObject(root.mcpServers);
|
|
12433
|
+
const env = stripElectronSpawnEnv(sideboard.env);
|
|
12434
|
+
servers.sideboard = {
|
|
12435
|
+
type: "stdio",
|
|
12436
|
+
command: sideboard.command,
|
|
12437
|
+
...sideboard.args && sideboard.args.length > 0 ? { args: sideboard.args } : {},
|
|
12438
|
+
...env ? { env } : {}
|
|
12439
|
+
};
|
|
12440
|
+
return { ...root, mcpServers: servers };
|
|
12441
|
+
}
|
|
12442
|
+
function writeMergedMcpServersJson(configPath, sideboard) {
|
|
12443
|
+
let existing = {};
|
|
12444
|
+
if ((0, import_node_fs31.existsSync)(configPath)) {
|
|
12445
|
+
try {
|
|
12446
|
+
existing = JSON.parse((0, import_node_fs31.readFileSync)(configPath, "utf8"));
|
|
12447
|
+
} catch {
|
|
12448
|
+
existing = {};
|
|
12449
|
+
}
|
|
12450
|
+
}
|
|
12451
|
+
const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
|
|
12452
|
+
(0, import_node_fs31.mkdirSync)((0, import_node_path34.dirname)(configPath), { recursive: true });
|
|
12453
|
+
(0, import_node_fs31.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
|
|
12454
|
+
`);
|
|
12455
|
+
}
|
|
12456
|
+
function launchFromResolved(server) {
|
|
12457
|
+
return {
|
|
12458
|
+
command: server.command,
|
|
12459
|
+
args: server.args,
|
|
12460
|
+
env: {
|
|
12461
|
+
...server.env ?? {},
|
|
12462
|
+
SIDEBOARD_APP_DATA: appDataDir()
|
|
12463
|
+
}
|
|
12464
|
+
};
|
|
12465
|
+
}
|
|
12466
|
+
async function registerPackagedUserMcpClients() {
|
|
12467
|
+
const launch = launchFromResolved(await resolveSideboardMcpServer());
|
|
12468
|
+
const cursor = userCursorMcpConfigPath();
|
|
12469
|
+
writeMergedMcpServersJson(cursor, launch);
|
|
12470
|
+
const claude = userClaudeMcpConfigPath();
|
|
12471
|
+
if ((0, import_node_fs31.existsSync)(claude)) {
|
|
12472
|
+
writeMergedMcpServersJson(claude, launch);
|
|
12473
|
+
return { cursor, claude };
|
|
12474
|
+
}
|
|
12475
|
+
return { cursor };
|
|
12476
|
+
}
|
|
12477
|
+
var import_node_fs31, import_node_os10, import_node_path34;
|
|
12478
|
+
var init_user_mcp_config = __esm({
|
|
12479
|
+
"src/agents/user-mcp-config.ts"() {
|
|
12480
|
+
"use strict";
|
|
12481
|
+
import_node_fs31 = require("fs");
|
|
12482
|
+
import_node_os10 = require("os");
|
|
12483
|
+
import_node_path34 = require("path");
|
|
12484
|
+
init_paths();
|
|
12485
|
+
init_injected_mcp();
|
|
12486
|
+
}
|
|
12487
|
+
});
|
|
12488
|
+
|
|
12489
|
+
// src/agents/orch-mcp-isolation.ts
|
|
12490
|
+
function isInjectedOrchMcpName(name) {
|
|
12491
|
+
const n = name.trim().toLowerCase();
|
|
12492
|
+
return n === "sideboard" || n === "brightsy" || n.startsWith("brightsy_");
|
|
12493
|
+
}
|
|
12494
|
+
function asObject2(value) {
|
|
12495
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
12496
|
+
return value;
|
|
12497
|
+
}
|
|
12498
|
+
function listMcpNamesFromJsonMap(raw, key) {
|
|
12499
|
+
return Object.keys(asObject2(asObject2(raw)[key])).filter((n) => n.trim());
|
|
12500
|
+
}
|
|
12501
|
+
function listMcpNamesFromCodexToml(text7) {
|
|
12502
|
+
try {
|
|
12503
|
+
const parsed = (0, import_smol_toml2.parse)(text7);
|
|
12504
|
+
return Object.keys(asObject2(parsed.mcp_servers)).filter((n) => n.trim());
|
|
12505
|
+
} catch {
|
|
12506
|
+
return [];
|
|
12507
|
+
}
|
|
12508
|
+
}
|
|
12509
|
+
function readJsonObject(path2) {
|
|
12510
|
+
try {
|
|
12511
|
+
return JSON.parse((0, import_node_fs32.readFileSync)(path2, "utf8"));
|
|
12512
|
+
} catch {
|
|
12513
|
+
return {};
|
|
12514
|
+
}
|
|
12515
|
+
}
|
|
12516
|
+
function readText(path2) {
|
|
12517
|
+
try {
|
|
12518
|
+
return (0, import_node_fs32.readFileSync)(path2, "utf8");
|
|
12519
|
+
} catch {
|
|
12520
|
+
return "";
|
|
12521
|
+
}
|
|
12522
|
+
}
|
|
12523
|
+
function userCodexConfigPaths(home = (0, import_node_os11.homedir)()) {
|
|
12524
|
+
return [(0, import_node_path35.join)(home, ".codex", "config.toml"), (0, import_node_path35.join)(home, ".config", "codex", "config.toml")];
|
|
12525
|
+
}
|
|
12526
|
+
function userOpencodeConfigPaths(home = (0, import_node_os11.homedir)()) {
|
|
12527
|
+
return [
|
|
12528
|
+
(0, import_node_path35.join)(home, ".config", "opencode", "opencode.json"),
|
|
12529
|
+
(0, import_node_path35.join)(home, ".config", "opencode", "opencode.jsonc")
|
|
12530
|
+
];
|
|
12531
|
+
}
|
|
12532
|
+
function userMcpNamesToDisable(opts) {
|
|
12533
|
+
const keep = new Set(
|
|
12534
|
+
[...opts.injectedNames ?? []].map((n) => n.trim().toLowerCase()).filter(Boolean)
|
|
12535
|
+
);
|
|
12536
|
+
const out = [];
|
|
12537
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12538
|
+
for (const raw of opts.names) {
|
|
12539
|
+
const name = raw.trim();
|
|
12540
|
+
if (!name) continue;
|
|
12541
|
+
const key = name.toLowerCase();
|
|
12542
|
+
if (seen.has(key) || keep.has(key) || isInjectedOrchMcpName(name)) continue;
|
|
12543
|
+
seen.add(key);
|
|
12544
|
+
out.push(name);
|
|
12545
|
+
}
|
|
12546
|
+
return out;
|
|
12547
|
+
}
|
|
12548
|
+
function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
|
|
12549
|
+
const names = [];
|
|
12550
|
+
for (const path2 of userCodexConfigPaths(home)) {
|
|
12551
|
+
if (!(0, import_node_fs32.existsSync)(path2)) continue;
|
|
12552
|
+
names.push(...listMcpNamesFromCodexToml(readText(path2)));
|
|
12553
|
+
}
|
|
12554
|
+
return names;
|
|
12555
|
+
}
|
|
12556
|
+
function listUserOpencodeMcpNames(home = (0, import_node_os11.homedir)()) {
|
|
12557
|
+
const names = [];
|
|
12558
|
+
for (const path2 of userOpencodeConfigPaths(home)) {
|
|
12559
|
+
if (!(0, import_node_fs32.existsSync)(path2)) continue;
|
|
12560
|
+
names.push(...listMcpNamesFromJsonMap(readJsonObject(path2), "mcp"));
|
|
12561
|
+
}
|
|
12562
|
+
return names;
|
|
12563
|
+
}
|
|
12564
|
+
function listUserClaudeMcpNames(home = (0, import_node_os11.homedir)()) {
|
|
12565
|
+
const claudePath = home === (0, import_node_os11.homedir)() ? userClaudeMcpConfigPath() : (0, import_node_path35.join)(home, ".claude.json");
|
|
12566
|
+
if (!(0, import_node_fs32.existsSync)(claudePath)) return [];
|
|
12567
|
+
return listMcpNamesFromJsonMap(readJsonObject(claudePath), "mcpServers");
|
|
12568
|
+
}
|
|
12569
|
+
function toCodexDisableUserMcpArgs(names) {
|
|
12570
|
+
const args = [];
|
|
12571
|
+
for (const name of names) {
|
|
12572
|
+
if (!/^[A-Za-z0-9_-]+$/.test(name)) continue;
|
|
12573
|
+
args.push("-c", `mcp_servers.${name}.enabled=false`);
|
|
12574
|
+
}
|
|
12575
|
+
return args;
|
|
12576
|
+
}
|
|
12577
|
+
function toCodexUnattendedAppsArgs() {
|
|
12578
|
+
return [
|
|
12579
|
+
"-c",
|
|
12580
|
+
"features.apps=false",
|
|
12581
|
+
"-c",
|
|
12582
|
+
"apps._default.enabled=false",
|
|
12583
|
+
"-c",
|
|
12584
|
+
"apps.posthog.enabled=false",
|
|
12585
|
+
"-c",
|
|
12586
|
+
"features.plugins=false"
|
|
12587
|
+
];
|
|
12588
|
+
}
|
|
12589
|
+
var import_node_fs32, import_node_os11, import_node_path35, import_smol_toml2;
|
|
12590
|
+
var init_orch_mcp_isolation = __esm({
|
|
12591
|
+
"src/agents/orch-mcp-isolation.ts"() {
|
|
12592
|
+
"use strict";
|
|
12593
|
+
import_node_fs32 = require("fs");
|
|
12594
|
+
import_node_os11 = require("os");
|
|
12595
|
+
import_node_path35 = require("path");
|
|
12596
|
+
import_smol_toml2 = require("smol-toml");
|
|
12597
|
+
init_user_mcp_config();
|
|
12598
|
+
}
|
|
12599
|
+
});
|
|
12600
|
+
|
|
12350
12601
|
// src/agents/types.ts
|
|
12351
12602
|
function permissionMode(thread) {
|
|
12352
12603
|
if (thread.sourceType === "orchestration") {
|
|
@@ -12395,16 +12646,8 @@ var init_types = __esm({
|
|
|
12395
12646
|
});
|
|
12396
12647
|
|
|
12397
12648
|
// src/agents/claude.ts
|
|
12398
|
-
|
|
12399
|
-
|
|
12400
|
-
return mcpListCache.servers;
|
|
12401
|
-
}
|
|
12402
|
-
const claude = resolveClaudeExecutable();
|
|
12403
|
-
const mcpText = await run(claude, ["mcp", "list"], { reject: false });
|
|
12404
|
-
const servers = parseMcpList(`${mcpText.stdout}
|
|
12405
|
-
${mcpText.stderr}`);
|
|
12406
|
-
mcpListCache = { at: Date.now(), servers };
|
|
12407
|
-
return servers;
|
|
12649
|
+
function isLocalDevAppDataDir(dir = process.env.SIDEBOARD_APP_DATA) {
|
|
12650
|
+
return /[/\\]\.sideboard[/\\]dev-app-data(?:[/\\]|$)/.test(dir ?? "");
|
|
12408
12651
|
}
|
|
12409
12652
|
function usageFromClaude(usage) {
|
|
12410
12653
|
if (!usage) return null;
|
|
@@ -12712,14 +12955,15 @@ function parseIssuesJson(raw) {
|
|
|
12712
12955
|
}
|
|
12713
12956
|
return [];
|
|
12714
12957
|
}
|
|
12715
|
-
var
|
|
12958
|
+
var import_node_fs33, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
|
|
12716
12959
|
var init_claude = __esm({
|
|
12717
12960
|
"src/agents/claude.ts"() {
|
|
12718
12961
|
"use strict";
|
|
12719
|
-
|
|
12962
|
+
import_node_fs33 = require("fs");
|
|
12720
12963
|
init_run();
|
|
12721
12964
|
init_app_settings();
|
|
12722
12965
|
init_claude_mcp();
|
|
12966
|
+
init_orch_mcp_isolation();
|
|
12723
12967
|
init_error_detail();
|
|
12724
12968
|
init_message_parts();
|
|
12725
12969
|
init_injected_mcp();
|
|
@@ -12750,13 +12994,12 @@ var init_claude = __esm({
|
|
|
12750
12994
|
"Skill(claude-in-chrome)"
|
|
12751
12995
|
];
|
|
12752
12996
|
CLAUDE_PROMPT_ARG_MAX = 2e5;
|
|
12753
|
-
mcpListCache = null;
|
|
12754
12997
|
claudeAdapter = {
|
|
12755
12998
|
kind: "claude",
|
|
12756
12999
|
async detect() {
|
|
12757
13000
|
const claude = resolveClaudeExecutable();
|
|
12758
13001
|
if (claude !== "claude") {
|
|
12759
|
-
if (!(0,
|
|
13002
|
+
if (!(0, import_node_fs33.existsSync)(claude)) {
|
|
12760
13003
|
return {
|
|
12761
13004
|
agent: "claude",
|
|
12762
13005
|
installed: false,
|
|
@@ -12824,10 +13067,9 @@ var init_claude = __esm({
|
|
|
12824
13067
|
...brightsyMcpAllowedTools(injectedBrightsyNames)
|
|
12825
13068
|
];
|
|
12826
13069
|
} else {
|
|
12827
|
-
const servers = await loadMcpServers();
|
|
12828
13070
|
allowedTools = [
|
|
12829
13071
|
...BASE_ALLOWED_TOOLS,
|
|
12830
|
-
...
|
|
13072
|
+
...mcpAllowToolsFromNames(userMcpNamesToDisable({ names: listUserClaudeMcpNames() })),
|
|
12831
13073
|
...sideboardWorktreeAllowedTools({
|
|
12832
13074
|
github: true,
|
|
12833
13075
|
linear: isLinearConnected(),
|
|
@@ -12855,9 +13097,7 @@ var init_claude = __esm({
|
|
|
12855
13097
|
const mcpConfigPath = writeMcpServersConfig(injectedServers);
|
|
12856
13098
|
if (mcpConfigPath) {
|
|
12857
13099
|
args.push("--mcp-config", mcpConfigPath);
|
|
12858
|
-
|
|
12859
|
-
args.push("--strict-mcp-config");
|
|
12860
|
-
}
|
|
13100
|
+
args.push("--strict-mcp-config");
|
|
12861
13101
|
}
|
|
12862
13102
|
if (chromeOn) {
|
|
12863
13103
|
args.push("--chrome");
|
|
@@ -12889,8 +13129,10 @@ var init_claude = __esm({
|
|
|
12889
13129
|
CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
|
|
12890
13130
|
CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS),
|
|
12891
13131
|
// `--strict-mcp-config` still fetches claude.ai connectors on some CLI
|
|
12892
|
-
// builds (anthropics/claude-code#60252). Coordinators
|
|
12893
|
-
|
|
13132
|
+
// builds (anthropics/claude-code#60252). Coordinators never need them.
|
|
13133
|
+
// Local `pnpm dev` also disables them: those HTTP connectors hang the
|
|
13134
|
+
// first worktree turn when Electron's cwd is this Sideboard repo.
|
|
13135
|
+
...isOrchestrator || isLocalDevAppDataDir() ? { ENABLE_CLAUDEAI_MCP_SERVERS: "false" } : {}
|
|
12894
13136
|
}
|
|
12895
13137
|
};
|
|
12896
13138
|
},
|
|
@@ -12952,249 +13194,65 @@ var init_claude = __esm({
|
|
|
12952
13194
|
if (delta?.text) return withEventParentId({ type: "stdout", data: delta.text }, parentId);
|
|
12953
13195
|
if (delta?.thinking) {
|
|
12954
13196
|
return withEventParentId({ type: "thinking", data: delta.thinking }, parentId);
|
|
12955
|
-
}
|
|
12956
|
-
return null;
|
|
12957
|
-
}
|
|
12958
|
-
if (obj.type === "result") {
|
|
12959
|
-
const events = [];
|
|
12960
|
-
const errorDetail = claudeResultErrorDetail(obj);
|
|
12961
|
-
if (errorDetail) {
|
|
12962
|
-
events.push({ type: "stderr", data: errorDetail });
|
|
12963
|
-
} else {
|
|
12964
|
-
const text7 = obj.result;
|
|
12965
|
-
if (typeof text7 === "string" && text7) events.push({ type: "stdout", data: text7 });
|
|
12966
|
-
}
|
|
12967
|
-
const usage = usageFromClaude(obj.usage);
|
|
12968
|
-
if (usage) {
|
|
12969
|
-
const costUsd = costUsdFromClaudeResult(obj);
|
|
12970
|
-
if (costUsd != null) usage.costUsd = costUsd;
|
|
12971
|
-
events.push({ type: "usage", data: usage, scope: "turn" });
|
|
12972
|
-
}
|
|
12973
|
-
if (events.length === 0) return null;
|
|
12974
|
-
return events.length === 1 ? events[0] : events;
|
|
12975
|
-
}
|
|
12976
|
-
return null;
|
|
12977
|
-
} catch {
|
|
12978
|
-
return { type: "stdout", data: line };
|
|
12979
|
-
}
|
|
12980
|
-
},
|
|
12981
|
-
async resolveSessionId(_worktreePath, cached) {
|
|
12982
|
-
return cached;
|
|
12983
|
-
},
|
|
12984
|
-
async buildAttach(thread) {
|
|
12985
|
-
const claude = resolveClaudeExecutable();
|
|
12986
|
-
const sessionId = await this.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
12987
|
-
const args = sessionId ? ["--resume", sessionId] : [];
|
|
12988
|
-
if (claudeChromeEnabled()) {
|
|
12989
|
-
args.push("--chrome");
|
|
12990
|
-
}
|
|
12991
|
-
return { file: claude, args, cwd: thread.worktreePath };
|
|
12992
|
-
},
|
|
12993
|
-
async listLinearIssues(_repoPath) {
|
|
12994
|
-
const claude = resolveClaudeExecutable();
|
|
12995
|
-
const prompt = "List my assigned Linear issues as JSON array only, no markdown. Each item: id, identifier, title, url, labels (string[]).";
|
|
12996
|
-
const { stdout, exitCode } = await run(
|
|
12997
|
-
claude,
|
|
12998
|
-
[
|
|
12999
|
-
"-p",
|
|
13000
|
-
prompt,
|
|
13001
|
-
"--output-format",
|
|
13002
|
-
"json",
|
|
13003
|
-
"--permission-mode",
|
|
13004
|
-
"bypassPermissions",
|
|
13005
|
-
"--allowedTools",
|
|
13006
|
-
"mcp__linear__*"
|
|
13007
|
-
],
|
|
13008
|
-
{ reject: false }
|
|
13009
|
-
);
|
|
13010
|
-
if (exitCode !== 0) return [];
|
|
13011
|
-
return parseIssuesJson(stdout);
|
|
13012
|
-
}
|
|
13013
|
-
};
|
|
13014
|
-
}
|
|
13015
|
-
});
|
|
13016
|
-
|
|
13017
|
-
// src/agents/user-mcp-config.ts
|
|
13018
|
-
function userCursorMcpConfigPath() {
|
|
13019
|
-
return (0, import_node_path33.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
|
|
13020
|
-
}
|
|
13021
|
-
function userClaudeMcpConfigPath() {
|
|
13022
|
-
return (0, import_node_path33.join)((0, import_node_os10.homedir)(), ".claude.json");
|
|
13023
|
-
}
|
|
13024
|
-
function asObject(value) {
|
|
13025
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
13026
|
-
return { ...value };
|
|
13027
|
-
}
|
|
13028
|
-
function stripElectronSpawnEnv(env) {
|
|
13029
|
-
if (!env) return void 0;
|
|
13030
|
-
const next = { ...env };
|
|
13031
|
-
delete next.ELECTRON_RUN_AS_NODE;
|
|
13032
|
-
delete next.ELECTRON_RUN_AS_NODE;
|
|
13033
|
-
return Object.keys(next).length > 0 ? next : void 0;
|
|
13034
|
-
}
|
|
13035
|
-
function mergeSideboardIntoMcpServersJson(existing, sideboard) {
|
|
13036
|
-
const root = asObject(existing);
|
|
13037
|
-
const servers = asObject(root.mcpServers);
|
|
13038
|
-
const env = stripElectronSpawnEnv(sideboard.env);
|
|
13039
|
-
servers.sideboard = {
|
|
13040
|
-
type: "stdio",
|
|
13041
|
-
command: sideboard.command,
|
|
13042
|
-
...sideboard.args && sideboard.args.length > 0 ? { args: sideboard.args } : {},
|
|
13043
|
-
...env ? { env } : {}
|
|
13044
|
-
};
|
|
13045
|
-
return { ...root, mcpServers: servers };
|
|
13046
|
-
}
|
|
13047
|
-
function writeMergedMcpServersJson(configPath, sideboard) {
|
|
13048
|
-
let existing = {};
|
|
13049
|
-
if ((0, import_node_fs31.existsSync)(configPath)) {
|
|
13050
|
-
try {
|
|
13051
|
-
existing = JSON.parse((0, import_node_fs31.readFileSync)(configPath, "utf8"));
|
|
13052
|
-
} catch {
|
|
13053
|
-
existing = {};
|
|
13054
|
-
}
|
|
13055
|
-
}
|
|
13056
|
-
const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
|
|
13057
|
-
(0, import_node_fs31.mkdirSync)((0, import_node_path33.dirname)(configPath), { recursive: true });
|
|
13058
|
-
(0, import_node_fs31.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
|
|
13059
|
-
`);
|
|
13060
|
-
}
|
|
13061
|
-
function launchFromResolved(server) {
|
|
13062
|
-
return {
|
|
13063
|
-
command: server.command,
|
|
13064
|
-
args: server.args,
|
|
13065
|
-
env: {
|
|
13066
|
-
...server.env ?? {},
|
|
13067
|
-
SIDEBOARD_APP_DATA: appDataDir()
|
|
13068
|
-
}
|
|
13069
|
-
};
|
|
13070
|
-
}
|
|
13071
|
-
async function registerPackagedUserMcpClients() {
|
|
13072
|
-
const launch = launchFromResolved(await resolveSideboardMcpServer());
|
|
13073
|
-
const cursor = userCursorMcpConfigPath();
|
|
13074
|
-
writeMergedMcpServersJson(cursor, launch);
|
|
13075
|
-
const claude = userClaudeMcpConfigPath();
|
|
13076
|
-
if ((0, import_node_fs31.existsSync)(claude)) {
|
|
13077
|
-
writeMergedMcpServersJson(claude, launch);
|
|
13078
|
-
return { cursor, claude };
|
|
13079
|
-
}
|
|
13080
|
-
return { cursor };
|
|
13081
|
-
}
|
|
13082
|
-
var import_node_fs31, import_node_os10, import_node_path33;
|
|
13083
|
-
var init_user_mcp_config = __esm({
|
|
13084
|
-
"src/agents/user-mcp-config.ts"() {
|
|
13085
|
-
"use strict";
|
|
13086
|
-
import_node_fs31 = require("fs");
|
|
13087
|
-
import_node_os10 = require("os");
|
|
13088
|
-
import_node_path33 = require("path");
|
|
13089
|
-
init_paths();
|
|
13090
|
-
init_injected_mcp();
|
|
13091
|
-
}
|
|
13092
|
-
});
|
|
13093
|
-
|
|
13094
|
-
// src/agents/orch-mcp-isolation.ts
|
|
13095
|
-
function isInjectedOrchMcpName(name) {
|
|
13096
|
-
const n = name.trim().toLowerCase();
|
|
13097
|
-
return n === "sideboard" || n === "brightsy" || n.startsWith("brightsy_");
|
|
13098
|
-
}
|
|
13099
|
-
function asObject2(value) {
|
|
13100
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
13101
|
-
return value;
|
|
13102
|
-
}
|
|
13103
|
-
function listMcpNamesFromJsonMap(raw, key) {
|
|
13104
|
-
return Object.keys(asObject2(asObject2(raw)[key])).filter((n) => n.trim());
|
|
13105
|
-
}
|
|
13106
|
-
function listMcpNamesFromCodexToml(text7) {
|
|
13107
|
-
try {
|
|
13108
|
-
const parsed = (0, import_smol_toml2.parse)(text7);
|
|
13109
|
-
return Object.keys(asObject2(parsed.mcp_servers)).filter((n) => n.trim());
|
|
13110
|
-
} catch {
|
|
13111
|
-
return [];
|
|
13112
|
-
}
|
|
13113
|
-
}
|
|
13114
|
-
function readJsonObject(path2) {
|
|
13115
|
-
try {
|
|
13116
|
-
return JSON.parse((0, import_node_fs32.readFileSync)(path2, "utf8"));
|
|
13117
|
-
} catch {
|
|
13118
|
-
return {};
|
|
13119
|
-
}
|
|
13120
|
-
}
|
|
13121
|
-
function readText(path2) {
|
|
13122
|
-
try {
|
|
13123
|
-
return (0, import_node_fs32.readFileSync)(path2, "utf8");
|
|
13124
|
-
} catch {
|
|
13125
|
-
return "";
|
|
13126
|
-
}
|
|
13127
|
-
}
|
|
13128
|
-
function userCodexConfigPaths(home = (0, import_node_os11.homedir)()) {
|
|
13129
|
-
return [(0, import_node_path34.join)(home, ".codex", "config.toml"), (0, import_node_path34.join)(home, ".config", "codex", "config.toml")];
|
|
13130
|
-
}
|
|
13131
|
-
function userOpencodeConfigPaths(home = (0, import_node_os11.homedir)()) {
|
|
13132
|
-
return [
|
|
13133
|
-
(0, import_node_path34.join)(home, ".config", "opencode", "opencode.json"),
|
|
13134
|
-
(0, import_node_path34.join)(home, ".config", "opencode", "opencode.jsonc")
|
|
13135
|
-
];
|
|
13136
|
-
}
|
|
13137
|
-
function userMcpNamesToDisable(opts) {
|
|
13138
|
-
const keep = new Set(
|
|
13139
|
-
[...opts.injectedNames ?? []].map((n) => n.trim().toLowerCase()).filter(Boolean)
|
|
13140
|
-
);
|
|
13141
|
-
const out = [];
|
|
13142
|
-
const seen = /* @__PURE__ */ new Set();
|
|
13143
|
-
for (const raw of opts.names) {
|
|
13144
|
-
const name = raw.trim();
|
|
13145
|
-
if (!name) continue;
|
|
13146
|
-
const key = name.toLowerCase();
|
|
13147
|
-
if (seen.has(key) || keep.has(key) || isInjectedOrchMcpName(name)) continue;
|
|
13148
|
-
seen.add(key);
|
|
13149
|
-
out.push(name);
|
|
13150
|
-
}
|
|
13151
|
-
return out;
|
|
13152
|
-
}
|
|
13153
|
-
function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
|
|
13154
|
-
const names = [];
|
|
13155
|
-
for (const path2 of userCodexConfigPaths(home)) {
|
|
13156
|
-
if (!(0, import_node_fs32.existsSync)(path2)) continue;
|
|
13157
|
-
names.push(...listMcpNamesFromCodexToml(readText(path2)));
|
|
13158
|
-
}
|
|
13159
|
-
return names;
|
|
13160
|
-
}
|
|
13161
|
-
function listUserOpencodeMcpNames(home = (0, import_node_os11.homedir)()) {
|
|
13162
|
-
const names = [];
|
|
13163
|
-
for (const path2 of userOpencodeConfigPaths(home)) {
|
|
13164
|
-
if (!(0, import_node_fs32.existsSync)(path2)) continue;
|
|
13165
|
-
names.push(...listMcpNamesFromJsonMap(readJsonObject(path2), "mcp"));
|
|
13166
|
-
}
|
|
13167
|
-
return names;
|
|
13168
|
-
}
|
|
13169
|
-
function toCodexDisableUserMcpArgs(names) {
|
|
13170
|
-
const args = [];
|
|
13171
|
-
for (const name of names) {
|
|
13172
|
-
if (!/^[A-Za-z0-9_-]+$/.test(name)) continue;
|
|
13173
|
-
args.push("-c", `mcp_servers.${name}.enabled=false`);
|
|
13174
|
-
}
|
|
13175
|
-
return args;
|
|
13176
|
-
}
|
|
13177
|
-
function toCodexUnattendedAppsArgs() {
|
|
13178
|
-
return [
|
|
13179
|
-
"-c",
|
|
13180
|
-
"features.apps=false",
|
|
13181
|
-
"-c",
|
|
13182
|
-
"apps._default.enabled=false",
|
|
13183
|
-
"-c",
|
|
13184
|
-
"apps.posthog.enabled=false",
|
|
13185
|
-
"-c",
|
|
13186
|
-
"features.plugins=false"
|
|
13187
|
-
];
|
|
13188
|
-
}
|
|
13189
|
-
var import_node_fs32, import_node_os11, import_node_path34, import_smol_toml2;
|
|
13190
|
-
var init_orch_mcp_isolation = __esm({
|
|
13191
|
-
"src/agents/orch-mcp-isolation.ts"() {
|
|
13192
|
-
"use strict";
|
|
13193
|
-
import_node_fs32 = require("fs");
|
|
13194
|
-
import_node_os11 = require("os");
|
|
13195
|
-
import_node_path34 = require("path");
|
|
13196
|
-
import_smol_toml2 = require("smol-toml");
|
|
13197
|
-
init_user_mcp_config();
|
|
13197
|
+
}
|
|
13198
|
+
return null;
|
|
13199
|
+
}
|
|
13200
|
+
if (obj.type === "result") {
|
|
13201
|
+
const events = [];
|
|
13202
|
+
const errorDetail = claudeResultErrorDetail(obj);
|
|
13203
|
+
if (errorDetail) {
|
|
13204
|
+
events.push({ type: "stderr", data: errorDetail });
|
|
13205
|
+
} else {
|
|
13206
|
+
const text7 = obj.result;
|
|
13207
|
+
if (typeof text7 === "string" && text7) events.push({ type: "stdout", data: text7 });
|
|
13208
|
+
}
|
|
13209
|
+
const usage = usageFromClaude(obj.usage);
|
|
13210
|
+
if (usage) {
|
|
13211
|
+
const costUsd = costUsdFromClaudeResult(obj);
|
|
13212
|
+
if (costUsd != null) usage.costUsd = costUsd;
|
|
13213
|
+
events.push({ type: "usage", data: usage, scope: "turn" });
|
|
13214
|
+
}
|
|
13215
|
+
if (events.length === 0) return null;
|
|
13216
|
+
return events.length === 1 ? events[0] : events;
|
|
13217
|
+
}
|
|
13218
|
+
return null;
|
|
13219
|
+
} catch {
|
|
13220
|
+
return { type: "stdout", data: line };
|
|
13221
|
+
}
|
|
13222
|
+
},
|
|
13223
|
+
async resolveSessionId(_worktreePath, cached) {
|
|
13224
|
+
return cached;
|
|
13225
|
+
},
|
|
13226
|
+
async buildAttach(thread) {
|
|
13227
|
+
const claude = resolveClaudeExecutable();
|
|
13228
|
+
const sessionId = await this.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
13229
|
+
const args = sessionId ? ["--resume", sessionId] : [];
|
|
13230
|
+
if (claudeChromeEnabled()) {
|
|
13231
|
+
args.push("--chrome");
|
|
13232
|
+
}
|
|
13233
|
+
return { file: claude, args, cwd: thread.worktreePath };
|
|
13234
|
+
},
|
|
13235
|
+
async listLinearIssues(_repoPath) {
|
|
13236
|
+
const claude = resolveClaudeExecutable();
|
|
13237
|
+
const prompt = "List my assigned Linear issues as JSON array only, no markdown. Each item: id, identifier, title, url, labels (string[]).";
|
|
13238
|
+
const { stdout, exitCode } = await run(
|
|
13239
|
+
claude,
|
|
13240
|
+
[
|
|
13241
|
+
"-p",
|
|
13242
|
+
prompt,
|
|
13243
|
+
"--output-format",
|
|
13244
|
+
"json",
|
|
13245
|
+
"--permission-mode",
|
|
13246
|
+
"bypassPermissions",
|
|
13247
|
+
"--allowedTools",
|
|
13248
|
+
"mcp__linear__*"
|
|
13249
|
+
],
|
|
13250
|
+
{ reject: false }
|
|
13251
|
+
);
|
|
13252
|
+
if (exitCode !== 0) return [];
|
|
13253
|
+
return parseIssuesJson(stdout);
|
|
13254
|
+
}
|
|
13255
|
+
};
|
|
13198
13256
|
}
|
|
13199
13257
|
});
|
|
13200
13258
|
|
|
@@ -13208,7 +13266,7 @@ async function listCodexModels() {
|
|
|
13208
13266
|
if (codex === "codex") {
|
|
13209
13267
|
const which = await run("which", ["codex"], { reject: false });
|
|
13210
13268
|
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
13211
|
-
} else if (!(0,
|
|
13269
|
+
} else if (!(0, import_node_fs34.existsSync)(codex)) {
|
|
13212
13270
|
return FALLBACK_CODEX_MODELS;
|
|
13213
13271
|
}
|
|
13214
13272
|
const listed = await run(codex, ["debug", "models"], { reject: false });
|
|
@@ -13243,12 +13301,12 @@ function usageFromCodex(usage) {
|
|
|
13243
13301
|
}
|
|
13244
13302
|
function codexConfigHasNetworkAccess() {
|
|
13245
13303
|
const candidates = [
|
|
13246
|
-
(0,
|
|
13247
|
-
(0,
|
|
13304
|
+
(0, import_node_path36.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
|
|
13305
|
+
(0, import_node_path36.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
|
|
13248
13306
|
];
|
|
13249
13307
|
for (const path2 of candidates) {
|
|
13250
|
-
if (!(0,
|
|
13251
|
-
const text7 = (0,
|
|
13308
|
+
if (!(0, import_node_fs34.existsSync)(path2)) continue;
|
|
13309
|
+
const text7 = (0, import_node_fs34.readFileSync)(path2, "utf8");
|
|
13252
13310
|
if (/network_access\s*=\s*true/.test(text7)) return true;
|
|
13253
13311
|
}
|
|
13254
13312
|
return false;
|
|
@@ -13280,21 +13338,21 @@ function asRecord2(value) {
|
|
|
13280
13338
|
return void 0;
|
|
13281
13339
|
}
|
|
13282
13340
|
function codexLooksAuthenticated() {
|
|
13283
|
-
const authPath = (0,
|
|
13284
|
-
if (!(0,
|
|
13341
|
+
const authPath = (0, import_node_path36.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
|
|
13342
|
+
if (!(0, import_node_fs34.existsSync)(authPath)) return false;
|
|
13285
13343
|
try {
|
|
13286
|
-
return (0,
|
|
13344
|
+
return (0, import_node_fs34.statSync)(authPath).size > 2;
|
|
13287
13345
|
} catch {
|
|
13288
13346
|
return false;
|
|
13289
13347
|
}
|
|
13290
13348
|
}
|
|
13291
|
-
var
|
|
13349
|
+
var import_node_fs34, import_node_os12, import_node_path36, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
13292
13350
|
var init_codex = __esm({
|
|
13293
13351
|
"src/agents/codex.ts"() {
|
|
13294
13352
|
"use strict";
|
|
13295
|
-
|
|
13353
|
+
import_node_fs34 = require("fs");
|
|
13296
13354
|
import_node_os12 = require("os");
|
|
13297
|
-
|
|
13355
|
+
import_node_path36 = require("path");
|
|
13298
13356
|
init_run();
|
|
13299
13357
|
init_app_settings();
|
|
13300
13358
|
init_global_workspace();
|
|
@@ -13320,7 +13378,7 @@ var init_codex = __esm({
|
|
|
13320
13378
|
async detect() {
|
|
13321
13379
|
const codex = resolveAgentExecutable("codex");
|
|
13322
13380
|
if (codex !== "codex") {
|
|
13323
|
-
if (!(0,
|
|
13381
|
+
if (!(0, import_node_fs34.existsSync)(codex)) {
|
|
13324
13382
|
return {
|
|
13325
13383
|
agent: "codex",
|
|
13326
13384
|
installed: false,
|
|
@@ -13820,21 +13878,21 @@ function platformRipgrepPackage() {
|
|
|
13820
13878
|
}
|
|
13821
13879
|
function usableRipgrepPath(candidate) {
|
|
13822
13880
|
const raw = candidate?.trim();
|
|
13823
|
-
if (!raw || !(0,
|
|
13881
|
+
if (!raw || !(0, import_node_path37.isAbsolute)(raw)) return null;
|
|
13824
13882
|
const readable = nodeReadableScriptPath(raw);
|
|
13825
|
-
if (!(0,
|
|
13883
|
+
if (!(0, import_node_fs35.existsSync)(readable) || isAsarPath(readable)) return null;
|
|
13826
13884
|
return readable;
|
|
13827
13885
|
}
|
|
13828
13886
|
function walkForBundledRipgrep(startFile) {
|
|
13829
13887
|
if (!startFile) return null;
|
|
13830
13888
|
const pkg = platformRipgrepPackage();
|
|
13831
13889
|
const name = rgBinaryName();
|
|
13832
|
-
let dir = (0,
|
|
13833
|
-
const root = (0,
|
|
13890
|
+
let dir = (0, import_node_path37.dirname)((0, import_node_path37.resolve)(startFile));
|
|
13891
|
+
const root = (0, import_node_path37.parse)(dir).root;
|
|
13834
13892
|
while (dir !== root) {
|
|
13835
|
-
const hit = usableRipgrepPath((0,
|
|
13893
|
+
const hit = usableRipgrepPath((0, import_node_path37.join)(dir, "node_modules", pkg, "bin", name));
|
|
13836
13894
|
if (hit) return hit;
|
|
13837
|
-
const next = (0,
|
|
13895
|
+
const next = (0, import_node_path37.dirname)(dir);
|
|
13838
13896
|
if (next === dir) break;
|
|
13839
13897
|
dir = next;
|
|
13840
13898
|
}
|
|
@@ -13844,7 +13902,7 @@ function requireResolveBundledRipgrep(fromFile) {
|
|
|
13844
13902
|
try {
|
|
13845
13903
|
const req = (0, import_node_module2.createRequire)(fromFile);
|
|
13846
13904
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
13847
|
-
return usableRipgrepPath((0,
|
|
13905
|
+
return usableRipgrepPath((0, import_node_path37.join)((0, import_node_path37.dirname)(pkgJson), "bin", rgBinaryName()));
|
|
13848
13906
|
} catch {
|
|
13849
13907
|
return null;
|
|
13850
13908
|
}
|
|
@@ -13866,13 +13924,13 @@ function cursorRipgrepEnv(opts) {
|
|
|
13866
13924
|
const path2 = resolveCursorRipgrepPath(opts);
|
|
13867
13925
|
return path2 ? { [RIPGREP_ENV]: path2 } : {};
|
|
13868
13926
|
}
|
|
13869
|
-
var
|
|
13927
|
+
var import_node_fs35, import_node_module2, import_node_path37, RIPGREP_ENV;
|
|
13870
13928
|
var init_cursor_ripgrep = __esm({
|
|
13871
13929
|
"src/agents/cursor-ripgrep.ts"() {
|
|
13872
13930
|
"use strict";
|
|
13873
|
-
|
|
13931
|
+
import_node_fs35 = require("fs");
|
|
13874
13932
|
import_node_module2 = require("module");
|
|
13875
|
-
|
|
13933
|
+
import_node_path37 = require("path");
|
|
13876
13934
|
init_node_launch();
|
|
13877
13935
|
init_packaged_runtime();
|
|
13878
13936
|
RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
@@ -13921,11 +13979,11 @@ function entryDir() {
|
|
|
13921
13979
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
13922
13980
|
if (cjsDir) return cjsDir;
|
|
13923
13981
|
try {
|
|
13924
|
-
return (0,
|
|
13982
|
+
return (0, import_node_path38.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
13925
13983
|
} catch {
|
|
13926
13984
|
try {
|
|
13927
13985
|
const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
|
|
13928
|
-
return (0,
|
|
13986
|
+
return (0, import_node_path38.dirname)(req.resolve("@sideboard-ai/core"));
|
|
13929
13987
|
} catch {
|
|
13930
13988
|
return process.cwd();
|
|
13931
13989
|
}
|
|
@@ -13936,27 +13994,27 @@ function cursorRunnerPath() {
|
|
|
13936
13994
|
if (packaged) return packaged;
|
|
13937
13995
|
const root = entryDir();
|
|
13938
13996
|
const candidates = [
|
|
13939
|
-
(0,
|
|
13940
|
-
(0,
|
|
13997
|
+
(0, import_node_path38.join)(root, "agents", "cursor-runner.js"),
|
|
13998
|
+
(0, import_node_path38.join)(root, "agents", "cursor-runner.cjs"),
|
|
13941
13999
|
// If somehow resolved from package root instead of dist/
|
|
13942
|
-
(0,
|
|
13943
|
-
(0,
|
|
14000
|
+
(0, import_node_path38.join)(root, "dist", "agents", "cursor-runner.js"),
|
|
14001
|
+
(0, import_node_path38.join)(root, "dist", "agents", "cursor-runner.cjs"),
|
|
13944
14002
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
13945
|
-
(0,
|
|
13946
|
-
(0,
|
|
14003
|
+
(0, import_node_path38.join)(root, "cursor-runner.ts"),
|
|
14004
|
+
(0, import_node_path38.join)(root, "src", "agents", "cursor-runner.ts")
|
|
13947
14005
|
];
|
|
13948
14006
|
for (const candidate of candidates) {
|
|
13949
|
-
if ((0,
|
|
14007
|
+
if ((0, import_node_fs36.existsSync)(candidate)) return candidate;
|
|
13950
14008
|
}
|
|
13951
14009
|
return candidates[0];
|
|
13952
14010
|
}
|
|
13953
|
-
var
|
|
14011
|
+
var import_node_fs36, import_node_module3, import_node_path38, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
|
|
13954
14012
|
var init_cursor = __esm({
|
|
13955
14013
|
"src/agents/cursor.ts"() {
|
|
13956
14014
|
"use strict";
|
|
13957
|
-
|
|
14015
|
+
import_node_fs36 = require("fs");
|
|
13958
14016
|
import_node_module3 = require("module");
|
|
13959
|
-
|
|
14017
|
+
import_node_path38 = require("path");
|
|
13960
14018
|
import_node_url2 = require("url");
|
|
13961
14019
|
import_sdk = require("@cursor/sdk");
|
|
13962
14020
|
init_run();
|
|
@@ -14108,7 +14166,7 @@ async function listOpencodeModels() {
|
|
|
14108
14166
|
if (opencode === "opencode") {
|
|
14109
14167
|
const which = await run("which", ["opencode"], { reject: false });
|
|
14110
14168
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
14111
|
-
} else if (!(0,
|
|
14169
|
+
} else if (!(0, import_node_fs37.existsSync)(opencode)) {
|
|
14112
14170
|
return FALLBACK_OPENCODE_MODELS;
|
|
14113
14171
|
}
|
|
14114
14172
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -14138,11 +14196,11 @@ function usageFromOpencode(tokens) {
|
|
|
14138
14196
|
cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
|
|
14139
14197
|
};
|
|
14140
14198
|
}
|
|
14141
|
-
var
|
|
14199
|
+
var import_node_fs37, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
|
|
14142
14200
|
var init_opencode = __esm({
|
|
14143
14201
|
"src/agents/opencode.ts"() {
|
|
14144
14202
|
"use strict";
|
|
14145
|
-
|
|
14203
|
+
import_node_fs37 = require("fs");
|
|
14146
14204
|
init_run();
|
|
14147
14205
|
init_app_settings();
|
|
14148
14206
|
init_global_workspace();
|
|
@@ -14170,7 +14228,7 @@ var init_opencode = __esm({
|
|
|
14170
14228
|
async detect() {
|
|
14171
14229
|
const opencode = resolveAgentExecutable("opencode");
|
|
14172
14230
|
if (opencode !== "opencode") {
|
|
14173
|
-
if (!(0,
|
|
14231
|
+
if (!(0, import_node_fs37.existsSync)(opencode)) {
|
|
14174
14232
|
return {
|
|
14175
14233
|
agent: "opencode",
|
|
14176
14234
|
installed: false,
|
|
@@ -14889,14 +14947,14 @@ function accessTokenFromCredentialsJson(raw) {
|
|
|
14889
14947
|
}
|
|
14890
14948
|
}
|
|
14891
14949
|
function claudeCredentialsPath() {
|
|
14892
|
-
const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0,
|
|
14893
|
-
return (0,
|
|
14950
|
+
const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path39.join)((0, import_node_os13.homedir)(), ".claude");
|
|
14951
|
+
return (0, import_node_path39.join)(root, ".credentials.json");
|
|
14894
14952
|
}
|
|
14895
14953
|
async function readFileAccessToken() {
|
|
14896
14954
|
const path2 = claudeCredentialsPath();
|
|
14897
|
-
if (!(0,
|
|
14955
|
+
if (!(0, import_node_fs38.existsSync)(path2)) return null;
|
|
14898
14956
|
try {
|
|
14899
|
-
return accessTokenFromCredentialsJson((0,
|
|
14957
|
+
return accessTokenFromCredentialsJson((0, import_node_fs38.readFileSync)(path2, "utf8"));
|
|
14900
14958
|
} catch {
|
|
14901
14959
|
return null;
|
|
14902
14960
|
}
|
|
@@ -15000,13 +15058,13 @@ async function getClaudePlanUsage(opts = {}) {
|
|
|
15000
15058
|
})();
|
|
15001
15059
|
return inflight;
|
|
15002
15060
|
}
|
|
15003
|
-
var
|
|
15061
|
+
var import_node_fs38, import_node_os13, import_node_path39, CLAUDE_OAUTH_USAGE_URL, CLAUDE_USAGE_TTL_MS, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS, KEYCHAIN_SERVICES, cache, errorUntil, inflight, lastGood, claudeVersion;
|
|
15004
15062
|
var init_claude_usage_client = __esm({
|
|
15005
15063
|
"src/agents/claude-usage-client.ts"() {
|
|
15006
15064
|
"use strict";
|
|
15007
|
-
|
|
15065
|
+
import_node_fs38 = require("fs");
|
|
15008
15066
|
import_node_os13 = require("os");
|
|
15009
|
-
|
|
15067
|
+
import_node_path39 = require("path");
|
|
15010
15068
|
init_run();
|
|
15011
15069
|
init_fetch();
|
|
15012
15070
|
init_app_settings();
|
|
@@ -15367,17 +15425,79 @@ var init_agents = __esm({
|
|
|
15367
15425
|
}
|
|
15368
15426
|
});
|
|
15369
15427
|
|
|
15428
|
+
// src/hook/agent-host-env.ts
|
|
15429
|
+
function isAgentHostEnvKey(key) {
|
|
15430
|
+
if (DROP_EXACT.has(key)) return true;
|
|
15431
|
+
return DROP_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
15432
|
+
}
|
|
15433
|
+
function stripHostToolingPath(pathValue) {
|
|
15434
|
+
if (!pathValue?.trim()) return "";
|
|
15435
|
+
return pathValue.split(import_node_path40.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path40.delimiter);
|
|
15436
|
+
}
|
|
15437
|
+
function sanitizeAgentHostEnv(env, cwd) {
|
|
15438
|
+
for (const key of Object.keys(env)) {
|
|
15439
|
+
if (isAgentHostEnvKey(key)) delete env[key];
|
|
15440
|
+
}
|
|
15441
|
+
env.PATH = stripHostToolingPath(env.PATH);
|
|
15442
|
+
const worktree = cwd?.trim();
|
|
15443
|
+
if (worktree) {
|
|
15444
|
+
env.PWD = worktree;
|
|
15445
|
+
env.INIT_CWD = worktree;
|
|
15446
|
+
}
|
|
15447
|
+
return env;
|
|
15448
|
+
}
|
|
15449
|
+
var import_node_path40, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
|
|
15450
|
+
var init_agent_host_env = __esm({
|
|
15451
|
+
"src/hook/agent-host-env.ts"() {
|
|
15452
|
+
"use strict";
|
|
15453
|
+
import_node_path40 = require("path");
|
|
15454
|
+
DROP_EXACT = /* @__PURE__ */ new Set([
|
|
15455
|
+
"NODE_PATH",
|
|
15456
|
+
"NODE_ENV_ELECTRON_VITE",
|
|
15457
|
+
"INIT_CWD",
|
|
15458
|
+
"npm_command",
|
|
15459
|
+
"npm_execpath",
|
|
15460
|
+
"npm_node_execpath",
|
|
15461
|
+
"npm_lifecycle_event",
|
|
15462
|
+
"npm_lifecycle_script",
|
|
15463
|
+
"PNPM_SCRIPT_SRC_DIR",
|
|
15464
|
+
"PNPM_STORE_DIR",
|
|
15465
|
+
"PORT",
|
|
15466
|
+
"SIDEBOARD_ROOT_PATH",
|
|
15467
|
+
"SIDEBOARD_IS_LOCAL",
|
|
15468
|
+
"SIDEBOARD_WORKSPACE_PATH",
|
|
15469
|
+
"SIDEBOARD_WORKSPACE_NAME",
|
|
15470
|
+
"SIDEBOARD_PORT",
|
|
15471
|
+
"CONDUCTOR_ROOT_PATH",
|
|
15472
|
+
"CONDUCTOR_IS_LOCAL",
|
|
15473
|
+
"CONDUCTOR_WORKSPACE_PATH",
|
|
15474
|
+
"CONDUCTOR_WORKSPACE_NAME",
|
|
15475
|
+
"CONDUCTOR_PORT",
|
|
15476
|
+
"CONDUCTOR_DEFAULT_BRANCH",
|
|
15477
|
+
"SIDEBOARD_DEFAULT_BRANCH"
|
|
15478
|
+
]);
|
|
15479
|
+
DROP_PREFIXES = [
|
|
15480
|
+
"npm_package_",
|
|
15481
|
+
"npm_config_",
|
|
15482
|
+
"PNPM_",
|
|
15483
|
+
"SIDEBOARD_PORT_",
|
|
15484
|
+
"CONDUCTOR_PORT_"
|
|
15485
|
+
];
|
|
15486
|
+
HOST_PATH_NOISE = /(?:^|\/)node_modules\/\.bin(?:\/|$)|node-gyp-bin|electron-vite/i;
|
|
15487
|
+
}
|
|
15488
|
+
});
|
|
15489
|
+
|
|
15370
15490
|
// src/hook/worktree-pkg-cache.ts
|
|
15371
15491
|
function worktreePkgCacheRoot(worktreePath) {
|
|
15372
|
-
return (0,
|
|
15492
|
+
return (0, import_node_path41.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
|
|
15373
15493
|
}
|
|
15374
15494
|
function worktreePkgCacheEnv(worktreePath) {
|
|
15375
15495
|
const root = worktreePkgCacheRoot(worktreePath);
|
|
15376
|
-
const store = (0,
|
|
15377
|
-
const pnpmCache = (0,
|
|
15378
|
-
const npmCache = (0,
|
|
15379
|
-
const nodeGyp = (0,
|
|
15380
|
-
const electron = (0,
|
|
15496
|
+
const store = (0, import_node_path41.join)(root, "pnpm-store");
|
|
15497
|
+
const pnpmCache = (0, import_node_path41.join)(root, "pnpm");
|
|
15498
|
+
const npmCache = (0, import_node_path41.join)(root, "npm");
|
|
15499
|
+
const nodeGyp = (0, import_node_path41.join)(root, "node-gyp");
|
|
15500
|
+
const electron = (0, import_node_path41.join)(root, "electron");
|
|
15381
15501
|
return {
|
|
15382
15502
|
npm_config_store_dir: store,
|
|
15383
15503
|
PNPM_STORE_DIR: store,
|
|
@@ -15399,8 +15519,8 @@ function fillGroup(env, keys, values) {
|
|
|
15399
15519
|
}
|
|
15400
15520
|
}
|
|
15401
15521
|
function ensureWorktreePkgCacheDirs(worktreePath) {
|
|
15402
|
-
if (!(0,
|
|
15403
|
-
(0,
|
|
15522
|
+
if (!(0, import_node_fs39.existsSync)(worktreePath)) return;
|
|
15523
|
+
(0, import_node_fs39.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
|
|
15404
15524
|
}
|
|
15405
15525
|
function applyWorktreePkgCacheEnv(env, worktreePath) {
|
|
15406
15526
|
const cwd = worktreePath.trim();
|
|
@@ -15413,12 +15533,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
|
|
|
15413
15533
|
fillGroup(env, ["electron_config_cache"], next);
|
|
15414
15534
|
ensureWorktreePkgCacheDirs(cwd);
|
|
15415
15535
|
}
|
|
15416
|
-
var
|
|
15536
|
+
var import_node_fs39, import_node_path41, WORKTREE_PKG_CACHE_REL;
|
|
15417
15537
|
var init_worktree_pkg_cache = __esm({
|
|
15418
15538
|
"src/hook/worktree-pkg-cache.ts"() {
|
|
15419
15539
|
"use strict";
|
|
15420
|
-
|
|
15421
|
-
|
|
15540
|
+
import_node_fs39 = require("fs");
|
|
15541
|
+
import_node_path41 = require("path");
|
|
15422
15542
|
WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
|
|
15423
15543
|
}
|
|
15424
15544
|
});
|
|
@@ -15516,26 +15636,54 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
15516
15636
|
assertOrchestratorCapableAgent(thread.agent);
|
|
15517
15637
|
}
|
|
15518
15638
|
const adapter = getAdapter(thread.agent);
|
|
15519
|
-
const
|
|
15639
|
+
const orch = isOrchestratorThread(thread);
|
|
15640
|
+
traceTurn("spawn.buildTurn.start", {
|
|
15641
|
+
threadId: thread.id,
|
|
15642
|
+
agent: thread.agent,
|
|
15643
|
+
orch,
|
|
15644
|
+
cwd: thread.worktreePath
|
|
15645
|
+
});
|
|
15646
|
+
const cmd = await withTimeout(
|
|
15647
|
+
adapter.buildTurn(thread, input),
|
|
15648
|
+
2e4,
|
|
15649
|
+
"buildTurn"
|
|
15650
|
+
);
|
|
15651
|
+
traceTurn("spawn.buildTurn.done", { file: cmd.file, cwd: cmd.cwd });
|
|
15520
15652
|
if (cmd.cwd !== thread.worktreePath) {
|
|
15521
15653
|
throw new Error(
|
|
15522
15654
|
`Agent cwd must be the thread worktree (got ${cmd.cwd}, expected ${thread.worktreePath})`
|
|
15523
15655
|
);
|
|
15524
15656
|
}
|
|
15525
15657
|
const env = childEnvWithAppSettings(cmd.env);
|
|
15658
|
+
sanitizeAgentHostEnv(env, cmd.cwd);
|
|
15659
|
+
ensureAgentPath(env);
|
|
15526
15660
|
applyPromptCacheTtlEnv(thread.agent, env);
|
|
15527
15661
|
applyAgentRunnerHeapEnv(env);
|
|
15528
|
-
if (!
|
|
15662
|
+
if (!orch) {
|
|
15529
15663
|
applyWorktreePkgCacheEnv(env, thread.worktreePath);
|
|
15530
15664
|
}
|
|
15531
15665
|
try {
|
|
15532
|
-
|
|
15533
|
-
|
|
15534
|
-
|
|
15535
|
-
|
|
15666
|
+
traceTurn("spawn.gitAuth.start");
|
|
15667
|
+
mergeAgentGitAuthEnv(
|
|
15668
|
+
env,
|
|
15669
|
+
await withTimeout(
|
|
15670
|
+
resolveAgentGitAuthEnv(env, { cwd: thread.worktreePath }),
|
|
15671
|
+
8e3,
|
|
15672
|
+
"gitAuth"
|
|
15673
|
+
)
|
|
15674
|
+
);
|
|
15675
|
+
if (!orch) {
|
|
15676
|
+
const slug = await withTimeout(
|
|
15677
|
+
resolveGithubRepoSlug(thread.worktreePath),
|
|
15678
|
+
8e3,
|
|
15679
|
+
"resolveGithubRepoSlug"
|
|
15680
|
+
);
|
|
15681
|
+
if (slug) env.GH_REPO = slug;
|
|
15536
15682
|
}
|
|
15683
|
+
traceTurn("spawn.gitAuth.done", { ghRepo: env.GH_REPO ?? null });
|
|
15537
15684
|
} catch (err) {
|
|
15538
15685
|
const detail = err instanceof Error ? err.message : String(err);
|
|
15686
|
+
traceTurn("spawn.gitAuth.fail", { detail });
|
|
15539
15687
|
console.warn(`[sideboard] git auth env failed (${thread.worktreePath}): ${detail}`);
|
|
15540
15688
|
}
|
|
15541
15689
|
const child = (0, import_execa3.execa)(cmd.file, cmd.args, {
|
|
@@ -15548,6 +15696,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
15548
15696
|
// so Claude doesn't wait ~3s for an empty pipe.
|
|
15549
15697
|
stdin: cmd.stdin != null ? "pipe" : "ignore"
|
|
15550
15698
|
});
|
|
15699
|
+
traceTurn("spawn.execa", { pid: child.pid ?? null, file: cmd.file });
|
|
15551
15700
|
if (cmd.stdin != null && child.stdin) {
|
|
15552
15701
|
child.stdin.write(cmd.stdin);
|
|
15553
15702
|
child.stdin.end();
|
|
@@ -15631,10 +15780,12 @@ var init_spawn = __esm({
|
|
|
15631
15780
|
init_git_auth_mode();
|
|
15632
15781
|
init_app_settings();
|
|
15633
15782
|
init_global_workspace();
|
|
15783
|
+
init_turn_trace();
|
|
15634
15784
|
init_brightsy();
|
|
15635
15785
|
init_agents();
|
|
15636
15786
|
init_orchestrator_capable();
|
|
15637
15787
|
init_message_parts();
|
|
15788
|
+
init_agent_host_env();
|
|
15638
15789
|
init_worktree_pkg_cache();
|
|
15639
15790
|
init_node_launch();
|
|
15640
15791
|
init_path();
|
|
@@ -16622,21 +16773,21 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
16622
16773
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
16623
16774
|
}
|
|
16624
16775
|
function readTextIfPresent(abs) {
|
|
16625
|
-
if (!(0,
|
|
16776
|
+
if (!(0, import_node_fs40.existsSync)(abs)) return null;
|
|
16626
16777
|
try {
|
|
16627
|
-
const content = (0,
|
|
16778
|
+
const content = (0, import_node_fs40.readFileSync)(abs, "utf8");
|
|
16628
16779
|
return content.trim() ? content : null;
|
|
16629
16780
|
} catch {
|
|
16630
16781
|
return null;
|
|
16631
16782
|
}
|
|
16632
16783
|
}
|
|
16633
16784
|
function readLocalGuidelines(worktreePath) {
|
|
16634
|
-
const localAbs = (0,
|
|
16785
|
+
const localAbs = (0, import_node_path42.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
16635
16786
|
const localContent = readTextIfPresent(localAbs);
|
|
16636
16787
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
16637
16788
|
return { path: REVIEW_REQUEST_PATH, content: localContent };
|
|
16638
16789
|
}
|
|
16639
|
-
const legacyAbs = (0,
|
|
16790
|
+
const legacyAbs = (0, import_node_path42.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
16640
16791
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
16641
16792
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
16642
16793
|
return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
|
|
@@ -16660,27 +16811,27 @@ function contextGuidelines(content, source) {
|
|
|
16660
16811
|
};
|
|
16661
16812
|
}
|
|
16662
16813
|
function writeContextGuidelines(worktreePath, content) {
|
|
16663
|
-
const abs = (0,
|
|
16664
|
-
(0,
|
|
16814
|
+
const abs = (0, import_node_path42.join)(worktreePath, CONTEXT_REVIEW_PATH);
|
|
16815
|
+
(0, import_node_fs40.mkdirSync)((0, import_node_path42.dirname)(abs), { recursive: true });
|
|
16665
16816
|
const body = content.endsWith("\n") ? content : `${content}
|
|
16666
16817
|
`;
|
|
16667
|
-
(0,
|
|
16818
|
+
(0, import_node_fs40.writeFileSync)(abs, body, "utf8");
|
|
16668
16819
|
return body;
|
|
16669
16820
|
}
|
|
16670
16821
|
function readSideboardReview(worktreePath, repoPath) {
|
|
16671
|
-
const fromWorktree = readTextIfPresent((0,
|
|
16822
|
+
const fromWorktree = readTextIfPresent((0, import_node_path42.join)(worktreePath, REPO_REVIEW_PATH));
|
|
16672
16823
|
if (fromWorktree) return fromWorktree;
|
|
16673
16824
|
const repo = repoPath?.replace(/\/+$/, "");
|
|
16674
16825
|
const wt = worktreePath.replace(/\/+$/, "");
|
|
16675
16826
|
if (!repo || repo === wt) return null;
|
|
16676
|
-
return readTextIfPresent((0,
|
|
16827
|
+
return readTextIfPresent((0, import_node_path42.join)(repo, REPO_REVIEW_PATH));
|
|
16677
16828
|
}
|
|
16678
16829
|
function ensureReviewGuidelinesFile(worktreePath, repoPath) {
|
|
16679
|
-
const skillContent = readTextIfPresent((0,
|
|
16830
|
+
const skillContent = readTextIfPresent((0, import_node_path42.join)(worktreePath, REVIEW_SKILL_PATH));
|
|
16680
16831
|
if (skillContent) {
|
|
16681
16832
|
return { ...skillGuidelines(skillContent, "skill"), wrote: false };
|
|
16682
16833
|
}
|
|
16683
|
-
const contextContent = readTextIfPresent((0,
|
|
16834
|
+
const contextContent = readTextIfPresent((0, import_node_path42.join)(worktreePath, CONTEXT_REVIEW_PATH));
|
|
16684
16835
|
if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
|
|
16685
16836
|
return { ...contextGuidelines(contextContent, "local"), wrote: false };
|
|
16686
16837
|
}
|
|
@@ -16718,7 +16869,7 @@ function buildReviewRequestAttachment(content, opts) {
|
|
|
16718
16869
|
};
|
|
16719
16870
|
}
|
|
16720
16871
|
function readExistingReviewRequestFile(worktreePath) {
|
|
16721
|
-
return readTextIfPresent((0,
|
|
16872
|
+
return readTextIfPresent((0, import_node_path42.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path42.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path42.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path42.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path42.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
16722
16873
|
}
|
|
16723
16874
|
async function requestReview(threadRef, send2) {
|
|
16724
16875
|
const from = findThreadByRef(threadRef);
|
|
@@ -16745,13 +16896,13 @@ async function requestReview(threadRef, send2) {
|
|
|
16745
16896
|
const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
|
|
16746
16897
|
return { tab: started, from };
|
|
16747
16898
|
}
|
|
16748
|
-
var import_node_crypto9,
|
|
16899
|
+
var import_node_crypto9, import_node_fs40, import_node_path42, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
|
|
16749
16900
|
var init_request_review = __esm({
|
|
16750
16901
|
"src/review/request-review.ts"() {
|
|
16751
16902
|
"use strict";
|
|
16752
16903
|
import_node_crypto9 = require("crypto");
|
|
16753
|
-
|
|
16754
|
-
|
|
16904
|
+
import_node_fs40 = require("fs");
|
|
16905
|
+
import_node_path42 = require("path");
|
|
16755
16906
|
init_global_workspace();
|
|
16756
16907
|
init_chat_tabs();
|
|
16757
16908
|
init_thread_store();
|
|
@@ -16777,9 +16928,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
16777
16928
|
return new RegExp(`^${escaped}$`).test(name);
|
|
16778
16929
|
}
|
|
16779
16930
|
function readWorktreeInclude(repoPath) {
|
|
16780
|
-
const path2 = (0,
|
|
16781
|
-
if (!(0,
|
|
16782
|
-
return (0,
|
|
16931
|
+
const path2 = (0, import_node_path43.join)(repoPath, ".worktreeinclude");
|
|
16932
|
+
if (!(0, import_node_fs41.existsSync)(path2)) return [];
|
|
16933
|
+
return (0, import_node_fs41.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
16783
16934
|
}
|
|
16784
16935
|
function resolveFilesToCopy(repoPath) {
|
|
16785
16936
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -16789,10 +16940,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
16789
16940
|
if (settings?.fileIncludeGlobs?.length) {
|
|
16790
16941
|
const matched = [];
|
|
16791
16942
|
try {
|
|
16792
|
-
for (const entry of (0,
|
|
16943
|
+
for (const entry of (0, import_node_fs41.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
16793
16944
|
if (!entry.isFile()) continue;
|
|
16794
16945
|
for (const glob of settings.fileIncludeGlobs) {
|
|
16795
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
16946
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path43.basename)(glob), entry.name)) {
|
|
16796
16947
|
matched.push(entry.name);
|
|
16797
16948
|
break;
|
|
16798
16949
|
}
|
|
@@ -16804,7 +16955,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
16804
16955
|
}
|
|
16805
16956
|
const defaults = [];
|
|
16806
16957
|
try {
|
|
16807
|
-
for (const entry of (0,
|
|
16958
|
+
for (const entry of (0, import_node_fs41.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
16808
16959
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
16809
16960
|
defaults.push(entry.name);
|
|
16810
16961
|
}
|
|
@@ -16818,11 +16969,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
16818
16969
|
const patterns = resolveFilesToCopy(repoPath);
|
|
16819
16970
|
const copied = [];
|
|
16820
16971
|
for (const rel of patterns) {
|
|
16821
|
-
const src = (0,
|
|
16822
|
-
if (!(0,
|
|
16823
|
-
const dest = (0,
|
|
16824
|
-
(0,
|
|
16825
|
-
(0,
|
|
16972
|
+
const src = (0, import_node_path43.join)(repoPath, rel);
|
|
16973
|
+
if (!(0, import_node_fs41.existsSync)(src)) continue;
|
|
16974
|
+
const dest = (0, import_node_path43.join)(worktreePath, rel);
|
|
16975
|
+
(0, import_node_fs41.mkdirSync)((0, import_node_path43.dirname)(dest), { recursive: true });
|
|
16976
|
+
(0, import_node_fs41.copyFileSync)(src, dest);
|
|
16826
16977
|
copied.push(rel);
|
|
16827
16978
|
}
|
|
16828
16979
|
return copied;
|
|
@@ -16857,7 +17008,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
16857
17008
|
const env = stripNestedElectronEnv({
|
|
16858
17009
|
...baseEnv ?? process.env
|
|
16859
17010
|
});
|
|
16860
|
-
const name = opts.workspaceName ?? (0,
|
|
17011
|
+
const name = opts.workspaceName ?? (0, import_node_path43.basename)(opts.worktreePath);
|
|
16861
17012
|
const ports = opts.ports ?? [];
|
|
16862
17013
|
const primary = ports[0];
|
|
16863
17014
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -17120,13 +17271,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
17120
17271
|
done: handle.done
|
|
17121
17272
|
};
|
|
17122
17273
|
}
|
|
17123
|
-
var
|
|
17274
|
+
var import_node_fs41, import_node_net, import_node_path43, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
17124
17275
|
var init_conductor = __esm({
|
|
17125
17276
|
"src/hook/conductor.ts"() {
|
|
17126
17277
|
"use strict";
|
|
17127
|
-
|
|
17278
|
+
import_node_fs41 = require("fs");
|
|
17128
17279
|
import_node_net = require("net");
|
|
17129
|
-
|
|
17280
|
+
import_node_path43 = require("path");
|
|
17130
17281
|
import_execa4 = require("execa");
|
|
17131
17282
|
import_node_readline3 = require("readline");
|
|
17132
17283
|
init_settings();
|
|
@@ -17154,9 +17305,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
17154
17305
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
17155
17306
|
);
|
|
17156
17307
|
const homeRoot = sideboardWorkspacesDir();
|
|
17157
|
-
if ((0,
|
|
17308
|
+
if ((0, import_node_fs42.existsSync)(homeRoot)) {
|
|
17158
17309
|
try {
|
|
17159
|
-
for (const entry of (0,
|
|
17310
|
+
for (const entry of (0, import_node_fs42.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
17160
17311
|
if (!entry.isDirectory()) continue;
|
|
17161
17312
|
void entry;
|
|
17162
17313
|
}
|
|
@@ -17166,7 +17317,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
17166
17317
|
const orphans = [];
|
|
17167
17318
|
const seen = /* @__PURE__ */ new Set();
|
|
17168
17319
|
for (const repoPath of repos) {
|
|
17169
|
-
if (!repoPath || !(0,
|
|
17320
|
+
if (!repoPath || !(0, import_node_fs42.existsSync)(repoPath)) continue;
|
|
17170
17321
|
try {
|
|
17171
17322
|
const wts = await listWorktrees(repoPath);
|
|
17172
17323
|
for (const wt of wts) {
|
|
@@ -17177,7 +17328,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
17177
17328
|
seen.add(path2);
|
|
17178
17329
|
let mtimeMs = 0;
|
|
17179
17330
|
try {
|
|
17180
|
-
mtimeMs = (0,
|
|
17331
|
+
mtimeMs = (0, import_node_fs42.statSync)(path2).mtimeMs;
|
|
17181
17332
|
} catch {
|
|
17182
17333
|
mtimeMs = 0;
|
|
17183
17334
|
}
|
|
@@ -17187,16 +17338,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
17187
17338
|
}
|
|
17188
17339
|
try {
|
|
17189
17340
|
const root = worktreesRoot(repoPath);
|
|
17190
|
-
if ((0,
|
|
17191
|
-
for (const entry of (0,
|
|
17341
|
+
if ((0, import_node_fs42.existsSync)(root)) {
|
|
17342
|
+
for (const entry of (0, import_node_fs42.readdirSync)(root, { withFileTypes: true })) {
|
|
17192
17343
|
if (!entry.isDirectory()) continue;
|
|
17193
|
-
const path2 = (0,
|
|
17344
|
+
const path2 = (0, import_node_path44.join)(root, entry.name).replace(/\/$/, "");
|
|
17194
17345
|
if (known.has(path2) || seen.has(path2)) continue;
|
|
17195
|
-
if (!(0,
|
|
17346
|
+
if (!(0, import_node_fs42.existsSync)((0, import_node_path44.join)(path2, ".git"))) continue;
|
|
17196
17347
|
seen.add(path2);
|
|
17197
17348
|
let mtimeMs = 0;
|
|
17198
17349
|
try {
|
|
17199
|
-
mtimeMs = (0,
|
|
17350
|
+
mtimeMs = (0, import_node_fs42.statSync)(path2).mtimeMs;
|
|
17200
17351
|
} catch {
|
|
17201
17352
|
mtimeMs = Date.now();
|
|
17202
17353
|
}
|
|
@@ -17257,12 +17408,12 @@ function worktreeCleanupSettings() {
|
|
|
17257
17408
|
autoCleanupOrphans: a.autoCleanupOrphans
|
|
17258
17409
|
};
|
|
17259
17410
|
}
|
|
17260
|
-
var
|
|
17411
|
+
var import_node_fs42, import_node_path44;
|
|
17261
17412
|
var init_orphan_cleanup = __esm({
|
|
17262
17413
|
"src/git/orphan-cleanup.ts"() {
|
|
17263
17414
|
"use strict";
|
|
17264
|
-
|
|
17265
|
-
|
|
17415
|
+
import_node_fs42 = require("fs");
|
|
17416
|
+
import_node_path44 = require("path");
|
|
17266
17417
|
init_worktree();
|
|
17267
17418
|
init_thread_store();
|
|
17268
17419
|
init_paths();
|
|
@@ -17437,12 +17588,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
17437
17588
|
if (!url) throw new Error("Clone URL is required");
|
|
17438
17589
|
let name = opts.name?.trim();
|
|
17439
17590
|
if (!name) {
|
|
17440
|
-
const leaf = (0,
|
|
17591
|
+
const leaf = (0, import_node_path45.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
17441
17592
|
name = leaf || "repo";
|
|
17442
17593
|
}
|
|
17443
17594
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
17444
|
-
const dest = (0,
|
|
17445
|
-
if ((0,
|
|
17595
|
+
const dest = (0, import_node_path45.join)(sideboardReposDir(), name);
|
|
17596
|
+
if ((0, import_node_fs43.existsSync)(dest)) {
|
|
17446
17597
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
17447
17598
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
17448
17599
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -17457,12 +17608,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
17457
17608
|
const workspace = await ensureWorkspace(repoPath);
|
|
17458
17609
|
return { repoPath, workspace };
|
|
17459
17610
|
}
|
|
17460
|
-
var
|
|
17611
|
+
var import_node_fs43, import_node_path45, import_execa6;
|
|
17461
17612
|
var init_clone_repo = __esm({
|
|
17462
17613
|
"src/git/clone-repo.ts"() {
|
|
17463
17614
|
"use strict";
|
|
17464
|
-
|
|
17465
|
-
|
|
17615
|
+
import_node_fs43 = require("fs");
|
|
17616
|
+
import_node_path45 = require("path");
|
|
17466
17617
|
import_execa6 = require("execa");
|
|
17467
17618
|
init_paths();
|
|
17468
17619
|
init_workspaces();
|
|
@@ -17583,24 +17734,24 @@ function jobTreeAlive(pid) {
|
|
|
17583
17734
|
return jobAlive(pid) || processGroupAlive(pid);
|
|
17584
17735
|
}
|
|
17585
17736
|
function readIntFile(file) {
|
|
17586
|
-
if (!(0,
|
|
17587
|
-
const n = Number.parseInt((0,
|
|
17737
|
+
if (!(0, import_node_fs44.existsSync)(file)) return null;
|
|
17738
|
+
const n = Number.parseInt((0, import_node_fs44.readFileSync)(file, "utf8").trim(), 10);
|
|
17588
17739
|
return Number.isInteger(n) ? n : null;
|
|
17589
17740
|
}
|
|
17590
17741
|
function jobDir(root, id, legacy = false) {
|
|
17591
|
-
return (0,
|
|
17742
|
+
return (0, import_node_path46.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
|
|
17592
17743
|
}
|
|
17593
17744
|
function resolveJobDir(root, id) {
|
|
17594
17745
|
const modern = jobDir(root, id, false);
|
|
17595
|
-
if ((0,
|
|
17746
|
+
if ((0, import_node_fs44.existsSync)(modern)) return modern;
|
|
17596
17747
|
const legacy = jobDir(root, id, true);
|
|
17597
|
-
if ((0,
|
|
17748
|
+
if ((0, import_node_fs44.existsSync)(legacy)) return legacy;
|
|
17598
17749
|
return modern;
|
|
17599
17750
|
}
|
|
17600
17751
|
function listJobIdsIn(root, rel) {
|
|
17601
|
-
const dir = (0,
|
|
17602
|
-
if (!(0,
|
|
17603
|
-
return (0,
|
|
17752
|
+
const dir = (0, import_node_path46.join)(root, rel);
|
|
17753
|
+
if (!(0, import_node_fs44.existsSync)(dir)) return [];
|
|
17754
|
+
return (0, import_node_fs44.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
|
|
17604
17755
|
}
|
|
17605
17756
|
function listRunningDetachedJobs(worktreePath) {
|
|
17606
17757
|
const root = worktreePath.trim();
|
|
@@ -17612,7 +17763,7 @@ function listRunningDetachedJobs(worktreePath) {
|
|
|
17612
17763
|
const running = [];
|
|
17613
17764
|
for (const id of ids) {
|
|
17614
17765
|
const dir = resolveJobDir(root, id);
|
|
17615
|
-
const pid = readIntFile((0,
|
|
17766
|
+
const pid = readIntFile((0, import_node_path46.join)(dir, "pid"));
|
|
17616
17767
|
if (jobTreeAlive(pid)) running.push(id);
|
|
17617
17768
|
}
|
|
17618
17769
|
return running.sort();
|
|
@@ -17625,6 +17776,7 @@ function looksLikeDeferredDonePromise(text7) {
|
|
|
17625
17776
|
return /\b(i['’]?ll|i will)\s+let you know\b/i.test(unquoted) || /\blet you know when\b/i.test(unquoted) || /\b(check back|ping me)\s+when\b/i.test(unquoted) || /\bi(?:['’]ll| will)\s+(report|update you)\s+when\b/i.test(unquoted);
|
|
17626
17777
|
}
|
|
17627
17778
|
function isJobContinuePrompt(text7) {
|
|
17779
|
+
if (typeof text7 !== "string") return false;
|
|
17628
17780
|
const t = text7.trim();
|
|
17629
17781
|
return t.startsWith("Detached job still running:") || t.startsWith("You ended the turn after promising to report later");
|
|
17630
17782
|
}
|
|
@@ -17694,8 +17846,8 @@ function planJobContinue(opts) {
|
|
|
17694
17846
|
return { action: "none" };
|
|
17695
17847
|
}
|
|
17696
17848
|
function tailProgress(logFile, maxLines = 12) {
|
|
17697
|
-
if (!(0,
|
|
17698
|
-
const lines = (0,
|
|
17849
|
+
if (!(0, import_node_fs44.existsSync)(logFile)) return "(no log yet)";
|
|
17850
|
+
const lines = (0, import_node_fs44.readFileSync)(logFile, "utf8").split("\n");
|
|
17699
17851
|
return lines.slice(-maxLines).join("\n");
|
|
17700
17852
|
}
|
|
17701
17853
|
function lastProgressLine(progress) {
|
|
@@ -17703,8 +17855,8 @@ function lastProgressLine(progress) {
|
|
|
17703
17855
|
return last ? last.slice(0, 72) : void 0;
|
|
17704
17856
|
}
|
|
17705
17857
|
function readLogLines(file) {
|
|
17706
|
-
if (!(0,
|
|
17707
|
-
const lines = (0,
|
|
17858
|
+
if (!(0, import_node_fs44.existsSync)(file)) return [];
|
|
17859
|
+
const lines = (0, import_node_fs44.readFileSync)(file, "utf8").split("\n");
|
|
17708
17860
|
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
17709
17861
|
return lines;
|
|
17710
17862
|
}
|
|
@@ -17715,15 +17867,15 @@ function takeDelta(logFile, cursorFile) {
|
|
|
17715
17867
|
return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
|
|
17716
17868
|
}
|
|
17717
17869
|
function snapshotJob(dir) {
|
|
17718
|
-
const pid = readIntFile((0,
|
|
17870
|
+
const pid = readIntFile((0, import_node_path46.join)(dir, "pid"));
|
|
17719
17871
|
const running = jobTreeAlive(pid);
|
|
17720
17872
|
return {
|
|
17721
17873
|
pid,
|
|
17722
17874
|
running,
|
|
17723
|
-
exitCode: readIntFile((0,
|
|
17724
|
-
log: (0,
|
|
17725
|
-
cursor: (0,
|
|
17726
|
-
progress: tailProgress((0,
|
|
17875
|
+
exitCode: readIntFile((0, import_node_path46.join)(dir, "exit")),
|
|
17876
|
+
log: (0, import_node_path46.join)(dir, "log"),
|
|
17877
|
+
cursor: (0, import_node_path46.join)(dir, "present.cursor"),
|
|
17878
|
+
progress: tailProgress((0, import_node_path46.join)(dir, "log"))
|
|
17727
17879
|
};
|
|
17728
17880
|
}
|
|
17729
17881
|
function toResult(id, snap, extra) {
|
|
@@ -17732,8 +17884,8 @@ function toResult(id, snap, extra) {
|
|
|
17732
17884
|
const stillRunning = snap.running && !ok;
|
|
17733
17885
|
const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
|
|
17734
17886
|
try {
|
|
17735
|
-
(0,
|
|
17736
|
-
(0,
|
|
17887
|
+
(0, import_node_fs44.mkdirSync)((0, import_node_path46.dirname)(snap.cursor), { recursive: true });
|
|
17888
|
+
(0, import_node_fs44.writeFileSync)(snap.cursor, `${nextCursor}
|
|
17737
17889
|
`);
|
|
17738
17890
|
} catch {
|
|
17739
17891
|
}
|
|
@@ -17762,7 +17914,7 @@ async function waitForDetachedJob(cwd, id, opts) {
|
|
|
17762
17914
|
const dir = resolveJobDir(root, jobId);
|
|
17763
17915
|
const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
|
|
17764
17916
|
const sleep2 = opts?.sleep ?? sleepMs;
|
|
17765
|
-
if (!(0,
|
|
17917
|
+
if (!(0, import_node_fs44.existsSync)(dir)) {
|
|
17766
17918
|
return {
|
|
17767
17919
|
stillRunning: false,
|
|
17768
17920
|
ok: false,
|
|
@@ -17808,10 +17960,10 @@ function killProcessTree(pid, signal) {
|
|
|
17808
17960
|
}
|
|
17809
17961
|
function appendJobLog(logFile, line) {
|
|
17810
17962
|
try {
|
|
17811
|
-
(0,
|
|
17963
|
+
(0, import_node_fs44.mkdirSync)((0, import_node_path46.dirname)(logFile), { recursive: true });
|
|
17812
17964
|
const body = line.endsWith("\n") ? line : `${line}
|
|
17813
17965
|
`;
|
|
17814
|
-
(0,
|
|
17966
|
+
(0, import_node_fs44.appendFileSync)(logFile, body);
|
|
17815
17967
|
} catch {
|
|
17816
17968
|
}
|
|
17817
17969
|
}
|
|
@@ -17821,7 +17973,7 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
17821
17973
|
const dir = resolveJobDir(root, jobId);
|
|
17822
17974
|
const sleep2 = opts?.sleep ?? sleepMs;
|
|
17823
17975
|
const why = opts?.reason?.trim() ?? "";
|
|
17824
|
-
if (!(0,
|
|
17976
|
+
if (!(0, import_node_fs44.existsSync)(dir)) {
|
|
17825
17977
|
return {
|
|
17826
17978
|
stillRunning: false,
|
|
17827
17979
|
ok: false,
|
|
@@ -17857,10 +18009,10 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
17857
18009
|
killProcessTree(targetPid, "SIGKILL");
|
|
17858
18010
|
await sleep2(100);
|
|
17859
18011
|
}
|
|
17860
|
-
const exitFile = (0,
|
|
17861
|
-
if (!(0,
|
|
18012
|
+
const exitFile = (0, import_node_path46.join)(dir, "exit");
|
|
18013
|
+
if (!(0, import_node_fs44.existsSync)(exitFile)) {
|
|
17862
18014
|
try {
|
|
17863
|
-
(0,
|
|
18015
|
+
(0, import_node_fs44.writeFileSync)(exitFile, "1\n");
|
|
17864
18016
|
} catch {
|
|
17865
18017
|
}
|
|
17866
18018
|
}
|
|
@@ -17880,12 +18032,12 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
17880
18032
|
hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
|
|
17881
18033
|
};
|
|
17882
18034
|
}
|
|
17883
|
-
var
|
|
18035
|
+
var import_node_fs44, import_node_path46, MAX_JOB_CONTINUES, MAX_JOB_DELTA_LINES, MAX_JOB_DELTA_CHARS, DEFERRED_DONE_MAX_CHARS, GH_WATCH_REFRESH, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
|
|
17884
18036
|
var init_wait_for_job = __esm({
|
|
17885
18037
|
"src/mcp/wait-for-job.ts"() {
|
|
17886
18038
|
"use strict";
|
|
17887
|
-
|
|
17888
|
-
|
|
18039
|
+
import_node_fs44 = require("fs");
|
|
18040
|
+
import_node_path46 = require("path");
|
|
17889
18041
|
init_workspace_scratch();
|
|
17890
18042
|
init_wait_for_turn();
|
|
17891
18043
|
MAX_JOB_CONTINUES = 8;
|
|
@@ -19430,7 +19582,7 @@ function reuseLiveThread(input, repoPath, match) {
|
|
|
19430
19582
|
}
|
|
19431
19583
|
async function createThread(input, _onSetupLine) {
|
|
19432
19584
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
19433
|
-
if (!(0,
|
|
19585
|
+
if (!(0, import_node_fs45.existsSync)(repoPath)) {
|
|
19434
19586
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
19435
19587
|
}
|
|
19436
19588
|
const reused = reuseLiveThread(input, repoPath, {
|
|
@@ -19615,11 +19767,11 @@ async function listLinearIssues(agent, repoPath) {
|
|
|
19615
19767
|
}
|
|
19616
19768
|
return adapter.listLinearIssues(repoPath);
|
|
19617
19769
|
}
|
|
19618
|
-
var
|
|
19770
|
+
var import_node_fs45;
|
|
19619
19771
|
var init_create = __esm({
|
|
19620
19772
|
"src/threads/create.ts"() {
|
|
19621
19773
|
"use strict";
|
|
19622
|
-
|
|
19774
|
+
import_node_fs45 = require("fs");
|
|
19623
19775
|
init_detect();
|
|
19624
19776
|
init_worktree();
|
|
19625
19777
|
init_home_board();
|
|
@@ -19771,20 +19923,20 @@ function writeTurnLive(threadId, progress) {
|
|
|
19771
19923
|
const path2 = threadLivePath(threadId);
|
|
19772
19924
|
const tmp = `${path2}.${process.pid}.tmp`;
|
|
19773
19925
|
try {
|
|
19774
|
-
(0,
|
|
19775
|
-
(0,
|
|
19926
|
+
(0, import_node_fs46.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
|
|
19927
|
+
(0, import_node_fs46.renameSync)(tmp, path2);
|
|
19776
19928
|
} catch {
|
|
19777
19929
|
try {
|
|
19778
|
-
(0,
|
|
19930
|
+
(0, import_node_fs46.unlinkSync)(tmp);
|
|
19779
19931
|
} catch {
|
|
19780
19932
|
}
|
|
19781
19933
|
}
|
|
19782
19934
|
}
|
|
19783
19935
|
function readTurnLive(threadId) {
|
|
19784
19936
|
const path2 = threadLivePath(threadId);
|
|
19785
|
-
if (!(0,
|
|
19937
|
+
if (!(0, import_node_fs46.existsSync)(path2)) return null;
|
|
19786
19938
|
try {
|
|
19787
|
-
const raw = JSON.parse((0,
|
|
19939
|
+
const raw = JSON.parse((0, import_node_fs46.readFileSync)(path2, "utf8"));
|
|
19788
19940
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
19789
19941
|
return raw;
|
|
19790
19942
|
} catch {
|
|
@@ -19796,17 +19948,17 @@ function clearTurnLive(threadId) {
|
|
|
19796
19948
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
19797
19949
|
buffers.delete(threadId);
|
|
19798
19950
|
const path2 = threadLivePath(threadId);
|
|
19799
|
-
if (!(0,
|
|
19951
|
+
if (!(0, import_node_fs46.existsSync)(path2)) return;
|
|
19800
19952
|
try {
|
|
19801
|
-
(0,
|
|
19953
|
+
(0, import_node_fs46.unlinkSync)(path2);
|
|
19802
19954
|
} catch {
|
|
19803
19955
|
}
|
|
19804
19956
|
}
|
|
19805
|
-
var
|
|
19957
|
+
var import_node_fs46, buffers, FLUSH_MS, MAX_PARTS;
|
|
19806
19958
|
var init_turn_live = __esm({
|
|
19807
19959
|
"src/store/turn-live.ts"() {
|
|
19808
19960
|
"use strict";
|
|
19809
|
-
|
|
19961
|
+
import_node_fs46 = require("fs");
|
|
19810
19962
|
init_message_parts();
|
|
19811
19963
|
init_paths();
|
|
19812
19964
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -20050,7 +20202,7 @@ var init_quota_failover = __esm({
|
|
|
20050
20202
|
// src/threads/adopt.ts
|
|
20051
20203
|
function thisModuleFile() {
|
|
20052
20204
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
20053
|
-
return cjsFile || process.argv[1] || (0,
|
|
20205
|
+
return cjsFile || process.argv[1] || (0, import_node_path47.join)(process.cwd(), "package.json");
|
|
20054
20206
|
}
|
|
20055
20207
|
function openReadonlySqlite(file) {
|
|
20056
20208
|
const req = (0, import_node_module4.createRequire)(thisModuleFile());
|
|
@@ -20068,21 +20220,21 @@ function mapAgentType(raw) {
|
|
|
20068
20220
|
return null;
|
|
20069
20221
|
}
|
|
20070
20222
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
20071
|
-
if (!workspacePath || !(0,
|
|
20223
|
+
if (!workspacePath || !(0, import_node_fs47.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
20072
20224
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
20073
20225
|
let best = null;
|
|
20074
20226
|
let hashes;
|
|
20075
20227
|
try {
|
|
20076
|
-
hashes = (0,
|
|
20228
|
+
hashes = (0, import_node_fs47.readdirSync)(CURSOR_SDK_STORE);
|
|
20077
20229
|
} catch {
|
|
20078
20230
|
return null;
|
|
20079
20231
|
}
|
|
20080
20232
|
for (const hash of hashes) {
|
|
20081
|
-
const agentsFile = (0,
|
|
20082
|
-
if (!(0,
|
|
20233
|
+
const agentsFile = (0, import_node_path47.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
20234
|
+
if (!(0, import_node_fs47.existsSync)(agentsFile)) continue;
|
|
20083
20235
|
let text7;
|
|
20084
20236
|
try {
|
|
20085
|
-
text7 = (0,
|
|
20237
|
+
text7 = (0, import_node_fs47.readFileSync)(agentsFile, "utf8");
|
|
20086
20238
|
} catch {
|
|
20087
20239
|
continue;
|
|
20088
20240
|
}
|
|
@@ -20106,7 +20258,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
20106
20258
|
return best?.agentId ?? null;
|
|
20107
20259
|
}
|
|
20108
20260
|
async function adoptThread(input) {
|
|
20109
|
-
if (!(0,
|
|
20261
|
+
if (!(0, import_node_fs47.existsSync)(input.worktreePath)) {
|
|
20110
20262
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
20111
20263
|
}
|
|
20112
20264
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -20135,18 +20287,18 @@ function conductorDbPath() {
|
|
|
20135
20287
|
return CONDUCTOR_DB;
|
|
20136
20288
|
}
|
|
20137
20289
|
function listConductorWorkspaces() {
|
|
20138
|
-
if (!(0,
|
|
20290
|
+
if (!(0, import_node_fs47.existsSync)(CONDUCTOR_DB)) {
|
|
20139
20291
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
20140
20292
|
}
|
|
20141
|
-
const tmp = (0,
|
|
20142
|
-
const snapshot = (0,
|
|
20293
|
+
const tmp = (0, import_node_fs47.mkdtempSync)((0, import_node_path47.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
|
|
20294
|
+
const snapshot = (0, import_node_path47.join)(tmp, "conductor.db");
|
|
20143
20295
|
try {
|
|
20144
|
-
(0,
|
|
20296
|
+
(0, import_node_fs47.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
20145
20297
|
for (const suffix of ["-wal", "-shm"]) {
|
|
20146
20298
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
20147
|
-
if ((0,
|
|
20299
|
+
if ((0, import_node_fs47.existsSync)(src)) {
|
|
20148
20300
|
try {
|
|
20149
|
-
(0,
|
|
20301
|
+
(0, import_node_fs47.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
20150
20302
|
} catch {
|
|
20151
20303
|
}
|
|
20152
20304
|
}
|
|
@@ -20222,22 +20374,22 @@ function listConductorWorkspaces() {
|
|
|
20222
20374
|
db.close();
|
|
20223
20375
|
}
|
|
20224
20376
|
} finally {
|
|
20225
|
-
(0,
|
|
20377
|
+
(0, import_node_fs47.rmSync)(tmp, { recursive: true, force: true });
|
|
20226
20378
|
}
|
|
20227
20379
|
}
|
|
20228
20380
|
function importConductorWorkspace(workspaceId) {
|
|
20229
|
-
if (!(0,
|
|
20381
|
+
if (!(0, import_node_fs47.existsSync)(CONDUCTOR_DB)) {
|
|
20230
20382
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
20231
20383
|
}
|
|
20232
|
-
const tmp = (0,
|
|
20233
|
-
const snapshot = (0,
|
|
20384
|
+
const tmp = (0, import_node_fs47.mkdtempSync)((0, import_node_path47.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
|
|
20385
|
+
const snapshot = (0, import_node_path47.join)(tmp, "conductor.db");
|
|
20234
20386
|
try {
|
|
20235
|
-
(0,
|
|
20387
|
+
(0, import_node_fs47.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
20236
20388
|
for (const suffix of ["-wal", "-shm"]) {
|
|
20237
20389
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
20238
|
-
if ((0,
|
|
20390
|
+
if ((0, import_node_fs47.existsSync)(src)) {
|
|
20239
20391
|
try {
|
|
20240
|
-
(0,
|
|
20392
|
+
(0, import_node_fs47.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
20241
20393
|
} catch {
|
|
20242
20394
|
}
|
|
20243
20395
|
}
|
|
@@ -20255,7 +20407,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
20255
20407
|
).get(workspaceId);
|
|
20256
20408
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
20257
20409
|
const worktreePath = String(row.workspacePath);
|
|
20258
|
-
if (!(0,
|
|
20410
|
+
if (!(0, import_node_fs47.existsSync)(worktreePath)) {
|
|
20259
20411
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
20260
20412
|
}
|
|
20261
20413
|
let sessionId = null;
|
|
@@ -20318,31 +20470,31 @@ function importConductorWorkspace(workspaceId) {
|
|
|
20318
20470
|
db.close();
|
|
20319
20471
|
}
|
|
20320
20472
|
} finally {
|
|
20321
|
-
(0,
|
|
20473
|
+
(0, import_node_fs47.rmSync)(tmp, { recursive: true, force: true });
|
|
20322
20474
|
}
|
|
20323
20475
|
}
|
|
20324
20476
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
20325
20477
|
return importConductorWorkspace(workspaceId);
|
|
20326
20478
|
}
|
|
20327
|
-
var import_node_child_process5,
|
|
20479
|
+
var import_node_child_process5, import_node_fs47, import_node_os14, import_node_path47, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
|
|
20328
20480
|
var init_adopt = __esm({
|
|
20329
20481
|
"src/threads/adopt.ts"() {
|
|
20330
20482
|
"use strict";
|
|
20331
20483
|
import_node_child_process5 = require("child_process");
|
|
20332
|
-
|
|
20484
|
+
import_node_fs47 = require("fs");
|
|
20333
20485
|
import_node_os14 = require("os");
|
|
20334
|
-
|
|
20486
|
+
import_node_path47 = require("path");
|
|
20335
20487
|
import_node_module4 = require("module");
|
|
20336
20488
|
init_worktree();
|
|
20337
20489
|
init_thread_store();
|
|
20338
|
-
CONDUCTOR_APP_SUPPORT = (0,
|
|
20490
|
+
CONDUCTOR_APP_SUPPORT = (0, import_node_path47.join)(
|
|
20339
20491
|
process.env.HOME ?? "",
|
|
20340
20492
|
"Library",
|
|
20341
20493
|
"Application Support",
|
|
20342
20494
|
"com.conductor.app"
|
|
20343
20495
|
);
|
|
20344
|
-
CONDUCTOR_DB = (0,
|
|
20345
|
-
CURSOR_SDK_STORE = (0,
|
|
20496
|
+
CONDUCTOR_DB = (0, import_node_path47.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
20497
|
+
CURSOR_SDK_STORE = (0, import_node_path47.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
20346
20498
|
}
|
|
20347
20499
|
});
|
|
20348
20500
|
|
|
@@ -20409,7 +20561,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
20409
20561
|
let createdWorktree = false;
|
|
20410
20562
|
const trees = await listWorktrees(repoPath);
|
|
20411
20563
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
20412
|
-
if (checkedOut?.path && (0,
|
|
20564
|
+
if (checkedOut?.path && (0, import_node_fs48.existsSync)(checkedOut.path)) {
|
|
20413
20565
|
if (input.reuseExistingWorktree !== false) {
|
|
20414
20566
|
worktreePath = checkedOut.path;
|
|
20415
20567
|
} else {
|
|
@@ -20551,7 +20703,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
20551
20703
|
async function createPrStack(input, onSetupLine) {
|
|
20552
20704
|
await requireAgent(input.agent);
|
|
20553
20705
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
20554
|
-
if (!(0,
|
|
20706
|
+
if (!(0, import_node_fs48.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
20555
20707
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
20556
20708
|
const status = await detectGhStack(repoPath);
|
|
20557
20709
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -20618,7 +20770,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
20618
20770
|
}
|
|
20619
20771
|
}
|
|
20620
20772
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
20621
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
20773
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs48.existsSync)(bootstrap.worktreePath)) {
|
|
20622
20774
|
try {
|
|
20623
20775
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
20624
20776
|
deleteBranch: bootstrap.branchName
|
|
@@ -20638,11 +20790,11 @@ function stackAgentDefaultsFrom(input) {
|
|
|
20638
20790
|
planMode: input.planMode
|
|
20639
20791
|
};
|
|
20640
20792
|
}
|
|
20641
|
-
var
|
|
20793
|
+
var import_node_fs48;
|
|
20642
20794
|
var init_stack_layers = __esm({
|
|
20643
20795
|
"src/threads/stack-layers.ts"() {
|
|
20644
20796
|
"use strict";
|
|
20645
|
-
|
|
20797
|
+
import_node_fs48 = require("fs");
|
|
20646
20798
|
init_detect();
|
|
20647
20799
|
init_run();
|
|
20648
20800
|
init_stack();
|
|
@@ -20655,7 +20807,7 @@ var init_stack_layers = __esm({
|
|
|
20655
20807
|
|
|
20656
20808
|
// src/diff/diff.ts
|
|
20657
20809
|
async function inspectGitWorktree(worktreePath) {
|
|
20658
|
-
if (!worktreePath || !(0,
|
|
20810
|
+
if (!worktreePath || !(0, import_node_fs49.existsSync)(worktreePath)) return "missing_worktree";
|
|
20659
20811
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
20660
20812
|
reject: false
|
|
20661
20813
|
});
|
|
@@ -20663,7 +20815,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
20663
20815
|
return "ok";
|
|
20664
20816
|
}
|
|
20665
20817
|
async function initializeGitRepository(worktreePath) {
|
|
20666
|
-
if (!worktreePath || !(0,
|
|
20818
|
+
if (!worktreePath || !(0, import_node_fs49.existsSync)(worktreePath)) {
|
|
20667
20819
|
throw new Error("Worktree not found");
|
|
20668
20820
|
}
|
|
20669
20821
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -20797,11 +20949,11 @@ new file mode 100644
|
|
|
20797
20949
|
};
|
|
20798
20950
|
}
|
|
20799
20951
|
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
20800
|
-
const abs = (0,
|
|
20952
|
+
const abs = (0, import_node_path48.join)(worktreePath, path2);
|
|
20801
20953
|
try {
|
|
20802
|
-
const st = (0,
|
|
20954
|
+
const st = (0, import_node_fs49.statSync)(abs);
|
|
20803
20955
|
if (st.isFile() && st.size > maxHunk) {
|
|
20804
|
-
const buf = (0,
|
|
20956
|
+
const buf = (0, import_node_fs49.readFileSync)(abs).subarray(0, maxHunk);
|
|
20805
20957
|
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
20806
20958
|
}
|
|
20807
20959
|
} catch {
|
|
@@ -21266,6 +21418,15 @@ async function getDiff(worktreePath, repoPath, opts) {
|
|
|
21266
21418
|
mergeBase: needsMergeBase ? mergeBase : null
|
|
21267
21419
|
};
|
|
21268
21420
|
}
|
|
21421
|
+
function statWorktreePath(worktreePath, relativePath) {
|
|
21422
|
+
assertSafeRelativePath(relativePath);
|
|
21423
|
+
const abs = (0, import_node_path48.join)(worktreePath, relativePath);
|
|
21424
|
+
if (!(0, import_node_fs49.existsSync)(abs)) return "missing";
|
|
21425
|
+
const st = (0, import_node_fs49.statSync)(abs);
|
|
21426
|
+
if (st.isDirectory()) return "dir";
|
|
21427
|
+
if (st.isFile()) return "file";
|
|
21428
|
+
return "missing";
|
|
21429
|
+
}
|
|
21269
21430
|
async function listWorktreeFiles(worktreePath, opts) {
|
|
21270
21431
|
const maxFiles = opts?.maxFiles ?? 5e3;
|
|
21271
21432
|
const tracked = await git(["ls-files", "-z"], worktreePath, { reject: false });
|
|
@@ -21290,8 +21451,8 @@ function isImageRelativePath(relativePath) {
|
|
|
21290
21451
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
21291
21452
|
assertSafeRelativePath(relativePath);
|
|
21292
21453
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
21293
|
-
const abs = (0,
|
|
21294
|
-
const st = (0,
|
|
21454
|
+
const abs = (0, import_node_path48.join)(worktreePath, relativePath);
|
|
21455
|
+
const st = (0, import_node_fs49.statSync)(abs);
|
|
21295
21456
|
if (!st.isFile()) {
|
|
21296
21457
|
throw new Error(`Not a file: ${relativePath}`);
|
|
21297
21458
|
}
|
|
@@ -21300,7 +21461,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
21300
21461
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
21301
21462
|
);
|
|
21302
21463
|
}
|
|
21303
|
-
const buf = (0,
|
|
21464
|
+
const buf = (0, import_node_fs49.readFileSync)(abs);
|
|
21304
21465
|
return {
|
|
21305
21466
|
path: relativePath,
|
|
21306
21467
|
contentBase64: buf.toString("base64"),
|
|
@@ -21310,12 +21471,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
21310
21471
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
21311
21472
|
assertSafeRelativePath(relativePath);
|
|
21312
21473
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
21313
|
-
const abs = (0,
|
|
21314
|
-
const st = (0,
|
|
21474
|
+
const abs = (0, import_node_path48.join)(worktreePath, relativePath);
|
|
21475
|
+
const st = (0, import_node_fs49.statSync)(abs);
|
|
21315
21476
|
if (!st.isFile()) {
|
|
21316
21477
|
throw new Error(`Not a file: ${relativePath}`);
|
|
21317
21478
|
}
|
|
21318
|
-
const buf = (0,
|
|
21479
|
+
const buf = (0, import_node_fs49.readFileSync)(abs);
|
|
21319
21480
|
if (isImageRelativePath(relativePath)) {
|
|
21320
21481
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
21321
21482
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -21358,9 +21519,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
21358
21519
|
}
|
|
21359
21520
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
21360
21521
|
assertSafeRelativePath(relativePath);
|
|
21361
|
-
const abs = (0,
|
|
21362
|
-
(0,
|
|
21363
|
-
(0,
|
|
21522
|
+
const abs = (0, import_node_path48.join)(worktreePath, relativePath);
|
|
21523
|
+
(0, import_node_fs49.mkdirSync)((0, import_node_path48.dirname)(abs), { recursive: true });
|
|
21524
|
+
(0, import_node_fs49.writeFileSync)(abs, content, "utf8");
|
|
21364
21525
|
return { path: relativePath };
|
|
21365
21526
|
}
|
|
21366
21527
|
async function getWorktreeDirtyStat(worktreePath) {
|
|
@@ -21400,12 +21561,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
21400
21561
|
truncated: full.files.length > maxFiles
|
|
21401
21562
|
};
|
|
21402
21563
|
}
|
|
21403
|
-
var
|
|
21564
|
+
var import_node_fs49, import_node_path48, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
|
|
21404
21565
|
var init_diff = __esm({
|
|
21405
21566
|
"src/diff/diff.ts"() {
|
|
21406
21567
|
"use strict";
|
|
21407
|
-
|
|
21408
|
-
|
|
21568
|
+
import_node_fs49 = require("fs");
|
|
21569
|
+
import_node_path48 = require("path");
|
|
21409
21570
|
init_run();
|
|
21410
21571
|
init_worktree();
|
|
21411
21572
|
mergeBaseCache = /* @__PURE__ */ new Map();
|
|
@@ -21762,7 +21923,7 @@ function parseFrontmatter(content) {
|
|
|
21762
21923
|
}
|
|
21763
21924
|
function readSkill(skillMd, source) {
|
|
21764
21925
|
try {
|
|
21765
|
-
const content = (0,
|
|
21926
|
+
const content = (0, import_node_fs50.readFileSync)(skillMd, "utf8");
|
|
21766
21927
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
21767
21928
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
21768
21929
|
const name = fmName || dirName;
|
|
@@ -21781,19 +21942,19 @@ function readSkill(skillMd, source) {
|
|
|
21781
21942
|
}
|
|
21782
21943
|
}
|
|
21783
21944
|
function scanSkillsDir(dir, source, out) {
|
|
21784
|
-
if (!(0,
|
|
21945
|
+
if (!(0, import_node_fs50.existsSync)(dir)) return;
|
|
21785
21946
|
let entries;
|
|
21786
21947
|
try {
|
|
21787
|
-
entries = (0,
|
|
21948
|
+
entries = (0, import_node_fs50.readdirSync)(dir);
|
|
21788
21949
|
} catch {
|
|
21789
21950
|
return;
|
|
21790
21951
|
}
|
|
21791
21952
|
for (const entry of entries) {
|
|
21792
21953
|
if (entry.startsWith(".")) continue;
|
|
21793
|
-
const skillMd = (0,
|
|
21794
|
-
if (!(0,
|
|
21954
|
+
const skillMd = (0, import_node_path49.join)(dir, entry, "SKILL.md");
|
|
21955
|
+
if (!(0, import_node_fs50.existsSync)(skillMd)) continue;
|
|
21795
21956
|
try {
|
|
21796
|
-
if (!(0,
|
|
21957
|
+
if (!(0, import_node_fs50.statSync)(skillMd).isFile()) continue;
|
|
21797
21958
|
} catch {
|
|
21798
21959
|
continue;
|
|
21799
21960
|
}
|
|
@@ -21802,24 +21963,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
21802
21963
|
}
|
|
21803
21964
|
}
|
|
21804
21965
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
21805
|
-
if (!(0,
|
|
21966
|
+
if (!(0, import_node_fs50.existsSync)(pluginsRoot)) return;
|
|
21806
21967
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
21807
21968
|
if (depth > 7) return;
|
|
21808
21969
|
let entries;
|
|
21809
21970
|
try {
|
|
21810
|
-
entries = (0,
|
|
21971
|
+
entries = (0, import_node_fs50.readdirSync)(dir);
|
|
21811
21972
|
} catch {
|
|
21812
21973
|
return;
|
|
21813
21974
|
}
|
|
21814
21975
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
21815
|
-
const skill = readSkill((0,
|
|
21976
|
+
const skill = readSkill((0, import_node_path49.join)(dir, "SKILL.md"), "cli");
|
|
21816
21977
|
if (skill) out.push(skill);
|
|
21817
21978
|
}
|
|
21818
21979
|
for (const entry of entries) {
|
|
21819
21980
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
21820
|
-
const full = (0,
|
|
21981
|
+
const full = (0, import_node_path49.join)(dir, entry);
|
|
21821
21982
|
try {
|
|
21822
|
-
if (!(0,
|
|
21983
|
+
if (!(0, import_node_fs50.statSync)(full).isDirectory()) continue;
|
|
21823
21984
|
} catch {
|
|
21824
21985
|
continue;
|
|
21825
21986
|
}
|
|
@@ -21837,17 +21998,17 @@ function discoverSkills(worktreePath) {
|
|
|
21837
21998
|
const home = (0, import_node_os15.homedir)();
|
|
21838
21999
|
const collected = [];
|
|
21839
22000
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
21840
|
-
scanSkillsDir((0,
|
|
22001
|
+
scanSkillsDir((0, import_node_path49.join)(worktreePath, rel), "workspace", collected);
|
|
21841
22002
|
}
|
|
21842
22003
|
for (const abs of [
|
|
21843
|
-
(0,
|
|
21844
|
-
(0,
|
|
21845
|
-
(0,
|
|
21846
|
-
(0,
|
|
22004
|
+
(0, import_node_path49.join)(home, ".claude/skills"),
|
|
22005
|
+
(0, import_node_path49.join)(home, ".cursor/skills"),
|
|
22006
|
+
(0, import_node_path49.join)(home, ".sideboard/skills"),
|
|
22007
|
+
(0, import_node_path49.join)(home, ".brightsy/skills")
|
|
21847
22008
|
]) {
|
|
21848
22009
|
scanSkillsDir(abs, "user", collected);
|
|
21849
22010
|
}
|
|
21850
|
-
scanClaudePluginSkills((0,
|
|
22011
|
+
scanClaudePluginSkills((0, import_node_path49.join)(home, ".claude/plugins"), collected);
|
|
21851
22012
|
collected.push(...bundledSkills());
|
|
21852
22013
|
const rank = {
|
|
21853
22014
|
workspace: 0,
|
|
@@ -21873,7 +22034,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
21873
22034
|
\u2026(truncated)` : body;
|
|
21874
22035
|
}
|
|
21875
22036
|
}
|
|
21876
|
-
const raw = (0,
|
|
22037
|
+
const raw = (0, import_node_fs50.readFileSync)(skillPath, "utf8");
|
|
21877
22038
|
if (raw.startsWith("---")) {
|
|
21878
22039
|
const end = raw.indexOf("\n---", 3);
|
|
21879
22040
|
if (end >= 0) {
|
|
@@ -21887,13 +22048,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
21887
22048
|
|
|
21888
22049
|
\u2026(truncated)` : raw;
|
|
21889
22050
|
}
|
|
21890
|
-
var
|
|
22051
|
+
var import_node_fs50, import_node_os15, import_node_path49, BUNDLED_SKILL_PREFIX;
|
|
21891
22052
|
var init_discover = __esm({
|
|
21892
22053
|
"src/skills/discover.ts"() {
|
|
21893
22054
|
"use strict";
|
|
21894
|
-
|
|
22055
|
+
import_node_fs50 = require("fs");
|
|
21895
22056
|
import_node_os15 = require("os");
|
|
21896
|
-
|
|
22057
|
+
import_node_path49 = require("path");
|
|
21897
22058
|
init_long_running();
|
|
21898
22059
|
BUNDLED_SKILL_PREFIX = "bundled:";
|
|
21899
22060
|
}
|
|
@@ -22042,10 +22203,22 @@ var init_consume_attachments = __esm({
|
|
|
22042
22203
|
});
|
|
22043
22204
|
|
|
22044
22205
|
// src/skills/detached-job-path.ts
|
|
22206
|
+
function compiledModuleDir() {
|
|
22207
|
+
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
22208
|
+
if (cjsDir) return cjsDir;
|
|
22209
|
+
try {
|
|
22210
|
+
const url = import_meta3.url;
|
|
22211
|
+
if (typeof url === "string" && url.length > 0) {
|
|
22212
|
+
return (0, import_node_path50.dirname)((0, import_node_url3.fileURLToPath)(url));
|
|
22213
|
+
}
|
|
22214
|
+
} catch {
|
|
22215
|
+
}
|
|
22216
|
+
return null;
|
|
22217
|
+
}
|
|
22045
22218
|
function detachedJobScriptIn(dir) {
|
|
22046
22219
|
for (const name of DETACHED_JOB_FILENAMES) {
|
|
22047
|
-
const script = (0,
|
|
22048
|
-
if ((0,
|
|
22220
|
+
const script = (0, import_node_path50.join)(dir, "scripts", name);
|
|
22221
|
+
if ((0, import_node_fs51.existsSync)(script)) return script;
|
|
22049
22222
|
}
|
|
22050
22223
|
return null;
|
|
22051
22224
|
}
|
|
@@ -22057,11 +22230,12 @@ function packagedDetachedJobPath() {
|
|
|
22057
22230
|
function resolveDetachedJobScript() {
|
|
22058
22231
|
const packaged = packagedDetachedJobPath();
|
|
22059
22232
|
if (packaged) return packaged;
|
|
22060
|
-
let dir = (
|
|
22233
|
+
let dir = compiledModuleDir();
|
|
22234
|
+
if (!dir) return null;
|
|
22061
22235
|
for (let i = 0; i < 8; i++) {
|
|
22062
22236
|
const candidate = detachedJobScriptIn(dir);
|
|
22063
22237
|
if (candidate) return candidate;
|
|
22064
|
-
const parent = (0,
|
|
22238
|
+
const parent = (0, import_node_path50.dirname)(dir);
|
|
22065
22239
|
if (parent === dir) break;
|
|
22066
22240
|
dir = parent;
|
|
22067
22241
|
}
|
|
@@ -22072,12 +22246,12 @@ function formatDetachedJobInvoke(scriptPath) {
|
|
|
22072
22246
|
if (resolved) return `node ${JSON.stringify(resolved)}`;
|
|
22073
22247
|
return "node scripts/detached-job.cjs";
|
|
22074
22248
|
}
|
|
22075
|
-
var
|
|
22249
|
+
var import_node_fs51, import_node_path50, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
|
|
22076
22250
|
var init_detached_job_path = __esm({
|
|
22077
22251
|
"src/skills/detached-job-path.ts"() {
|
|
22078
22252
|
"use strict";
|
|
22079
|
-
|
|
22080
|
-
|
|
22253
|
+
import_node_fs51 = require("fs");
|
|
22254
|
+
import_node_path50 = require("path");
|
|
22081
22255
|
import_node_url3 = require("url");
|
|
22082
22256
|
init_packaged_runtime();
|
|
22083
22257
|
import_meta3 = {};
|
|
@@ -22259,9 +22433,9 @@ function formatPrGateDirective() {
|
|
|
22259
22433
|
}
|
|
22260
22434
|
function formatProcessGuideDirective(opts) {
|
|
22261
22435
|
const worktree = opts?.worktreePath?.trim();
|
|
22262
|
-
const hasGraphSkill = !!worktree && (0,
|
|
22263
|
-
const hasReviewSkill = !!worktree && (0,
|
|
22264
|
-
const hasInstallSkill = !!worktree && (0,
|
|
22436
|
+
const hasGraphSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path51.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
|
|
22437
|
+
const hasReviewSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path51.join)(worktree, ".claude/skills/review/SKILL.md"));
|
|
22438
|
+
const hasInstallSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path51.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
|
|
22265
22439
|
return [
|
|
22266
22440
|
"Process guides (recurring work only):",
|
|
22267
22441
|
hasGraphSkill ? "- Migrations, ports, batch fixes, and other fan-out: follow `.claude/skills/graph-engineering/SKILL.md` (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch around it." : null,
|
|
@@ -22299,12 +22473,12 @@ function formatArtifactDirective() {
|
|
|
22299
22473
|
function formatUiReminder() {
|
|
22300
22474
|
return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos, \u201Cwhat next?\u201D, or after a review) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
|
|
22301
22475
|
}
|
|
22302
|
-
var
|
|
22476
|
+
var import_node_fs52, import_node_path51, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
|
|
22303
22477
|
var init_instructions = __esm({
|
|
22304
22478
|
"src/agents/instructions.ts"() {
|
|
22305
22479
|
"use strict";
|
|
22306
|
-
|
|
22307
|
-
|
|
22480
|
+
import_node_fs52 = require("fs");
|
|
22481
|
+
import_node_path51 = require("path");
|
|
22308
22482
|
init_git_auth_mode();
|
|
22309
22483
|
init_branch_prefix();
|
|
22310
22484
|
init_worktree_labels();
|
|
@@ -22690,40 +22864,40 @@ __export(plan_file_exports, {
|
|
|
22690
22864
|
writePlanFile: () => writePlanFile
|
|
22691
22865
|
});
|
|
22692
22866
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
22693
|
-
const gitignoreAbs = (0,
|
|
22694
|
-
if ((0,
|
|
22695
|
-
(0,
|
|
22696
|
-
(0,
|
|
22867
|
+
const gitignoreAbs = (0, import_node_path52.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
22868
|
+
if ((0, import_node_fs53.existsSync)(gitignoreAbs)) return;
|
|
22869
|
+
(0, import_node_fs53.mkdirSync)((0, import_node_path52.dirname)(gitignoreAbs), { recursive: true });
|
|
22870
|
+
(0, import_node_fs53.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
22697
22871
|
}
|
|
22698
22872
|
function planFileAbs(worktreePath) {
|
|
22699
|
-
return (0,
|
|
22873
|
+
return (0, import_node_path52.join)(worktreePath, PLAN_FILE_REL);
|
|
22700
22874
|
}
|
|
22701
22875
|
function readTextIfPresent2(abs) {
|
|
22702
|
-
if (!(0,
|
|
22876
|
+
if (!(0, import_node_fs53.existsSync)(abs)) return null;
|
|
22703
22877
|
try {
|
|
22704
|
-
const content = (0,
|
|
22878
|
+
const content = (0, import_node_fs53.readFileSync)(abs, "utf8");
|
|
22705
22879
|
return content.trim() ? content : null;
|
|
22706
22880
|
} catch {
|
|
22707
22881
|
return null;
|
|
22708
22882
|
}
|
|
22709
22883
|
}
|
|
22710
22884
|
function readPlanFile(worktreePath) {
|
|
22711
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
22885
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path52.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path52.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
22712
22886
|
}
|
|
22713
22887
|
function writePlanFile(worktreePath, content) {
|
|
22714
22888
|
ensureAttachmentsGitignore(worktreePath);
|
|
22715
22889
|
const abs = planFileAbs(worktreePath);
|
|
22716
|
-
(0,
|
|
22890
|
+
(0, import_node_fs53.mkdirSync)((0, import_node_path52.dirname)(abs), { recursive: true });
|
|
22717
22891
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
22718
|
-
(0,
|
|
22892
|
+
(0, import_node_fs53.writeFileSync)(abs, body, "utf8");
|
|
22719
22893
|
return PLAN_FILE_REL;
|
|
22720
22894
|
}
|
|
22721
|
-
var
|
|
22895
|
+
var import_node_fs53, import_node_path52;
|
|
22722
22896
|
var init_plan_file = __esm({
|
|
22723
22897
|
"src/plan/plan-file.ts"() {
|
|
22724
22898
|
"use strict";
|
|
22725
|
-
|
|
22726
|
-
|
|
22899
|
+
import_node_fs53 = require("fs");
|
|
22900
|
+
import_node_path52 = require("path");
|
|
22727
22901
|
init_workspace_scratch();
|
|
22728
22902
|
init_plan_present();
|
|
22729
22903
|
init_plan_present();
|
|
@@ -22785,9 +22959,9 @@ function recoverFinishedCursorRun(opts) {
|
|
|
22785
22959
|
return best;
|
|
22786
22960
|
}
|
|
22787
22961
|
function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
22788
|
-
if (!(0,
|
|
22962
|
+
if (!(0, import_node_fs54.existsSync)(runsPath)) return null;
|
|
22789
22963
|
try {
|
|
22790
|
-
const lines = (0,
|
|
22964
|
+
const lines = (0, import_node_fs54.readFileSync)(runsPath, "utf8").split("\n");
|
|
22791
22965
|
let best = null;
|
|
22792
22966
|
for (const line of lines) {
|
|
22793
22967
|
const trimmed = line.trim();
|
|
@@ -22813,11 +22987,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
|
22813
22987
|
return null;
|
|
22814
22988
|
}
|
|
22815
22989
|
}
|
|
22816
|
-
var
|
|
22990
|
+
var import_node_fs54;
|
|
22817
22991
|
var init_cursor_recover = __esm({
|
|
22818
22992
|
"src/agents/cursor-recover.ts"() {
|
|
22819
22993
|
"use strict";
|
|
22820
|
-
|
|
22994
|
+
import_node_fs54 = require("fs");
|
|
22821
22995
|
init_cursor_store();
|
|
22822
22996
|
}
|
|
22823
22997
|
});
|
|
@@ -22960,17 +23134,18 @@ async function startOrchestration(opts) {
|
|
|
22960
23134
|
}
|
|
22961
23135
|
return updated;
|
|
22962
23136
|
}
|
|
22963
|
-
var import_node_events,
|
|
23137
|
+
var import_node_events, import_node_fs55, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
|
|
22964
23138
|
var init_orchestrator = __esm({
|
|
22965
23139
|
"src/orchestrator/orchestrator.ts"() {
|
|
22966
23140
|
"use strict";
|
|
22967
23141
|
import_node_events = require("events");
|
|
22968
23142
|
init_outbound_watch();
|
|
22969
|
-
|
|
23143
|
+
import_node_fs55 = require("fs");
|
|
22970
23144
|
init_error_detail();
|
|
22971
23145
|
init_run();
|
|
22972
23146
|
init_stale_lock();
|
|
22973
23147
|
init_spawn();
|
|
23148
|
+
init_turn_trace();
|
|
22974
23149
|
init_agents();
|
|
22975
23150
|
init_worktree();
|
|
22976
23151
|
init_stack();
|
|
@@ -23131,7 +23306,7 @@ var init_orchestrator = __esm({
|
|
|
23131
23306
|
this.lightReconcileAt.set(repoPath, Date.now());
|
|
23132
23307
|
for (const thread of listThreads()) {
|
|
23133
23308
|
if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
|
|
23134
|
-
if (!(0,
|
|
23309
|
+
if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
|
|
23135
23310
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
23136
23311
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
23137
23312
|
}
|
|
@@ -23160,7 +23335,7 @@ var init_orchestrator = __esm({
|
|
|
23160
23335
|
}
|
|
23161
23336
|
continue;
|
|
23162
23337
|
}
|
|
23163
|
-
if (!(0,
|
|
23338
|
+
if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
|
|
23164
23339
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
23165
23340
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
23166
23341
|
continue;
|
|
@@ -23226,7 +23401,7 @@ var init_orchestrator = __esm({
|
|
|
23226
23401
|
}
|
|
23227
23402
|
if (thread.queue.length > 0) {
|
|
23228
23403
|
this.haltDrain.delete(thread.id);
|
|
23229
|
-
|
|
23404
|
+
this.armDrain(thread.id);
|
|
23230
23405
|
}
|
|
23231
23406
|
}
|
|
23232
23407
|
}
|
|
@@ -23562,7 +23737,7 @@ var init_orchestrator = __esm({
|
|
|
23562
23737
|
this.emit({ type: "status_changed", threadId: thread.id, status: "queued" });
|
|
23563
23738
|
}
|
|
23564
23739
|
if (thisProcessShouldDrainAgentQueues() && !shouldSteer) {
|
|
23565
|
-
|
|
23740
|
+
this.armDrain(thread.id);
|
|
23566
23741
|
}
|
|
23567
23742
|
return this.requireThread(thread.id);
|
|
23568
23743
|
});
|
|
@@ -23642,9 +23817,15 @@ var init_orchestrator = __esm({
|
|
|
23642
23817
|
if (inFlight || foreignLive) {
|
|
23643
23818
|
this.stop(thread.id, { clearQueue: false, continueQueue: true });
|
|
23644
23819
|
}
|
|
23645
|
-
|
|
23820
|
+
this.armDrain(thread.id);
|
|
23646
23821
|
return this.requireThread(thread.id);
|
|
23647
23822
|
}
|
|
23823
|
+
armDrain(threadId) {
|
|
23824
|
+
void this.drainQueue(threadId).catch((err) => {
|
|
23825
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
23826
|
+
console.error(`[sideboard] drainQueue ${threadId}: ${detail}`);
|
|
23827
|
+
});
|
|
23828
|
+
}
|
|
23648
23829
|
async drainQueue(threadId) {
|
|
23649
23830
|
if (this.draining.has(threadId)) return;
|
|
23650
23831
|
this.draining.add(threadId);
|
|
@@ -23716,196 +23897,205 @@ var init_orchestrator = __esm({
|
|
|
23716
23897
|
this.emit({ type: "status_changed", threadId, status: "running" });
|
|
23717
23898
|
this.emit({ type: "turn_started", threadId, prompt });
|
|
23718
23899
|
try {
|
|
23719
|
-
|
|
23720
|
-
|
|
23721
|
-
|
|
23722
|
-
|
|
23723
|
-
try {
|
|
23724
|
-
const compact = await maybeCompactContext(thread);
|
|
23725
|
-
if (compact.didCompact) {
|
|
23726
|
-
thread = updateThread(threadId, {
|
|
23727
|
-
messages: compact.thread.messages,
|
|
23728
|
-
sessionId: compact.thread.sessionId
|
|
23729
|
-
});
|
|
23730
|
-
this.emit({
|
|
23731
|
-
type: "context_compacted",
|
|
23732
|
-
threadId,
|
|
23733
|
-
olderCount: compact.olderCount ?? 0,
|
|
23734
|
-
method: compact.method ?? "extractive"
|
|
23735
|
-
});
|
|
23900
|
+
try {
|
|
23901
|
+
const baseline = await captureTurnBaseline(thread.worktreePath);
|
|
23902
|
+
if (baseline) this.turnBaselines.set(threadId, baseline);
|
|
23903
|
+
} catch {
|
|
23736
23904
|
}
|
|
23737
|
-
|
|
23738
|
-
|
|
23739
|
-
|
|
23740
|
-
|
|
23741
|
-
|
|
23742
|
-
|
|
23743
|
-
|
|
23744
|
-
|
|
23745
|
-
|
|
23746
|
-
|
|
23747
|
-
|
|
23748
|
-
|
|
23749
|
-
|
|
23750
|
-
|
|
23751
|
-
|
|
23752
|
-
|
|
23753
|
-
|
|
23754
|
-
|
|
23755
|
-
thread.worktreePath,
|
|
23756
|
-
gitPrompt,
|
|
23757
|
-
{
|
|
23758
|
-
attachments: autoContinue ? [] : sentAttachments ?? []
|
|
23905
|
+
try {
|
|
23906
|
+
const compact = await maybeCompactContext(thread);
|
|
23907
|
+
if (compact.didCompact) {
|
|
23908
|
+
thread = updateThread(threadId, {
|
|
23909
|
+
messages: compact.thread.messages,
|
|
23910
|
+
sessionId: compact.thread.sessionId
|
|
23911
|
+
});
|
|
23912
|
+
this.emit({
|
|
23913
|
+
type: "context_compacted",
|
|
23914
|
+
threadId,
|
|
23915
|
+
olderCount: compact.olderCount ?? 0,
|
|
23916
|
+
method: compact.method ?? "extractive"
|
|
23917
|
+
});
|
|
23918
|
+
}
|
|
23919
|
+
} catch (err) {
|
|
23920
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23921
|
+
this.emit({ type: "error", threadId, message: `context compact failed: ${message}` });
|
|
23922
|
+
thread = this.requireThread(threadId);
|
|
23759
23923
|
}
|
|
23760
|
-
|
|
23761
|
-
|
|
23762
|
-
|
|
23763
|
-
|
|
23764
|
-
|
|
23765
|
-
|
|
23766
|
-
|
|
23767
|
-
|
|
23768
|
-
|
|
23769
|
-
|
|
23770
|
-
|
|
23771
|
-
|
|
23772
|
-
|
|
23773
|
-
|
|
23774
|
-
|
|
23775
|
-
|
|
23776
|
-
|
|
23777
|
-
|
|
23778
|
-
|
|
23779
|
-
|
|
23780
|
-
|
|
23781
|
-
|
|
23782
|
-
|
|
23783
|
-
|
|
23784
|
-
ticketProvider: issueTicket?.provider
|
|
23785
|
-
}) : null;
|
|
23786
|
-
const viewerContextReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatViewerContextReminder() : null;
|
|
23787
|
-
const reviewWriteGateReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && isReviewWriteGatedThread(
|
|
23788
|
-
thread,
|
|
23789
|
-
thread.worktreePath ? threadsSharingWorktree(thread.worktreePath) : []
|
|
23790
|
-
) ? formatReviewWriteGateReminder() : null;
|
|
23791
|
-
const slackReplyContext = formatSlackRepliesForTurn(
|
|
23792
|
-
pendingSlackExternalReplies(thread.messages)
|
|
23793
|
-
);
|
|
23794
|
-
const turnReminders = [
|
|
23795
|
-
worktreeReminder,
|
|
23796
|
-
optionalServicesReminder,
|
|
23797
|
-
issueToolsReminder,
|
|
23798
|
-
reviewWriteGateReminder,
|
|
23799
|
-
viewerContextReminder,
|
|
23800
|
-
artifactReminder,
|
|
23801
|
-
longRunningReminder
|
|
23802
|
-
].filter(Boolean).join("\n\n") || void 0;
|
|
23803
|
-
const prGateDirective = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && mentionsPrGoal(prompt) ? formatPrGateDirective() : null;
|
|
23804
|
-
const agentPrompt = [
|
|
23805
|
-
thread.planMode ? PLAN_MODE_INSTRUCTION : null,
|
|
23806
|
-
orchestrationReminder,
|
|
23807
|
-
prGateDirective,
|
|
23808
|
-
slackReplyContext,
|
|
23809
|
-
expandedPrompt
|
|
23810
|
-
].filter(Boolean).join("\n\n");
|
|
23811
|
-
if (!autoContinue && sentAttachments) {
|
|
23812
|
-
updateThread(threadId, { pendingTurnAttachments: [] });
|
|
23813
|
-
}
|
|
23814
|
-
const adapter = getAdapter(thread.agent);
|
|
23815
|
-
const resolved = await adapter.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
23816
|
-
if (resolved && resolved !== thread.sessionId) {
|
|
23817
|
-
updateThread(threadId, { sessionId: resolved });
|
|
23818
|
-
}
|
|
23819
|
-
const fresh = this.requireThread(threadId);
|
|
23820
|
-
if (!fresh.worktreePath?.trim()) {
|
|
23821
|
-
throw new Error(
|
|
23822
|
-
`Thread ${threadId} has no worktreePath \u2014 refusing to start an agent outside an isolated worktree`
|
|
23924
|
+
const promptText = typeof prompt === "string" ? prompt : "";
|
|
23925
|
+
const autoContinue = isJobContinuePrompt(promptText) || promptText.startsWith("The previous agent process ended before it finished.");
|
|
23926
|
+
const parked = takePendingTurnAttachments(thread);
|
|
23927
|
+
const sentAttachments = !autoContinue && parked.length > 0 ? parked : void 0;
|
|
23928
|
+
appendMessage(threadId, {
|
|
23929
|
+
role: "user",
|
|
23930
|
+
text: promptText,
|
|
23931
|
+
...sentAttachments ? { attachments: sentAttachments } : {},
|
|
23932
|
+
...autoContinue ? { origin: "continue" } : {},
|
|
23933
|
+
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
23934
|
+
});
|
|
23935
|
+
traceTurn("runTurn.afterUserMessage", {
|
|
23936
|
+
threadId,
|
|
23937
|
+
agent: thread.agent,
|
|
23938
|
+
orch: isOrchestratorThread(thread)
|
|
23939
|
+
});
|
|
23940
|
+
thread = this.requireThread(threadId);
|
|
23941
|
+
const gitPrompt = expandCanonicalGitRequest(promptText);
|
|
23942
|
+
const { agentPrompt: expandedPrompt } = expandComposerPrompt(
|
|
23943
|
+
thread.worktreePath,
|
|
23944
|
+
gitPrompt,
|
|
23945
|
+
{
|
|
23946
|
+
attachments: autoContinue ? [] : sentAttachments ?? []
|
|
23947
|
+
}
|
|
23823
23948
|
);
|
|
23824
|
-
|
|
23825
|
-
|
|
23826
|
-
|
|
23827
|
-
|
|
23828
|
-
|
|
23829
|
-
|
|
23830
|
-
|
|
23831
|
-
|
|
23832
|
-
|
|
23833
|
-
|
|
23834
|
-
|
|
23835
|
-
|
|
23836
|
-
|
|
23837
|
-
|
|
23838
|
-
|
|
23839
|
-
|
|
23840
|
-
|
|
23841
|
-
|
|
23842
|
-
|
|
23843
|
-
|
|
23844
|
-
|
|
23845
|
-
|
|
23846
|
-
|
|
23847
|
-
|
|
23848
|
-
|
|
23849
|
-
|
|
23850
|
-
|
|
23851
|
-
|
|
23852
|
-
|
|
23853
|
-
|
|
23854
|
-
|
|
23855
|
-
)
|
|
23856
|
-
|
|
23857
|
-
|
|
23858
|
-
|
|
23949
|
+
const slackInbound = /^(Slack DM|Slack @mention)(?:\n|$)/.test(
|
|
23950
|
+
expandedPrompt.trim()
|
|
23951
|
+
);
|
|
23952
|
+
const orchestrationReminder = isOrchestratorThread(thread) ? [
|
|
23953
|
+
coordinatorTurnReminder({
|
|
23954
|
+
parentId: threadId,
|
|
23955
|
+
goal: thread.sourceRef || thread.title
|
|
23956
|
+
}),
|
|
23957
|
+
slackInbound ? [
|
|
23958
|
+
"This turn is a Slack DM or @mention. Your reply is posted back in Slack \u2014 keep it concise. Sideboard signs it with this Mac's destination name; do not prefix the name yourself.",
|
|
23959
|
+
SLACK_REPLY_FORMATTING
|
|
23960
|
+
].join("\n") : null
|
|
23961
|
+
].filter(Boolean).join("\n") : null;
|
|
23962
|
+
const artifactReminder = thread.agent !== "brightsy" ? formatUiReminder() : null;
|
|
23963
|
+
const longRunningReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatLongRunningReminder() : null;
|
|
23964
|
+
const worktreeReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatWorktreeReminder() : null;
|
|
23965
|
+
const optionalServicesReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatOptionalServicesReminder(loadAppSettings().integrations) : null;
|
|
23966
|
+
const issueTicket = issueTicketFromThread(thread, resolveEffectiveIssueSource());
|
|
23967
|
+
const issueToolsReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatIssueToolsReminder({
|
|
23968
|
+
linear: isLinearConnected(),
|
|
23969
|
+
abletime: isAbleTimeConnected(),
|
|
23970
|
+
github: true,
|
|
23971
|
+
ticketId: issueTicket?.id,
|
|
23972
|
+
ticketProvider: issueTicket?.provider
|
|
23973
|
+
}) : null;
|
|
23974
|
+
const viewerContextReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatViewerContextReminder() : null;
|
|
23975
|
+
const reviewWriteGateReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && isReviewWriteGatedThread(
|
|
23976
|
+
thread,
|
|
23977
|
+
thread.worktreePath ? threadsSharingWorktree(thread.worktreePath) : []
|
|
23978
|
+
) ? formatReviewWriteGateReminder() : null;
|
|
23979
|
+
const slackReplyContext = formatSlackRepliesForTurn(
|
|
23980
|
+
pendingSlackExternalReplies(thread.messages)
|
|
23981
|
+
);
|
|
23982
|
+
const turnReminders = [
|
|
23983
|
+
worktreeReminder,
|
|
23984
|
+
optionalServicesReminder,
|
|
23985
|
+
issueToolsReminder,
|
|
23986
|
+
reviewWriteGateReminder,
|
|
23987
|
+
viewerContextReminder,
|
|
23988
|
+
artifactReminder,
|
|
23989
|
+
longRunningReminder
|
|
23990
|
+
].filter(Boolean).join("\n\n") || void 0;
|
|
23991
|
+
const prGateDirective = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && mentionsPrGoal(promptText) ? formatPrGateDirective() : null;
|
|
23992
|
+
const agentPrompt = [
|
|
23993
|
+
thread.planMode ? PLAN_MODE_INSTRUCTION : null,
|
|
23994
|
+
orchestrationReminder,
|
|
23995
|
+
prGateDirective,
|
|
23996
|
+
slackReplyContext,
|
|
23997
|
+
expandedPrompt
|
|
23998
|
+
].filter(Boolean).join("\n\n");
|
|
23999
|
+
if (!autoContinue && sentAttachments) {
|
|
24000
|
+
updateThread(threadId, { pendingTurnAttachments: [] });
|
|
24001
|
+
}
|
|
24002
|
+
const adapter = getAdapter(thread.agent);
|
|
24003
|
+
const resolved = await adapter.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
24004
|
+
if (resolved && resolved !== thread.sessionId) {
|
|
24005
|
+
updateThread(threadId, { sessionId: resolved });
|
|
24006
|
+
}
|
|
24007
|
+
const fresh = this.requireThread(threadId);
|
|
24008
|
+
if (!fresh.worktreePath?.trim()) {
|
|
24009
|
+
throw new Error(
|
|
24010
|
+
`Thread ${threadId} has no worktreePath \u2014 refusing to start an agent outside an isolated worktree`
|
|
23859
24011
|
);
|
|
23860
24012
|
}
|
|
23861
|
-
|
|
23862
|
-
|
|
23863
|
-
|
|
23864
|
-
|
|
23865
|
-
const
|
|
23866
|
-
|
|
23867
|
-
|
|
23868
|
-
|
|
23869
|
-
|
|
23870
|
-
|
|
24013
|
+
const isBrightsy = fresh.agent === "brightsy";
|
|
24014
|
+
const isOrchestration = isOrchestratorThread(fresh);
|
|
24015
|
+
const { autoRenameBranchEnabled: autoRenameBranchEnabled2, getGithubGitAuthMode: getGithubGitAuthMode2, gitBranchPrefixSetting: gitBranchPrefixSetting2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
24016
|
+
const gitAuthMode = getGithubGitAuthMode2();
|
|
24017
|
+
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
24018
|
+
githubSlug: await withTimeout(
|
|
24019
|
+
resolveGithubRepoSlug(fresh.worktreePath),
|
|
24020
|
+
8e3,
|
|
24021
|
+
"resolveGithubRepoSlug"
|
|
24022
|
+
).catch(() => null),
|
|
24023
|
+
gitAuthMode
|
|
23871
24024
|
});
|
|
23872
|
-
|
|
23873
|
-
|
|
23874
|
-
|
|
23875
|
-
const
|
|
23876
|
-
|
|
23877
|
-
|
|
23878
|
-
|
|
23879
|
-
|
|
23880
|
-
|
|
23881
|
-
|
|
24025
|
+
const artifactDirective = isBrightsy ? null : formatArtifactDirective();
|
|
24026
|
+
const longRunningDirective = isBrightsy || isOrchestration ? null : formatLongRunningDirective();
|
|
24027
|
+
const optionalServicesDirective = isBrightsy || isOrchestration ? null : formatOptionalServicesDirective(loadAppSettings().integrations);
|
|
24028
|
+
const freshIssueTicket = issueTicketFromThread(fresh, resolveEffectiveIssueSource());
|
|
24029
|
+
const issueToolsDirective = isBrightsy || isOrchestration ? null : formatIssueToolsDirective({
|
|
24030
|
+
linear: isLinearConnected(),
|
|
24031
|
+
abletime: isAbleTimeConnected(),
|
|
24032
|
+
github: true,
|
|
24033
|
+
ticketId: freshIssueTicket?.id,
|
|
24034
|
+
ticketProvider: freshIssueTicket?.provider
|
|
24035
|
+
});
|
|
24036
|
+
const reviewWriteGateDirective = isBrightsy || isOrchestration || !isReviewWriteGatedThread(
|
|
24037
|
+
fresh,
|
|
24038
|
+
fresh.worktreePath ? threadsSharingWorktree(fresh.worktreePath) : []
|
|
24039
|
+
) ? null : formatReviewWriteGateDirective();
|
|
24040
|
+
let viewerContextDirective = null;
|
|
24041
|
+
if (!isBrightsy && !isOrchestration) {
|
|
24042
|
+
try {
|
|
24043
|
+
viewerContextDirective = formatViewerContextDirective(
|
|
24044
|
+
resolveViewerProfileForRepo(fresh.repoPath || fresh.worktreePath)
|
|
24045
|
+
);
|
|
24046
|
+
} catch {
|
|
24047
|
+
viewerContextDirective = formatViewerContextDirective(
|
|
24048
|
+
resolveViewerProfileForRepo()
|
|
24049
|
+
);
|
|
24050
|
+
}
|
|
23882
24051
|
}
|
|
23883
|
-
|
|
23884
|
-
|
|
23885
|
-
|
|
23886
|
-
|
|
23887
|
-
|
|
23888
|
-
|
|
23889
|
-
|
|
23890
|
-
|
|
23891
|
-
)
|
|
24052
|
+
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
24053
|
+
let renameBranchDirective = null;
|
|
24054
|
+
if (!isBrightsy && !isOrchestration && autoRenameBranchEnabled2()) {
|
|
24055
|
+
const { resolveGitBranchPrefix: resolveGitBranchPrefix2 } = await Promise.resolve().then(() => (init_branch_prefix(), branch_prefix_exports));
|
|
24056
|
+
renameBranchDirective = formatRenameBranchDirective(fresh, {
|
|
24057
|
+
customPrompt: settings?.prompts?.renameBranch,
|
|
24058
|
+
branchPrefix: resolveGitBranchPrefix2({
|
|
24059
|
+
setting: gitBranchPrefixSetting2()
|
|
24060
|
+
})
|
|
23892
24061
|
});
|
|
23893
24062
|
}
|
|
23894
|
-
|
|
23895
|
-
|
|
23896
|
-
|
|
23897
|
-
|
|
23898
|
-
|
|
23899
|
-
|
|
23900
|
-
|
|
23901
|
-
|
|
23902
|
-
|
|
23903
|
-
|
|
23904
|
-
|
|
23905
|
-
|
|
23906
|
-
|
|
23907
|
-
|
|
24063
|
+
let seed = null;
|
|
24064
|
+
if (!fresh.sessionId) {
|
|
24065
|
+
const prior = fresh.messages.slice(0, -1);
|
|
24066
|
+
seed = isBrightsy ? buildBrightsySessionSeed(prior) : buildSessionSeed(prior);
|
|
24067
|
+
}
|
|
24068
|
+
let coordinatorDirective = null;
|
|
24069
|
+
if (isOrchestration) {
|
|
24070
|
+
if (isGlobalThread(fresh)) {
|
|
24071
|
+
ensureGlobalCoordinatorCwd({ orchestratorThreadId: fresh.id });
|
|
24072
|
+
}
|
|
24073
|
+
if (!fresh.sessionId) {
|
|
24074
|
+
const inventory = await enrichWorkspacesWithGithub(this.listWorkspaces());
|
|
24075
|
+
coordinatorDirective = coordinatorSystemPrompt({
|
|
24076
|
+
goal: fresh.sourceRef || fresh.title || "Orchestration",
|
|
24077
|
+
parentId: fresh.id,
|
|
24078
|
+
workspaces: inventory,
|
|
24079
|
+
audience: /^(Slack DM|Slack @mention)(?:\n|$)/.test(
|
|
24080
|
+
expandedPrompt.trim()
|
|
24081
|
+
) ? "slack" : "desktop"
|
|
24082
|
+
});
|
|
24083
|
+
}
|
|
24084
|
+
}
|
|
24085
|
+
const cachedPrefix = fresh.sessionId ? "" : [
|
|
24086
|
+
coordinatorDirective,
|
|
24087
|
+
worktreeDirective,
|
|
24088
|
+
optionalServicesDirective,
|
|
24089
|
+
issueToolsDirective,
|
|
24090
|
+
reviewWriteGateDirective,
|
|
24091
|
+
viewerContextDirective,
|
|
24092
|
+
artifactDirective,
|
|
24093
|
+
longRunningDirective,
|
|
24094
|
+
renameBranchDirective,
|
|
24095
|
+
seed
|
|
24096
|
+
].filter(Boolean).join("\n\n---\n\n");
|
|
23908
24097
|
const stderrTail = [];
|
|
24098
|
+
traceTurn("runTurn.beforeSpawn", { threadId, agent: fresh.agent });
|
|
23909
24099
|
const handle = await spawnAgentTurn(
|
|
23910
24100
|
fresh,
|
|
23911
24101
|
{
|
|
@@ -24705,6 +24895,18 @@ var init_orchestrator = __esm({
|
|
|
24705
24895
|
const thread = this.requireThread(threadRef);
|
|
24706
24896
|
return listWorktreeFiles(thread.worktreePath);
|
|
24707
24897
|
}
|
|
24898
|
+
async statPath(threadRef, relativePath) {
|
|
24899
|
+
const thread = this.requireThread(threadRef);
|
|
24900
|
+
if (relativePath.includes("..") || relativePath.startsWith("/")) {
|
|
24901
|
+
return "missing";
|
|
24902
|
+
}
|
|
24903
|
+
if (!relativePath || relativePath === ".") return "dir";
|
|
24904
|
+
try {
|
|
24905
|
+
return statWorktreePath(thread.worktreePath, relativePath);
|
|
24906
|
+
} catch {
|
|
24907
|
+
return "missing";
|
|
24908
|
+
}
|
|
24909
|
+
}
|
|
24708
24910
|
async readFile(threadRef, relativePath) {
|
|
24709
24911
|
const thread = this.requireThread(threadRef);
|
|
24710
24912
|
if (relativePath.includes("..") || relativePath.startsWith("/")) {
|
|
@@ -25187,7 +25389,7 @@ var init_orchestrator = __esm({
|
|
|
25187
25389
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
25188
25390
|
return restored2;
|
|
25189
25391
|
}
|
|
25190
|
-
if (!(0,
|
|
25392
|
+
if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
|
|
25191
25393
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
25192
25394
|
throw new Error(
|
|
25193
25395
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -25967,6 +26169,7 @@ __export(index_exports, {
|
|
|
25967
26169
|
maxConcurrentAgents: () => maxConcurrentAgents,
|
|
25968
26170
|
maybeCompactContext: () => maybeCompactContext,
|
|
25969
26171
|
mcpAllowTools: () => mcpAllowTools,
|
|
26172
|
+
mcpAllowToolsFromNames: () => mcpAllowToolsFromNames,
|
|
25970
26173
|
mcpAuthWarnings: () => mcpAuthWarnings,
|
|
25971
26174
|
mcpStatusThinkingFromClaudeInit: () => mcpStatusThinkingFromClaudeInit,
|
|
25972
26175
|
mentionsPrGoal: () => mentionsPrGoal,
|
|
@@ -26179,6 +26382,7 @@ __export(index_exports, {
|
|
|
26179
26382
|
startOrchestration: () => startOrchestration,
|
|
26180
26383
|
startSlackOAuth: () => startSlackOAuth,
|
|
26181
26384
|
startSlackRelayServer: () => startSlackRelayServer,
|
|
26385
|
+
statWorktreePath: () => statWorktreePath,
|
|
26182
26386
|
stripBrightsyNdjsonNoise: () => stripBrightsyNdjsonNoise,
|
|
26183
26387
|
stripNestedElectronEnv: () => stripNestedElectronEnv,
|
|
26184
26388
|
submitPrStack: () => submitPrStack,
|
|
@@ -28681,7 +28885,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
28681
28885
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
28682
28886
|
var import_zod9 = require("zod");
|
|
28683
28887
|
var import_node_crypto15 = require("crypto");
|
|
28684
|
-
var
|
|
28888
|
+
var import_node_path55 = require("path");
|
|
28685
28889
|
init_orchestrator();
|
|
28686
28890
|
init_worktree();
|
|
28687
28891
|
init_global_workspace();
|
|
@@ -30401,27 +30605,27 @@ init_gh_errors();
|
|
|
30401
30605
|
init_git_auth_mode();
|
|
30402
30606
|
|
|
30403
30607
|
// src/board/load-home-board.ts
|
|
30404
|
-
var
|
|
30405
|
-
var
|
|
30608
|
+
var import_node_fs57 = require("fs");
|
|
30609
|
+
var import_node_path54 = require("path");
|
|
30406
30610
|
init_worktree();
|
|
30407
30611
|
init_paths();
|
|
30408
30612
|
|
|
30409
30613
|
// src/board/board-pins.ts
|
|
30410
30614
|
var import_node_crypto14 = require("crypto");
|
|
30411
|
-
var
|
|
30412
|
-
var
|
|
30615
|
+
var import_node_fs56 = require("fs");
|
|
30616
|
+
var import_node_path53 = require("path");
|
|
30413
30617
|
init_paths();
|
|
30414
30618
|
init_home_board();
|
|
30415
30619
|
var FILE = "home-board-pins.json";
|
|
30416
30620
|
var VERSION = 1;
|
|
30417
30621
|
function pinsFile() {
|
|
30418
|
-
return (0,
|
|
30622
|
+
return (0, import_node_path53.join)(appDataDir(), FILE);
|
|
30419
30623
|
}
|
|
30420
30624
|
function readDisk() {
|
|
30421
30625
|
const path2 = pinsFile();
|
|
30422
|
-
if (!(0,
|
|
30626
|
+
if (!(0, import_node_fs56.existsSync)(path2)) return [];
|
|
30423
30627
|
try {
|
|
30424
|
-
const raw = JSON.parse((0,
|
|
30628
|
+
const raw = JSON.parse((0, import_node_fs56.readFileSync)(path2, "utf8"));
|
|
30425
30629
|
if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
|
|
30426
30630
|
return raw.items.filter((item) => item?.id && item.kind && item.ref);
|
|
30427
30631
|
} catch {
|
|
@@ -30429,8 +30633,8 @@ function readDisk() {
|
|
|
30429
30633
|
}
|
|
30430
30634
|
}
|
|
30431
30635
|
function writeDisk(items) {
|
|
30432
|
-
(0,
|
|
30433
|
-
(0,
|
|
30636
|
+
(0, import_node_fs56.mkdirSync)(appDataDir(), { recursive: true });
|
|
30637
|
+
(0, import_node_fs56.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
|
|
30434
30638
|
}
|
|
30435
30639
|
function listBoardPins() {
|
|
30436
30640
|
return readDisk();
|
|
@@ -30482,7 +30686,7 @@ function replaceBoardPins(items) {
|
|
|
30482
30686
|
}
|
|
30483
30687
|
function clearBoardPins() {
|
|
30484
30688
|
try {
|
|
30485
|
-
(0,
|
|
30689
|
+
(0, import_node_fs56.unlinkSync)(pinsFile());
|
|
30486
30690
|
} catch {
|
|
30487
30691
|
}
|
|
30488
30692
|
}
|
|
@@ -30499,7 +30703,7 @@ function homeBoardWorkspaceKey(workspaces) {
|
|
|
30499
30703
|
return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
|
|
30500
30704
|
}
|
|
30501
30705
|
function cacheFile() {
|
|
30502
|
-
return (0,
|
|
30706
|
+
return (0, import_node_path54.join)(appDataDir(), "home-board-cache.json");
|
|
30503
30707
|
}
|
|
30504
30708
|
function emptyInputs() {
|
|
30505
30709
|
return {
|
|
@@ -30525,9 +30729,9 @@ function shouldCacheHomeBoardInputs(inputs) {
|
|
|
30525
30729
|
}
|
|
30526
30730
|
function readDiskCache() {
|
|
30527
30731
|
const path2 = cacheFile();
|
|
30528
|
-
if (!(0,
|
|
30732
|
+
if (!(0, import_node_fs57.existsSync)(path2)) return null;
|
|
30529
30733
|
try {
|
|
30530
|
-
const raw = JSON.parse((0,
|
|
30734
|
+
const raw = JSON.parse((0, import_node_fs57.readFileSync)(path2, "utf8"));
|
|
30531
30735
|
if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
|
|
30532
30736
|
return null;
|
|
30533
30737
|
}
|
|
@@ -30541,14 +30745,14 @@ function readDiskCache() {
|
|
|
30541
30745
|
}
|
|
30542
30746
|
function writeDiskCache(entry) {
|
|
30543
30747
|
try {
|
|
30544
|
-
(0,
|
|
30545
|
-
(0,
|
|
30748
|
+
(0, import_node_fs57.mkdirSync)(appDataDir(), { recursive: true });
|
|
30749
|
+
(0, import_node_fs57.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
|
|
30546
30750
|
} catch {
|
|
30547
30751
|
}
|
|
30548
30752
|
}
|
|
30549
30753
|
function deleteDiskCache() {
|
|
30550
30754
|
try {
|
|
30551
|
-
(0,
|
|
30755
|
+
(0, import_node_fs57.unlinkSync)(cacheFile());
|
|
30552
30756
|
} catch {
|
|
30553
30757
|
}
|
|
30554
30758
|
}
|
|
@@ -30734,7 +30938,7 @@ function orchCreateThreadAgentNote(input) {
|
|
|
30734
30938
|
// src/mcp/server.ts
|
|
30735
30939
|
var MAX_ORCH_THREADS = 5;
|
|
30736
30940
|
var CREATE_THREAD_TIMEOUT_MS = 9e4;
|
|
30737
|
-
function
|
|
30941
|
+
function withTimeout2(promise, ms, label) {
|
|
30738
30942
|
return new Promise((resolve, reject) => {
|
|
30739
30943
|
const timer = setTimeout(() => {
|
|
30740
30944
|
reject(new Error(`${label} timed out after ${Math.round(ms / 1e3)}s`));
|
|
@@ -30788,7 +30992,7 @@ async function createOrchChildThread(orch, args, resolveNewThreadOptions2) {
|
|
|
30788
30992
|
const agentNote = orchCreateThreadAgentNote(opts);
|
|
30789
30993
|
try {
|
|
30790
30994
|
const priorIds = new Set(orch.getThreads(false).map((t) => t.id));
|
|
30791
|
-
const thread = await
|
|
30995
|
+
const thread = await withTimeout2(
|
|
30792
30996
|
orch.createThread({
|
|
30793
30997
|
sourceType: args.sourceType,
|
|
30794
30998
|
sourceRef: args.sourceRef,
|
|
@@ -30898,7 +31102,7 @@ async function startMcpServer() {
|
|
|
30898
31102
|
async () => {
|
|
30899
31103
|
const threads = orch.getThreads(true);
|
|
30900
31104
|
const lines = threads.map((t) => {
|
|
30901
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0,
|
|
31105
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0, import_node_path55.basename)(t.repoPath) || t.repoPath;
|
|
30902
31106
|
const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
|
|
30903
31107
|
const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
|
|
30904
31108
|
const preview = lastMessagePreview(t.messages, 80);
|
|
@@ -33865,9 +34069,9 @@ var import_node_http4 = require("http");
|
|
|
33865
34069
|
var import_ws3 = require("ws");
|
|
33866
34070
|
|
|
33867
34071
|
// src/slack/relay-static.ts
|
|
33868
|
-
var
|
|
34072
|
+
var import_node_fs58 = require("fs");
|
|
33869
34073
|
var import_promises = require("fs/promises");
|
|
33870
|
-
var
|
|
34074
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
33871
34075
|
var TYPES = {
|
|
33872
34076
|
".css": "text/css; charset=utf-8",
|
|
33873
34077
|
".html": "text/html; charset=utf-8",
|
|
@@ -33898,9 +34102,9 @@ function resolveStaticPath(root, requestUrl) {
|
|
|
33898
34102
|
return null;
|
|
33899
34103
|
}
|
|
33900
34104
|
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
33901
|
-
const rootResolved =
|
|
33902
|
-
const candidate =
|
|
33903
|
-
if (candidate !== rootResolved && !candidate.startsWith(rootResolved +
|
|
34105
|
+
const rootResolved = import_node_path56.default.resolve(root);
|
|
34106
|
+
const candidate = import_node_path56.default.resolve(rootResolved, `.${pathname}`);
|
|
34107
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path56.default.sep)) {
|
|
33904
34108
|
return null;
|
|
33905
34109
|
}
|
|
33906
34110
|
return candidate;
|
|
@@ -33914,7 +34118,7 @@ async function fileSize(file) {
|
|
|
33914
34118
|
}
|
|
33915
34119
|
}
|
|
33916
34120
|
function sendFile(req, res, file, size) {
|
|
33917
|
-
const ext =
|
|
34121
|
+
const ext = import_node_path56.default.extname(file).toLowerCase();
|
|
33918
34122
|
res.writeHead(200, {
|
|
33919
34123
|
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
33920
34124
|
"Content-Length": size,
|
|
@@ -33924,7 +34128,7 @@ function sendFile(req, res, file, size) {
|
|
|
33924
34128
|
res.end();
|
|
33925
34129
|
return true;
|
|
33926
34130
|
}
|
|
33927
|
-
(0,
|
|
34131
|
+
(0, import_node_fs58.createReadStream)(file).pipe(res);
|
|
33928
34132
|
return true;
|
|
33929
34133
|
}
|
|
33930
34134
|
async function tryServeStatic(req, res, root) {
|
|
@@ -33933,7 +34137,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
33933
34137
|
if (!candidate) return false;
|
|
33934
34138
|
const direct = await fileSize(candidate);
|
|
33935
34139
|
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
33936
|
-
const asIndex =
|
|
34140
|
+
const asIndex = import_node_path56.default.join(candidate, "index.html");
|
|
33937
34141
|
const indexSize = await fileSize(asIndex);
|
|
33938
34142
|
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
33939
34143
|
return false;
|
|
@@ -34756,6 +34960,7 @@ init_outbound_watch();
|
|
|
34756
34960
|
maxConcurrentAgents,
|
|
34757
34961
|
maybeCompactContext,
|
|
34758
34962
|
mcpAllowTools,
|
|
34963
|
+
mcpAllowToolsFromNames,
|
|
34759
34964
|
mcpAuthWarnings,
|
|
34760
34965
|
mcpStatusThinkingFromClaudeInit,
|
|
34761
34966
|
mentionsPrGoal,
|
|
@@ -34968,6 +35173,7 @@ init_outbound_watch();
|
|
|
34968
35173
|
startOrchestration,
|
|
34969
35174
|
startSlackOAuth,
|
|
34970
35175
|
startSlackRelayServer,
|
|
35176
|
+
statWorktreePath,
|
|
34971
35177
|
stripBrightsyNdjsonNoise,
|
|
34972
35178
|
stripNestedElectronEnv,
|
|
34973
35179
|
submitPrStack,
|