@sideboard-ai/core 0.1.99 → 0.1.103
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/cursor-runner.cjs +22 -22
- package/dist/agents/cursor-runner.js +2 -2
- package/dist/{agents-ESJKIQQA.js → agents-UT5GCJH3.js} +8 -8
- package/dist/{agents-3MWWWSMF.js → agents-XZBAKBO2.js} +9 -9
- package/dist/{app-settings-BRF7VKTQ.js → app-settings-EKJM2344.js} +2 -2
- package/dist/{app-settings-ZXPAB3QN.js → app-settings-VDJK2BZ2.js} +2 -2
- package/dist/{caffeinate-hold-U3QJBV67.js → caffeinate-hold-NBRUWYXO.js} +2 -2
- package/dist/{caffeinate-hold-I7SG6UQR.js → caffeinate-hold-X3JNPR42.js} +2 -2
- package/dist/{chunk-UYQYK2RY.js → chunk-27MCESES.js} +3 -3
- package/dist/{chunk-QSLE4VEM.js → chunk-2GO3YKBA.js} +4 -4
- package/dist/{chunk-DKHGWYWR.js → chunk-7YKXHBIW.js} +1 -1
- package/dist/{chunk-JL4SJ6V7.js → chunk-BD2ICC4D.js} +4 -0
- package/dist/{chunk-NZPGMNFC.js → chunk-DCOZABNT.js} +1 -1
- package/dist/{chunk-CIRXAYWS.js → chunk-DHAGMJIK.js} +55 -28
- package/dist/{chunk-XUWDLRAE.js → chunk-ETMRBJKA.js} +11 -11
- package/dist/{chunk-MBP3XG57.js → chunk-H6LP57EF.js} +7 -7
- package/dist/{chunk-FO67IJTY.js → chunk-HHLZWO7U.js} +5 -5
- package/dist/{chunk-GXSYI7FH.js → chunk-HUKCGRAT.js} +209 -59
- package/dist/{chunk-3WA37BRI.js → chunk-KGSVLZV6.js} +11 -4
- package/dist/{chunk-7KDBDMNC.js → chunk-KLBOWJ74.js} +1 -1
- package/dist/{chunk-FYS2BULQ.js → chunk-LANDJIAI.js} +213 -63
- package/dist/{chunk-OANJQTVG.js → chunk-ND6AO7C5.js} +3 -3
- package/dist/{chunk-HI2OTFFR.js → chunk-OW34MVDN.js} +5 -5
- package/dist/{chunk-JOF3XIEM.js → chunk-P3BQ5DOL.js} +11 -4
- package/dist/{chunk-B4R2VB2A.js → chunk-QZQEXME2.js} +4 -0
- package/dist/{chunk-R7BQBSDT.js → chunk-WA3DVVWG.js} +55 -28
- package/dist/{chunk-6LFV4VFI.js → chunk-WSYCND2U.js} +1 -1
- package/dist/{chunk-FT2SQOL4.js → chunk-XHZJJWLI.js} +1 -1
- package/dist/{chunk-XH2GS2LO.js → chunk-YJADJH5U.js} +11 -11
- package/dist/{connected-teams-SWHJWK2A.js → connected-teams-J4I5AKMR.js} +2 -2
- package/dist/{connected-teams-TLVKZPJP.js → connected-teams-M5XNXRI5.js} +2 -2
- package/dist/{coordinator-prompt-OQOOD5ET.js → coordinator-prompt-3DFZRMXE.js} +5 -5
- package/dist/{coordinator-prompt-AKEY4WSO.js → coordinator-prompt-UWHSD65V.js} +5 -5
- package/dist/{cursor-recover-S5ORPW34.js → cursor-recover-JBTIDARH.js} +1 -1
- package/dist/{cursor-recover-G34BYKL2.js → cursor-recover-ZUJG6XRQ.js} +1 -1
- package/dist/{global-workspace-WMF3BJP5.js → global-workspace-KJQS5S2C.js} +6 -6
- package/dist/{global-workspace-RSQXRLT7.js → global-workspace-UR4E3CCG.js} +6 -6
- package/dist/index.cjs +851 -232
- package/dist/index.d.cts +39 -6
- package/dist/index.d.ts +39 -6
- package/dist/index.js +561 -138
- package/dist/mcp/run-stdio.cjs +651 -256
- package/dist/mcp/run-stdio.js +345 -143
- package/dist/{paths-TZX4L5X7.js → paths-QCI3MTO5.js} +3 -1
- package/dist/{paths-JQM2XRAD.js → paths-UMEDHOS5.js} +3 -1
- package/dist/{thread-store-XAKWCV2E.js → thread-store-4OUEQ2DB.js} +2 -2
- package/dist/{thread-store-V7NOOXKE.js → thread-store-DQJGDKIJ.js} +2 -2
- package/dist/{workspaces-MZVQHRSJ.js → workspaces-NTIVI6DI.js} +7 -7
- package/dist/{workspaces-4ZY4QPWQ.js → workspaces-TKJXPNV4.js} +7 -7
- package/dist/{worktree-EO5QAGJU.js → worktree-NKWN5ZTS.js} +4 -4
- package/dist/{worktree-DA4BOV7G.js → worktree-PEUPFAKL.js} +4 -4
- package/package.json +2 -2
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
ensureCliTeamTracked,
|
|
7
7
|
ensureConnectedBrightsyTeamTokens,
|
|
8
8
|
loadBrightsyConfig
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-7YKXHBIW.js";
|
|
10
10
|
import {
|
|
11
11
|
isOrchestratorThread
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-OW34MVDN.js";
|
|
13
13
|
import {
|
|
14
14
|
codexUnattendedGitConfigArgs,
|
|
15
15
|
mergeAgentGitAuthEnv,
|
|
16
16
|
resolveAgentGitAuthEnv,
|
|
17
17
|
resolveCodexGitWritableRoots
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-WA3DVVWG.js";
|
|
19
19
|
import {
|
|
20
20
|
claudeChromeEnabled,
|
|
21
21
|
isElectronLikeCommand,
|
|
@@ -24,10 +24,10 @@ import {
|
|
|
24
24
|
resolveClaudeExecutable,
|
|
25
25
|
unwrapStrippedElectronLaunch,
|
|
26
26
|
wrapElectronAsNodeLaunch
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-WSYCND2U.js";
|
|
28
28
|
import {
|
|
29
29
|
appDataDir
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-BD2ICC4D.js";
|
|
31
31
|
import {
|
|
32
32
|
enrichPathWithNpmGlobalBin,
|
|
33
33
|
isConductorBundledCli,
|
|
@@ -178,7 +178,15 @@ function looksLikeMinifiedJsDump(line) {
|
|
|
178
178
|
function looksLikeNestedElectronCrash(line) {
|
|
179
179
|
return /HasCustomHostObject|ElectronInitializeICUandStartNode/i.test(line);
|
|
180
180
|
}
|
|
181
|
+
function looksLikeHomebrewLibuvCrash(line) {
|
|
182
|
+
const uvRun = /uv_run/i.test(line);
|
|
183
|
+
const spin = /SpinEventLoopInternal/i.test(line);
|
|
184
|
+
const homebrewUv = /Cellar\/libuv|libuv\.\d\.dylib/i.test(line);
|
|
185
|
+
const homebrewNode = /Cellar\/node\//i.test(line);
|
|
186
|
+
return uvRun && (homebrewUv || spin || homebrewNode) || spin && (homebrewUv || homebrewNode);
|
|
187
|
+
}
|
|
181
188
|
var NESTED_ELECTRON_SUMMARY = "Cursor local agent crashed at Electron startup (nested Chromium / HasCustomHostObject)";
|
|
189
|
+
var HOMEBREW_LIBUV_SUMMARY = "Cursor runner crashed in Node (Homebrew Node + shared libuv). Install Node 22 LTS (`brew install node@22`) and retry.";
|
|
182
190
|
var MINIFIED_DUMP_SUMMARY = "Cursor local agent crashed during startup (truncated crash dump)";
|
|
183
191
|
function clipStderr(text, maxChars) {
|
|
184
192
|
const trimmed = text.trim();
|
|
@@ -190,6 +198,7 @@ function summarizeTurnStderr(tail, maxChars = 500) {
|
|
|
190
198
|
const cursorStartup = [...tail].reverse().find((line) => /cursor startup failed:/i.test(line));
|
|
191
199
|
if (cursorStartup) return clipStderr(cursorStartup, maxChars);
|
|
192
200
|
if (tail.some(looksLikeNestedElectronCrash)) return NESTED_ELECTRON_SUMMARY;
|
|
201
|
+
if (tail.some(looksLikeHomebrewLibuvCrash)) return HOMEBREW_LIBUV_SUMMARY;
|
|
193
202
|
if (tail.some(
|
|
194
203
|
(line) => /\[resource_exhausted\]|resource_exhausted/i.test(line) || /findFilesWithRipgrep/.test(line)
|
|
195
204
|
)) {
|
|
@@ -212,6 +221,20 @@ function looksLikeInvalidAgentSession(text) {
|
|
|
212
221
|
if (!lower) return false;
|
|
213
222
|
return /session not found/.test(lower) || /no conversation found/.test(lower) || /conversation .+ not found/.test(lower) || /thread .+ not found/.test(lower) || /unknown session/.test(lower) || /invalid session/.test(lower) || /session .+ (missing|expired|deleted|gone)/.test(lower) || /cannot resume/.test(lower) || /failed to (load|resume|open) session/.test(lower) || /corrupt local agent checkpoint/.test(lower) || /missing root blob/.test(lower) || /\bagent\b.{0,120}\bnot found\b/.test(lower);
|
|
214
223
|
}
|
|
224
|
+
function looksLikeRetryableRunnerCrash(text) {
|
|
225
|
+
if (looksLikeAgentFailureMessage(text)) return false;
|
|
226
|
+
if (looksLikeInvalidAgentSession(text)) return false;
|
|
227
|
+
const lower = text.trim().toLowerCase();
|
|
228
|
+
if (/cannot find (?:package|module)|err_module_not_found/.test(lower)) return false;
|
|
229
|
+
if (!lower) return true;
|
|
230
|
+
return /uv_run|spineventloopinternal|libuv|homebrew node \+ shared libuv|hascustomhostobject|electroninitializeicuandstartnode|nested chromium|truncated crash dump|sig(?:segv|abrt|ill)|segmentation fault|illegal instruction|fatal error/.test(
|
|
231
|
+
lower
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
function shouldRetryFailedAgentTurn(detail, opts) {
|
|
235
|
+
if (looksLikeInvalidAgentSession(detail) && opts.hasSession) return true;
|
|
236
|
+
return looksLikeRetryableRunnerCrash(detail);
|
|
237
|
+
}
|
|
215
238
|
function looksLikeAgentFailureMessage(text) {
|
|
216
239
|
const lower = text.trim().toLowerCase();
|
|
217
240
|
if (!lower) return false;
|
|
@@ -256,11 +279,22 @@ function humanizeAgentFailDetail(detail) {
|
|
|
256
279
|
if (/hascustomhostobject|electroninitializeicuandstartnode|nested chromium/i.test(lower)) {
|
|
257
280
|
return `${raw} \u2014 retry the turn; if it keeps failing, pick another agent.`;
|
|
258
281
|
}
|
|
282
|
+
if (/homebrew node \+ shared libuv|uv_run|spineventloopinternal/i.test(lower)) {
|
|
283
|
+
return /brew install node@22/i.test(raw) ? raw : `${raw} \u2014 install Node 22 LTS (\`brew install node@22\`) and retry.`;
|
|
284
|
+
}
|
|
259
285
|
if (/corrupt local agent checkpoint|missing root blob|truncated crash dump/.test(lower)) {
|
|
260
286
|
return `${raw} \u2014 retry the turn (Sideboard will start a fresh Cursor session).`;
|
|
261
287
|
}
|
|
262
288
|
return raw;
|
|
263
289
|
}
|
|
290
|
+
function turnFailChatText(opts) {
|
|
291
|
+
const chat = opts.assistantText.trim();
|
|
292
|
+
if (chat) return chat;
|
|
293
|
+
if (opts.exitCode === 0) return "";
|
|
294
|
+
const detail = opts.detail.trim();
|
|
295
|
+
if (detail) return humanizeAgentFailDetail(detail);
|
|
296
|
+
return formatTurnExitError(opts.exitCode ?? 1, "");
|
|
297
|
+
}
|
|
264
298
|
function formatTurnExitError(exitCode, stderrSummary) {
|
|
265
299
|
const code = exitCode ?? 1;
|
|
266
300
|
const raw = stderrSummary.trim();
|
|
@@ -639,9 +673,54 @@ function sideboardMcpProfile(env = process.env) {
|
|
|
639
673
|
}
|
|
640
674
|
|
|
641
675
|
// src/agents/node-launch.ts
|
|
642
|
-
import { existsSync as
|
|
676
|
+
import { existsSync as existsSync3, readdirSync, realpathSync } from "fs";
|
|
643
677
|
import { homedir } from "os";
|
|
678
|
+
import { join as join2 } from "path";
|
|
679
|
+
|
|
680
|
+
// src/agents/packaged-runtime.ts
|
|
681
|
+
import { existsSync as existsSync2 } from "fs";
|
|
644
682
|
import { join } from "path";
|
|
683
|
+
function electronResourcesPath() {
|
|
684
|
+
const resources = process.resourcesPath;
|
|
685
|
+
if (typeof resources !== "string" || !resources) return null;
|
|
686
|
+
return resources;
|
|
687
|
+
}
|
|
688
|
+
function packagedCursorRuntimeDir() {
|
|
689
|
+
const resources = electronResourcesPath();
|
|
690
|
+
if (!resources) return null;
|
|
691
|
+
const dir = join(resources, "cursor-runtime");
|
|
692
|
+
if (!existsSync2(join(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
|
|
693
|
+
return dir;
|
|
694
|
+
}
|
|
695
|
+
function packagedCursorRunnerPath() {
|
|
696
|
+
const dir = packagedCursorRuntimeDir();
|
|
697
|
+
return dir ? join(dir, "core-dist", "agents", "cursor-runner.js") : null;
|
|
698
|
+
}
|
|
699
|
+
function packagedMcpDir() {
|
|
700
|
+
const resources = electronResourcesPath();
|
|
701
|
+
if (!resources) return null;
|
|
702
|
+
const dir = join(resources, "sideboard-mcp");
|
|
703
|
+
if (!existsSync2(join(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
|
|
704
|
+
return dir;
|
|
705
|
+
}
|
|
706
|
+
function packagedMcpStdioPath() {
|
|
707
|
+
const dir = packagedMcpDir();
|
|
708
|
+
return dir ? join(dir, "core-dist", "mcp", "run-stdio.js") : null;
|
|
709
|
+
}
|
|
710
|
+
function packagedBundledNodePath() {
|
|
711
|
+
const resources = electronResourcesPath();
|
|
712
|
+
if (!resources) return null;
|
|
713
|
+
const bin = join(resources, "node", "bin", "node");
|
|
714
|
+
if (!existsSync2(bin)) return null;
|
|
715
|
+
return bin;
|
|
716
|
+
}
|
|
717
|
+
function packagedCursorRipgrepCandidate(platformPkg, binName) {
|
|
718
|
+
const dir = packagedCursorRuntimeDir();
|
|
719
|
+
if (!dir) return null;
|
|
720
|
+
return join(dir, "node_modules", platformPkg, "bin", binName);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// src/agents/node-launch.ts
|
|
645
724
|
function isAsarPath(filePath) {
|
|
646
725
|
if (/\.asar\.unpacked([/\\]|$)/.test(filePath)) return false;
|
|
647
726
|
return /\.asar([/\\]|$)/.test(filePath);
|
|
@@ -650,28 +729,130 @@ function unpackedAsarPath(filePath) {
|
|
|
650
729
|
if (!isAsarPath(filePath)) return null;
|
|
651
730
|
const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
|
|
652
731
|
if (unpacked === filePath) return null;
|
|
653
|
-
return
|
|
732
|
+
return existsSync3(unpacked) ? unpacked : null;
|
|
654
733
|
}
|
|
655
734
|
function nodeReadableScriptPath(scriptPath) {
|
|
656
735
|
return unpackedAsarPath(scriptPath) ?? scriptPath;
|
|
657
736
|
}
|
|
658
|
-
var
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
const
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
737
|
+
var PREFERRED_LTS_MAJORS = [24, 22, 20];
|
|
738
|
+
function parseNodeMajor(version) {
|
|
739
|
+
const match = /^v?(\d+)/.exec(version.trim());
|
|
740
|
+
if (!match) return null;
|
|
741
|
+
const major = Number(match[1]);
|
|
742
|
+
return Number.isInteger(major) ? major : null;
|
|
743
|
+
}
|
|
744
|
+
function scoreNodeForAgentRuntime(candidate) {
|
|
745
|
+
const major = parseNodeMajor(candidate.version);
|
|
746
|
+
if (major == null) return Number.NEGATIVE_INFINITY;
|
|
747
|
+
if (major < 20) return major - 100;
|
|
748
|
+
const posix = candidate.path.replace(/\\/g, "/");
|
|
749
|
+
let score = 0;
|
|
750
|
+
if (major % 2 === 0) {
|
|
751
|
+
score += 1e3 + major * 10;
|
|
752
|
+
} else {
|
|
753
|
+
score += major;
|
|
754
|
+
}
|
|
755
|
+
if (/\/Cellar\/node\/\d/.test(posix) && !/\/Cellar\/node@\d+/.test(posix)) {
|
|
756
|
+
score -= 50;
|
|
757
|
+
}
|
|
758
|
+
return score;
|
|
759
|
+
}
|
|
760
|
+
function pickPreferredNode(candidates) {
|
|
761
|
+
let best = null;
|
|
762
|
+
let bestScore = Number.NEGATIVE_INFINITY;
|
|
763
|
+
for (const candidate of candidates) {
|
|
764
|
+
const score = scoreNodeForAgentRuntime(candidate);
|
|
765
|
+
if (score > bestScore) {
|
|
766
|
+
bestScore = score;
|
|
767
|
+
best = candidate;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
return best;
|
|
771
|
+
}
|
|
772
|
+
function versionDirNodeBins(root, toBin) {
|
|
773
|
+
if (!existsSync3(root)) return [];
|
|
774
|
+
try {
|
|
775
|
+
return readdirSync(root).map(toBin);
|
|
776
|
+
} catch {
|
|
777
|
+
return [];
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
function defaultNodeBinCandidates(home = homedir()) {
|
|
781
|
+
const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
|
|
782
|
+
(prefix) => PREFERRED_LTS_MAJORS.map((major) => join2(prefix, "opt", `node@${major}`, "bin", "node"))
|
|
783
|
+
);
|
|
784
|
+
return [
|
|
785
|
+
...kegs,
|
|
786
|
+
"/opt/homebrew/bin/node",
|
|
787
|
+
"/usr/local/bin/node",
|
|
788
|
+
join2(home, ".local/share/fnm/aliases/default/bin/node"),
|
|
789
|
+
join2(home, ".nvm/current/bin/node"),
|
|
790
|
+
join2(home, ".volta/bin/node"),
|
|
791
|
+
join2(home, ".asdf/shims/node"),
|
|
792
|
+
join2(home, ".local/share/mise/shims/node"),
|
|
793
|
+
...versionDirNodeBins(
|
|
794
|
+
join2(home, ".nvm", "versions", "node"),
|
|
795
|
+
(name) => join2(home, ".nvm", "versions", "node", name, "bin", "node")
|
|
796
|
+
),
|
|
797
|
+
...versionDirNodeBins(
|
|
798
|
+
join2(home, ".local/share/fnm", "node-versions"),
|
|
799
|
+
(name) => join2(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
|
|
800
|
+
),
|
|
801
|
+
...versionDirNodeBins(
|
|
802
|
+
join2(home, ".volta", "tools", "image", "node"),
|
|
803
|
+
(name) => join2(home, ".volta", "tools", "image", "node", name, "bin", "node")
|
|
804
|
+
)
|
|
670
805
|
];
|
|
671
|
-
|
|
672
|
-
|
|
806
|
+
}
|
|
807
|
+
function uniqueExistingNodeBins(paths) {
|
|
808
|
+
const seen = /* @__PURE__ */ new Set();
|
|
809
|
+
const out = [];
|
|
810
|
+
for (const raw of paths) {
|
|
811
|
+
const p = raw.trim();
|
|
812
|
+
if (!p || !existsSync3(p) || isElectronLikeCommand(p)) continue;
|
|
813
|
+
let key = p;
|
|
814
|
+
try {
|
|
815
|
+
key = realpathSync(p);
|
|
816
|
+
} catch {
|
|
817
|
+
continue;
|
|
818
|
+
}
|
|
819
|
+
if (seen.has(key)) continue;
|
|
820
|
+
seen.add(key);
|
|
821
|
+
out.push(p);
|
|
673
822
|
}
|
|
674
|
-
return
|
|
823
|
+
return out;
|
|
824
|
+
}
|
|
825
|
+
async function whichAllNode() {
|
|
826
|
+
if (process.platform === "win32") {
|
|
827
|
+
const located = await run("where", ["node"], { reject: false, timeoutMs: 5e3 });
|
|
828
|
+
if (located.exitCode !== 0) return [];
|
|
829
|
+
return located.stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
830
|
+
}
|
|
831
|
+
const all = await run("which", ["-a", "node"], { reject: false, timeoutMs: 5e3 });
|
|
832
|
+
if (all.exitCode === 0 && all.stdout.trim()) {
|
|
833
|
+
return all.stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
834
|
+
}
|
|
835
|
+
const single = await run("which", ["node"], { reject: false, timeoutMs: 5e3 });
|
|
836
|
+
if (single.exitCode !== 0 || !single.stdout.trim()) return [];
|
|
837
|
+
return [single.stdout.trim()];
|
|
838
|
+
}
|
|
839
|
+
async function probeNodeVersion(bin) {
|
|
840
|
+
const probed = await run(bin, ["-v"], { reject: false, timeoutMs: 4e3 });
|
|
841
|
+
if (probed.exitCode !== 0) return null;
|
|
842
|
+
const version = probed.stdout.trim().split(/\r?\n/).find(Boolean);
|
|
843
|
+
return version || null;
|
|
844
|
+
}
|
|
845
|
+
async function findSystemNode() {
|
|
846
|
+
const fromPath = await whichAllNode();
|
|
847
|
+
const bins = uniqueExistingNodeBins([...fromPath, ...defaultNodeBinCandidates()]);
|
|
848
|
+
if (bins.length === 0) return null;
|
|
849
|
+
const probed = await Promise.all(
|
|
850
|
+
bins.map(async (path) => {
|
|
851
|
+
const version = await probeNodeVersion(path);
|
|
852
|
+
return version ? { path, version } : null;
|
|
853
|
+
})
|
|
854
|
+
);
|
|
855
|
+
return pickPreferredNode(probed.filter((c) => c != null));
|
|
675
856
|
}
|
|
676
857
|
function applyNodeLaunch(launch, args) {
|
|
677
858
|
const readableArgs = args.map(nodeReadableScriptPath);
|
|
@@ -689,9 +870,13 @@ function applyNodeLaunch(launch, args) {
|
|
|
689
870
|
async function resolveNodeLaunch(scriptPath) {
|
|
690
871
|
const script = nodeReadableScriptPath(scriptPath);
|
|
691
872
|
if (!isAsarPath(script)) {
|
|
692
|
-
const
|
|
693
|
-
if (
|
|
694
|
-
return { file:
|
|
873
|
+
const bundled = packagedBundledNodePath();
|
|
874
|
+
if (bundled && !isElectronLikeCommand(bundled)) {
|
|
875
|
+
return { file: bundled, env: {} };
|
|
876
|
+
}
|
|
877
|
+
const node = await findSystemNode();
|
|
878
|
+
if (node) {
|
|
879
|
+
return { file: node.path, env: {}, nodeVersion: node.version };
|
|
695
880
|
}
|
|
696
881
|
}
|
|
697
882
|
return {
|
|
@@ -700,42 +885,6 @@ async function resolveNodeLaunch(scriptPath) {
|
|
|
700
885
|
};
|
|
701
886
|
}
|
|
702
887
|
|
|
703
|
-
// src/agents/packaged-runtime.ts
|
|
704
|
-
import { existsSync as existsSync3 } from "fs";
|
|
705
|
-
import { join as join2 } from "path";
|
|
706
|
-
function electronResourcesPath() {
|
|
707
|
-
const resources = process.resourcesPath;
|
|
708
|
-
if (typeof resources !== "string" || !resources) return null;
|
|
709
|
-
return resources;
|
|
710
|
-
}
|
|
711
|
-
function packagedCursorRuntimeDir() {
|
|
712
|
-
const resources = electronResourcesPath();
|
|
713
|
-
if (!resources) return null;
|
|
714
|
-
const dir = join2(resources, "cursor-runtime");
|
|
715
|
-
if (!existsSync3(join2(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
|
|
716
|
-
return dir;
|
|
717
|
-
}
|
|
718
|
-
function packagedCursorRunnerPath() {
|
|
719
|
-
const dir = packagedCursorRuntimeDir();
|
|
720
|
-
return dir ? join2(dir, "core-dist", "agents", "cursor-runner.js") : null;
|
|
721
|
-
}
|
|
722
|
-
function packagedMcpDir() {
|
|
723
|
-
const resources = electronResourcesPath();
|
|
724
|
-
if (!resources) return null;
|
|
725
|
-
const dir = join2(resources, "sideboard-mcp");
|
|
726
|
-
if (!existsSync3(join2(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
|
|
727
|
-
return dir;
|
|
728
|
-
}
|
|
729
|
-
function packagedMcpStdioPath() {
|
|
730
|
-
const dir = packagedMcpDir();
|
|
731
|
-
return dir ? join2(dir, "core-dist", "mcp", "run-stdio.js") : null;
|
|
732
|
-
}
|
|
733
|
-
function packagedCursorRipgrepCandidate(platformPkg, binName) {
|
|
734
|
-
const dir = packagedCursorRuntimeDir();
|
|
735
|
-
if (!dir) return null;
|
|
736
|
-
return join2(dir, "node_modules", platformPkg, "bin", binName);
|
|
737
|
-
}
|
|
738
|
-
|
|
739
888
|
// src/agents/injected-mcp.ts
|
|
740
889
|
var SIDEBOARD_MCP_ALLOWED_TOOLS = [
|
|
741
890
|
"mcp__sideboard",
|
|
@@ -1208,7 +1357,7 @@ var claudeAdapter = {
|
|
|
1208
1357
|
);
|
|
1209
1358
|
}
|
|
1210
1359
|
const mode = permissionMode(thread);
|
|
1211
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
1360
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-KJQS5S2C.js");
|
|
1212
1361
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
1213
1362
|
const injectedServers = await buildInjectedMcpServers({
|
|
1214
1363
|
includeSideboard: true,
|
|
@@ -2841,9 +2990,10 @@ export {
|
|
|
2841
2990
|
pushTurnStderr,
|
|
2842
2991
|
summarizeTurnStderr,
|
|
2843
2992
|
looksLikeInvalidAgentSession,
|
|
2993
|
+
shouldRetryFailedAgentTurn,
|
|
2844
2994
|
looksLikeAgentFailureMessage,
|
|
2845
2995
|
fallbackTurnFailDetail,
|
|
2846
|
-
|
|
2996
|
+
turnFailChatText,
|
|
2847
2997
|
formatTurnExitError,
|
|
2848
2998
|
applyTurnUsage,
|
|
2849
2999
|
encodeBrightsyTarget,
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
isGlobalRepoPath
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OW34MVDN.js";
|
|
6
6
|
import {
|
|
7
7
|
ensureGhPreferOrigin,
|
|
8
8
|
resolveRepoRoot
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-WA3DVVWG.js";
|
|
10
10
|
import {
|
|
11
11
|
appDataDir
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-BD2ICC4D.js";
|
|
13
13
|
|
|
14
14
|
// src/store/workspaces.ts
|
|
15
15
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -2,25 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
ensureGlobalCoordinatorCwd
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-YJADJH5U.js";
|
|
6
6
|
import {
|
|
7
7
|
allocateTeamName,
|
|
8
8
|
takenSlugsFromThread,
|
|
9
9
|
teamSlugFromName
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-WA3DVVWG.js";
|
|
11
11
|
import {
|
|
12
12
|
createEmptyThread,
|
|
13
13
|
listThreads,
|
|
14
14
|
updateThread,
|
|
15
15
|
writeThread
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-P3BQ5DOL.js";
|
|
17
17
|
import {
|
|
18
18
|
resolveNewThreadOptions,
|
|
19
19
|
resolveThreadDefaults
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-WSYCND2U.js";
|
|
21
21
|
import {
|
|
22
22
|
globalAgentCwd
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-BD2ICC4D.js";
|
|
24
24
|
|
|
25
25
|
// src/brightsy/cloud-connect-constants.ts
|
|
26
26
|
var CLOUD_ORCHESTRATOR_GOAL = "Cloud-connected Sideboard orchestrator";
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
threadFilePath,
|
|
8
8
|
threadLockPath,
|
|
9
9
|
threadsDir
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-BD2ICC4D.js";
|
|
11
11
|
|
|
12
12
|
// src/store/thread-store.ts
|
|
13
13
|
import { randomUUID } from "crypto";
|
|
@@ -119,8 +119,11 @@ function writeThread(thread) {
|
|
|
119
119
|
function idPath(id) {
|
|
120
120
|
return id;
|
|
121
121
|
}
|
|
122
|
+
function isThreadRecordFile(name) {
|
|
123
|
+
return name.endsWith(".json") && !name.endsWith(".live.json");
|
|
124
|
+
}
|
|
122
125
|
function listThreads(opts) {
|
|
123
|
-
const files = readdirSync(threadsDir()).filter(
|
|
126
|
+
const files = readdirSync(threadsDir()).filter(isThreadRecordFile);
|
|
124
127
|
const threads = files.map((f) => {
|
|
125
128
|
try {
|
|
126
129
|
return normalizeThread(
|
|
@@ -129,7 +132,9 @@ function listThreads(opts) {
|
|
|
129
132
|
} catch {
|
|
130
133
|
return null;
|
|
131
134
|
}
|
|
132
|
-
}).filter(
|
|
135
|
+
}).filter(
|
|
136
|
+
(t) => t !== null && typeof t.id === "string" && t.id.length > 0
|
|
137
|
+
).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
133
138
|
if (opts?.includeArchived) return threads;
|
|
134
139
|
return threads.filter((t) => t.status !== "archived");
|
|
135
140
|
}
|
|
@@ -161,7 +166,9 @@ function setStatus(id, status, lastError) {
|
|
|
161
166
|
}
|
|
162
167
|
function findThreadByRef(ref) {
|
|
163
168
|
const all = listThreads({ includeArchived: true });
|
|
164
|
-
return all.find(
|
|
169
|
+
return all.find(
|
|
170
|
+
(t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref
|
|
171
|
+
) ?? null;
|
|
165
172
|
}
|
|
166
173
|
|
|
167
174
|
export {
|
|
@@ -400,6 +400,9 @@ function worktreesRoot(repoPath) {
|
|
|
400
400
|
function threadFilePath(id) {
|
|
401
401
|
return join4(threadsDir(), `${id}.json`);
|
|
402
402
|
}
|
|
403
|
+
function threadLivePath(id) {
|
|
404
|
+
return join4(threadsDir(), `${id}.live.json`);
|
|
405
|
+
}
|
|
403
406
|
function threadLockPath(id) {
|
|
404
407
|
return join4(locksDir(), `${id}.lock`);
|
|
405
408
|
}
|
|
@@ -433,6 +436,7 @@ export {
|
|
|
433
436
|
repoSlug,
|
|
434
437
|
worktreesRoot,
|
|
435
438
|
threadFilePath,
|
|
439
|
+
threadLivePath,
|
|
436
440
|
threadLockPath,
|
|
437
441
|
globalAgentCwd
|
|
438
442
|
};
|
|
@@ -5,14 +5,14 @@ import {
|
|
|
5
5
|
} from "./chunk-B3SJXYIJ.js";
|
|
6
6
|
import {
|
|
7
7
|
listThreads
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-P3BQ5DOL.js";
|
|
9
9
|
import {
|
|
10
10
|
getGithubGitAuthMode,
|
|
11
11
|
getGithubPat
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WSYCND2U.js";
|
|
13
13
|
import {
|
|
14
14
|
worktreesRoot
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-BD2ICC4D.js";
|
|
16
16
|
import {
|
|
17
17
|
gh,
|
|
18
18
|
git,
|
|
@@ -787,7 +787,7 @@ function allocateTeamName(taken, random = Math.random) {
|
|
|
787
787
|
|
|
788
788
|
// src/git/worktree-labels.ts
|
|
789
789
|
function normalizeWorktreePath(worktreePath) {
|
|
790
|
-
const trimmed = worktreePath.replace(/\/+$/, "") || "/";
|
|
790
|
+
const trimmed = (worktreePath ?? "").replace(/\/+$/, "") || "/";
|
|
791
791
|
const absolute = trimmed.startsWith("/");
|
|
792
792
|
const parts = trimmed.split("/").filter((p) => p && p !== ".");
|
|
793
793
|
const out = [];
|
|
@@ -1154,6 +1154,30 @@ function formatGitAuthModeDirective(mode) {
|
|
|
1154
1154
|
}
|
|
1155
1155
|
}
|
|
1156
1156
|
|
|
1157
|
+
// src/util/enqueue-by-key.ts
|
|
1158
|
+
var tails = /* @__PURE__ */ new Map();
|
|
1159
|
+
function enqueueByKey(key, fn) {
|
|
1160
|
+
const prev = tails.get(key) ?? Promise.resolve();
|
|
1161
|
+
const next = prev.then(fn, fn);
|
|
1162
|
+
tails.set(
|
|
1163
|
+
key,
|
|
1164
|
+
next.then(
|
|
1165
|
+
() => void 0,
|
|
1166
|
+
() => void 0
|
|
1167
|
+
)
|
|
1168
|
+
);
|
|
1169
|
+
return next;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
// src/git/repo-git-lock.ts
|
|
1173
|
+
function repoLockKey(repoPath) {
|
|
1174
|
+
const trimmed = repoPath.replace(/\/+$/, "");
|
|
1175
|
+
return `git-worktree:${trimmed || "/"}`;
|
|
1176
|
+
}
|
|
1177
|
+
function withRepoGitLock(repoPath, fn) {
|
|
1178
|
+
return enqueueByKey(repoLockKey(repoPath), fn);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1157
1181
|
// src/git/pr-gates.ts
|
|
1158
1182
|
function prIsInMergeQueue(gate) {
|
|
1159
1183
|
if (gate.isInMergeQueue) return true;
|
|
@@ -2223,12 +2247,13 @@ async function createThreadWorktree(opts) {
|
|
|
2223
2247
|
`Invalid git reference: ${opts.sourceRef} (and fetch did not resolve it)`
|
|
2224
2248
|
);
|
|
2225
2249
|
}
|
|
2226
|
-
const
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2250
|
+
const added = await withRepoGitLock(opts.repoPath, async () => {
|
|
2251
|
+
const add = await git(
|
|
2252
|
+
["worktree", "add", "-b", branchName, worktreePath, startPoint],
|
|
2253
|
+
opts.repoPath,
|
|
2254
|
+
{ reject: false, timeoutMs: 6e4 }
|
|
2255
|
+
);
|
|
2256
|
+
if (add.exitCode === 0) return branchName;
|
|
2232
2257
|
const err = `${add.stderr}
|
|
2233
2258
|
${add.stdout}`;
|
|
2234
2259
|
if (/already used by worktree|already exists|checked out/i.test(err)) {
|
|
@@ -2239,17 +2264,14 @@ ${add.stdout}`;
|
|
|
2239
2264
|
opts.repoPath,
|
|
2240
2265
|
{ reject: false, timeoutMs: 6e4 }
|
|
2241
2266
|
);
|
|
2242
|
-
if (retry.exitCode === 0)
|
|
2243
|
-
branchName = alt;
|
|
2244
|
-
await ensureGhPreferOrigin(worktreePath);
|
|
2245
|
-
return { branchName, worktreePath };
|
|
2246
|
-
}
|
|
2267
|
+
if (retry.exitCode === 0) return alt;
|
|
2247
2268
|
}
|
|
2248
2269
|
}
|
|
2249
2270
|
throw new Error(
|
|
2250
2271
|
`Failed to create worktree: ${add.stderr.trim() || add.stdout.trim() || `exit ${add.exitCode}`}`
|
|
2251
2272
|
);
|
|
2252
|
-
}
|
|
2273
|
+
});
|
|
2274
|
+
branchName = added;
|
|
2253
2275
|
await ensureGhPreferOrigin(worktreePath);
|
|
2254
2276
|
return { branchName, worktreePath };
|
|
2255
2277
|
}
|
|
@@ -2273,12 +2295,13 @@ async function createExistingBranchWorktree(opts) {
|
|
|
2273
2295
|
);
|
|
2274
2296
|
}
|
|
2275
2297
|
const startPoint = await resolveWorktreeStartPoint(opts.repoPath, branchName);
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2298
|
+
await withRepoGitLock(opts.repoPath, async () => {
|
|
2299
|
+
const add = await git(
|
|
2300
|
+
["worktree", "add", worktreePath, startPoint],
|
|
2301
|
+
opts.repoPath,
|
|
2302
|
+
{ reject: false }
|
|
2303
|
+
);
|
|
2304
|
+
if (add.exitCode === 0) return;
|
|
2282
2305
|
const retry = await git(
|
|
2283
2306
|
["worktree", "add", worktreePath, branchName],
|
|
2284
2307
|
opts.repoPath,
|
|
@@ -2289,7 +2312,7 @@ async function createExistingBranchWorktree(opts) {
|
|
|
2289
2312
|
`Failed to create worktree for ${branchName}: ${retry.stderr.trim() || add.stderr.trim() || retry.stdout.trim() || add.stdout.trim() || `exit ${add.exitCode}`}`
|
|
2290
2313
|
);
|
|
2291
2314
|
}
|
|
2292
|
-
}
|
|
2315
|
+
});
|
|
2293
2316
|
const head = await git(["rev-parse", "--abbrev-ref", "HEAD"], worktreePath, {
|
|
2294
2317
|
reject: false
|
|
2295
2318
|
});
|
|
@@ -2300,12 +2323,14 @@ async function createExistingBranchWorktree(opts) {
|
|
|
2300
2323
|
return { branchName, worktreePath };
|
|
2301
2324
|
}
|
|
2302
2325
|
async function removeWorktree(repoPath, worktreePath, opts) {
|
|
2303
|
-
await
|
|
2304
|
-
|
|
2326
|
+
await withRepoGitLock(repoPath, async () => {
|
|
2327
|
+
await git(["worktree", "remove", "--force", worktreePath], repoPath, {
|
|
2328
|
+
reject: false
|
|
2329
|
+
});
|
|
2330
|
+
if (opts?.deleteBranch) {
|
|
2331
|
+
await git(["branch", "-D", opts.deleteBranch], repoPath, { reject: false });
|
|
2332
|
+
}
|
|
2305
2333
|
});
|
|
2306
|
-
if (opts?.deleteBranch) {
|
|
2307
|
-
await git(["branch", "-D", opts.deleteBranch], repoPath, { reject: false });
|
|
2308
|
-
}
|
|
2309
2334
|
}
|
|
2310
2335
|
async function listWorktrees(repoPath) {
|
|
2311
2336
|
const { stdout } = await git(
|
|
@@ -2606,6 +2631,8 @@ export {
|
|
|
2606
2631
|
resolveCodexGitWritableRoots,
|
|
2607
2632
|
codexUnattendedGitConfigArgs,
|
|
2608
2633
|
formatGitAuthModeDirective,
|
|
2634
|
+
enqueueByKey,
|
|
2635
|
+
withRepoGitLock,
|
|
2609
2636
|
detectGhStack,
|
|
2610
2637
|
getPrStack,
|
|
2611
2638
|
initPrStack,
|