@sideboard-ai/core 0.1.83 → 0.1.85
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 +88 -53
- package/dist/agents/cursor-runner.js +93 -56
- package/dist/{agents-4KRD46KG.js → agents-FD77JUOP.js} +10 -10
- package/dist/{agents-3YPUZME7.js → agents-YAYNNJWC.js} +9 -9
- package/dist/{app-settings-MQXL7OUF.js → app-settings-K6RFCRF6.js} +2 -2
- package/dist/{app-settings-GVSOIJLZ.js → app-settings-PEXK5VEX.js} +1 -1
- package/dist/{chunk-LVTNWH7B.js → chunk-2N5DVTGH.js} +2 -2
- package/dist/{chunk-JMRJ4F5B.js → chunk-3CCRD6WS.js} +69 -20
- package/dist/{chunk-AE5VBOFE.js → chunk-3KETJKYA.js} +9 -2
- package/dist/{chunk-IZ7RPF54.js → chunk-5KLC2MWZ.js} +5 -1
- package/dist/{chunk-DJFGX4RT.js → chunk-6GKDYUTJ.js} +3 -3
- package/dist/{chunk-VROPG6QF.js → chunk-6K5VAPVR.js} +3 -3
- package/dist/{chunk-HBBXS2FR.js → chunk-6WQAYBVE.js} +89 -21
- package/dist/{chunk-UHGN4KCL.js → chunk-AY53MPDE.js} +4 -0
- package/dist/{chunk-SEOICVGB.js → chunk-CBJSPTBG.js} +30 -6
- package/dist/{chunk-BTL7EMGT.js → chunk-HHTHF5BQ.js} +4 -4
- package/dist/{chunk-YO3CYL6B.js → chunk-I3FRXL7J.js} +1 -1
- package/dist/{chunk-RS54WYYH.js → chunk-JFQ2M6NQ.js} +2 -2
- package/dist/{chunk-NXXT5SE3.js → chunk-JTHWVYSD.js} +3 -3
- package/dist/{chunk-GD2FM6FN.js → chunk-KRAUS3RF.js} +87 -17
- package/dist/{chunk-D4DPQ552.js → chunk-LGXBYZZA.js} +9 -2
- package/dist/{chunk-E2MIA7DO.js → chunk-SH75CXJR.js} +2 -2
- package/dist/{chunk-JW6YFPQE.js → chunk-WGI6KXKJ.js} +36 -11
- package/dist/{chunk-ERJS3ZDP.js → chunk-XVFV56JG.js} +2 -2
- package/dist/{connected-teams-ZRS53OAT.js → connected-teams-BNBM7OIC.js} +2 -2
- package/dist/{connected-teams-35EIRJCP.js → connected-teams-LSQ5TAZP.js} +2 -2
- package/dist/{coordinator-prompt-46JE4NQR.js → coordinator-prompt-VN7FF76K.js} +5 -5
- package/dist/{coordinator-prompt-6ICA54JR.js → coordinator-prompt-YYQSPLIP.js} +4 -4
- package/dist/{global-workspace-GSLCEB5E.js → global-workspace-BRIDCBMY.js} +6 -6
- package/dist/{global-workspace-OBRWUPZG.js → global-workspace-U3XVTQLL.js} +5 -5
- package/dist/index.cjs +235 -94
- package/dist/index.d.cts +32 -6
- package/dist/index.d.ts +32 -6
- package/dist/index.js +47 -33
- package/dist/mcp/run-stdio.cjs +532 -399
- package/dist/mcp/run-stdio.js +43 -36
- package/dist/{run-V2WZUMJA.js → run-CFKZPY7F.js} +1 -1
- package/dist/{run-A4RHY7HH.js → run-XKTAJRWF.js} +1 -1
- package/dist/{workspaces-RJIWQB6J.js → workspaces-AIZDG6PS.js} +6 -6
- package/dist/{workspaces-7B3PTEF4.js → workspaces-IWQIWAMQ.js} +7 -7
- package/dist/{worktree-U3UIID2K.js → worktree-6ZALJUWG.js} +3 -3
- package/dist/{worktree-HSN5LWY6.js → worktree-7Y22WHR7.js} +4 -4
- package/package.json +1 -1
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -54,6 +54,9 @@ function wrapElectronAsNodeLaunch(file, args) {
|
|
|
54
54
|
args: ["-c", STRIP_NESTED_ELECTRON_THEN_EXEC, "sh", file, ...args]
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
+
function isStrippedElectronLaunch(command, args) {
|
|
58
|
+
return command === "/bin/sh" && Boolean(args?.[1]?.includes("ELECTRON_RUN_AS_NODE") && args[1].includes("unset"));
|
|
59
|
+
}
|
|
57
60
|
var NESTED_ELECTRON_ENV_PREFIXES, STRIP_NESTED_ELECTRON_THEN_EXEC;
|
|
58
61
|
var init_nested_electron_env = __esm({
|
|
59
62
|
"src/hook/nested-electron-env.ts"() {
|
|
@@ -730,20 +733,36 @@ function pushTurnStderr(tail, line, maxLines = 12) {
|
|
|
730
733
|
tail.push(trimmed);
|
|
731
734
|
while (tail.length > maxLines) tail.shift();
|
|
732
735
|
}
|
|
736
|
+
function looksLikeMinifiedJsDump(line) {
|
|
737
|
+
if (line.length < 200) return false;
|
|
738
|
+
return /yield Promise\.all/.test(line) || /\(0,[A-Za-z$]\.\w+\)/.test(line) || /CURSOR_RIPGREP_PATH/.test(line);
|
|
739
|
+
}
|
|
740
|
+
function looksLikeNestedElectronCrash(line) {
|
|
741
|
+
return /HasCustomHostObject|ElectronInitializeICUandStartNode/i.test(line);
|
|
742
|
+
}
|
|
743
|
+
function clipStderr(text3, maxChars) {
|
|
744
|
+
const trimmed = text3.trim();
|
|
745
|
+
if (trimmed.length <= maxChars) return trimmed;
|
|
746
|
+
return trimmed.slice(0, maxChars);
|
|
747
|
+
}
|
|
733
748
|
function summarizeTurnStderr(tail, maxChars = 500) {
|
|
734
749
|
if (tail.length === 0) return "";
|
|
750
|
+
const cursorStartup = [...tail].reverse().find((line) => /cursor startup failed:/i.test(line));
|
|
751
|
+
if (cursorStartup) return clipStderr(cursorStartup, maxChars);
|
|
752
|
+
if (tail.some(looksLikeNestedElectronCrash)) return NESTED_ELECTRON_SUMMARY;
|
|
735
753
|
const moduleMissing = [...tail].reverse().find((line) => /cannot find module/i.test(line));
|
|
736
|
-
if (moduleMissing)
|
|
737
|
-
|
|
754
|
+
if (moduleMissing) return clipStderr(moduleMissing, maxChars);
|
|
755
|
+
const useful = tail.filter((line) => !looksLikeMinifiedJsDump(line));
|
|
756
|
+
if (useful.length === 0 && tail.some(looksLikeMinifiedJsDump)) {
|
|
757
|
+
return MINIFIED_DUMP_SUMMARY;
|
|
738
758
|
}
|
|
739
|
-
const joined = tail.slice(-6).join("\n").trim();
|
|
740
|
-
|
|
741
|
-
return joined.slice(joined.length - maxChars);
|
|
759
|
+
const joined = (useful.length ? useful : tail).slice(-6).join("\n").trim();
|
|
760
|
+
return clipStderr(joined, maxChars);
|
|
742
761
|
}
|
|
743
762
|
function looksLikeInvalidAgentSession(text3) {
|
|
744
763
|
const lower = text3.trim().toLowerCase();
|
|
745
764
|
if (!lower) return false;
|
|
746
|
-
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);
|
|
765
|
+
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);
|
|
747
766
|
}
|
|
748
767
|
function looksLikeAgentFailureMessage(text3) {
|
|
749
768
|
const lower = text3.trim().toLowerCase();
|
|
@@ -783,6 +802,12 @@ function humanizeAgentFailDetail(detail) {
|
|
|
783
802
|
if (/context.*(too long|exceed)|prompt is too long|conversation too long/.test(lower)) {
|
|
784
803
|
return `${raw} \u2014 start a new chat or compact context, then retry.`;
|
|
785
804
|
}
|
|
805
|
+
if (/hascustomhostobject|electroninitializeicuandstartnode|nested chromium/i.test(lower)) {
|
|
806
|
+
return `${raw} \u2014 retry the turn; if it keeps failing, pick another agent.`;
|
|
807
|
+
}
|
|
808
|
+
if (/corrupt local agent checkpoint|missing root blob|truncated crash dump/.test(lower)) {
|
|
809
|
+
return `${raw} \u2014 retry the turn (Sideboard will start a fresh Cursor session).`;
|
|
810
|
+
}
|
|
786
811
|
return raw;
|
|
787
812
|
}
|
|
788
813
|
function formatTurnExitError(exitCode, stderrSummary) {
|
|
@@ -798,11 +823,13 @@ function formatTurnExitError(exitCode, stderrSummary) {
|
|
|
798
823
|
if (looksLikeAgentFailureMessage(raw)) return detail;
|
|
799
824
|
return `exit ${code}: ${detail}`;
|
|
800
825
|
}
|
|
801
|
-
var NODE_VERSION_FOOTER;
|
|
826
|
+
var NODE_VERSION_FOOTER, NESTED_ELECTRON_SUMMARY, MINIFIED_DUMP_SUMMARY;
|
|
802
827
|
var init_error_detail = __esm({
|
|
803
828
|
"src/agents/error-detail.ts"() {
|
|
804
829
|
"use strict";
|
|
805
830
|
NODE_VERSION_FOOTER = /^Node\.js v\d+/i;
|
|
831
|
+
NESTED_ELECTRON_SUMMARY = "Cursor local agent crashed at Electron startup (nested Chromium / HasCustomHostObject)";
|
|
832
|
+
MINIFIED_DUMP_SUMMARY = "Cursor local agent crashed during startup (truncated crash dump)";
|
|
806
833
|
}
|
|
807
834
|
});
|
|
808
835
|
|
|
@@ -1705,261 +1732,9 @@ var init_gh_errors = __esm({
|
|
|
1705
1732
|
}
|
|
1706
1733
|
});
|
|
1707
1734
|
|
|
1708
|
-
// src/git/git-auth-mode.ts
|
|
1709
|
-
function appendIndexedGitConfig(existing, entries) {
|
|
1710
|
-
const start = Number.parseInt(String(existing?.GIT_CONFIG_COUNT ?? "0"), 10);
|
|
1711
|
-
const count = Number.isFinite(start) && start > 0 ? start : 0;
|
|
1712
|
-
const out = {};
|
|
1713
|
-
entries.forEach((entry, i) => {
|
|
1714
|
-
const n = count + i;
|
|
1715
|
-
out[`GIT_CONFIG_KEY_${n}`] = entry.key;
|
|
1716
|
-
out[`GIT_CONFIG_VALUE_${n}`] = entry.value;
|
|
1717
|
-
});
|
|
1718
|
-
out.GIT_CONFIG_COUNT = String(count + entries.length);
|
|
1719
|
-
return out;
|
|
1720
|
-
}
|
|
1721
|
-
function githubAgentGitEnv(existing) {
|
|
1722
|
-
return appendIndexedGitConfig(existing, HTTPS_REWRITE);
|
|
1723
|
-
}
|
|
1724
|
-
function applyGithubGitAuthEnv(existing, opts) {
|
|
1725
|
-
const out = {};
|
|
1726
|
-
if (opts.mode === "gh" || opts.mode === "token") {
|
|
1727
|
-
Object.assign(out, githubAgentGitEnv(existing));
|
|
1728
|
-
}
|
|
1729
|
-
if (opts.mode === "token") {
|
|
1730
|
-
const token = opts.token?.trim();
|
|
1731
|
-
if (token && !existing?.GH_TOKEN?.trim()) {
|
|
1732
|
-
out.GH_TOKEN = token;
|
|
1733
|
-
}
|
|
1734
|
-
}
|
|
1735
|
-
return out;
|
|
1736
|
-
}
|
|
1737
|
-
function formatGitAuthModeDirective(mode) {
|
|
1738
|
-
switch (mode) {
|
|
1739
|
-
case "gh":
|
|
1740
|
-
return [
|
|
1741
|
-
"Git authentication (Account \u2192 GitHub mode: gh CLI):",
|
|
1742
|
-
"- This process rewrites `git@github.com:` and `ssh://git@github.com/` to HTTPS.",
|
|
1743
|
-
"- `gh` supplies credentials (`gh auth git-credential`). Do not switch remotes to SSH.",
|
|
1744
|
-
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below."
|
|
1745
|
-
].join("\n");
|
|
1746
|
-
case "ssh":
|
|
1747
|
-
return [
|
|
1748
|
-
"Git authentication (Account \u2192 GitHub mode: SSH):",
|
|
1749
|
-
"- Keep SSH remotes (`git@github.com:\u2026`). Do not rewrite them to HTTPS.",
|
|
1750
|
-
"- Use this Mac\u2019s SSH agent / keys. If push fails with `Permission denied (publickey)`, tell the user to start ssh-agent or switch Account \u2192 GitHub to Auto / gh CLI \u2014 do not rewrite remotes yourself.",
|
|
1751
|
-
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below (API still uses `gh`)."
|
|
1752
|
-
].join("\n");
|
|
1753
|
-
case "token":
|
|
1754
|
-
return [
|
|
1755
|
-
"Git authentication (Account \u2192 GitHub mode: personal access token):",
|
|
1756
|
-
"- This process rewrites GitHub SSH remotes to HTTPS.",
|
|
1757
|
-
"- `GH_TOKEN` is set in the environment. Use HTTPS git and `gh`; do not paste the token into commands or chat.",
|
|
1758
|
-
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below."
|
|
1759
|
-
].join("\n");
|
|
1760
|
-
case "auto":
|
|
1761
|
-
default:
|
|
1762
|
-
return [
|
|
1763
|
-
"Git authentication (Account \u2192 GitHub mode: auto):",
|
|
1764
|
-
"- Prefer the existing remote URL (SSH or HTTPS). Do not rewrite remotes unless a push/fetch fails.",
|
|
1765
|
-
'- If `git push` fails with `Permission denied (publickey)`, this shell has no ssh-agent. Retry over HTTPS (do not stop): `git -c url.https://github.com/.insteadOf=git@github.com: -c http.extraHeader="AUTHORIZATION: bearer $(gh auth token)" push -u origin HEAD`.',
|
|
1766
|
-
"- Then create/update the PR with `gh` as below."
|
|
1767
|
-
].join("\n");
|
|
1768
|
-
}
|
|
1769
|
-
}
|
|
1770
|
-
var HTTPS_REWRITE;
|
|
1771
|
-
var init_git_auth_mode = __esm({
|
|
1772
|
-
"src/git/git-auth-mode.ts"() {
|
|
1773
|
-
"use strict";
|
|
1774
|
-
HTTPS_REWRITE = [
|
|
1775
|
-
{ key: "url.https://github.com/.insteadOf", value: "git@github.com:" },
|
|
1776
|
-
{ key: "url.https://github.com/.insteadOf", value: "ssh://git@github.com/" },
|
|
1777
|
-
{ key: "credential.https://github.com.helper", value: "!gh auth git-credential" }
|
|
1778
|
-
];
|
|
1779
|
-
}
|
|
1780
|
-
});
|
|
1781
|
-
|
|
1782
|
-
// src/agents/path.ts
|
|
1783
|
-
function prependPathDir(env, dir) {
|
|
1784
|
-
if (!dir || !(0, import_node_fs8.existsSync)(dir)) return;
|
|
1785
|
-
const current = env.PATH ?? "";
|
|
1786
|
-
const parts = current.split(import_node_path8.delimiter).filter(Boolean);
|
|
1787
|
-
if (parts.includes(dir)) {
|
|
1788
|
-
env.PATH = current;
|
|
1789
|
-
return;
|
|
1790
|
-
}
|
|
1791
|
-
env.PATH = [dir, ...parts].join(import_node_path8.delimiter);
|
|
1792
|
-
}
|
|
1793
|
-
function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os3.homedir)()) {
|
|
1794
|
-
return (0, import_node_path8.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
|
|
1795
|
-
}
|
|
1796
|
-
function isConductorBundledCli(filePath) {
|
|
1797
|
-
const p = (filePath ?? "").replace(/\\/g, "/");
|
|
1798
|
-
return p.includes("/com.conductor.app/bin/") || p.endsWith("/com.conductor.app/bin");
|
|
1799
|
-
}
|
|
1800
|
-
function ensureAgentPath(env = process.env) {
|
|
1801
|
-
const home = env.HOME || env.USERPROFILE || (0, import_node_os3.homedir)();
|
|
1802
|
-
const current = env.PATH ?? "";
|
|
1803
|
-
const parts = current.split(import_node_path8.delimiter).filter(Boolean);
|
|
1804
|
-
const seen = new Set(parts);
|
|
1805
|
-
const extras = [
|
|
1806
|
-
...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path8.join)(home, rel)),
|
|
1807
|
-
"/opt/homebrew/bin",
|
|
1808
|
-
"/usr/local/bin",
|
|
1809
|
-
// Keep after Homebrew/npm so a user-installed CLI still wins.
|
|
1810
|
-
conductorBundledBinDir(home)
|
|
1811
|
-
];
|
|
1812
|
-
for (const dir of extras.reverse()) {
|
|
1813
|
-
if (!dir || seen.has(dir) || !(0, import_node_fs8.existsSync)(dir)) continue;
|
|
1814
|
-
parts.unshift(dir);
|
|
1815
|
-
seen.add(dir);
|
|
1816
|
-
}
|
|
1817
|
-
const next = parts.join(import_node_path8.delimiter);
|
|
1818
|
-
env.PATH = next;
|
|
1819
|
-
return next;
|
|
1820
|
-
}
|
|
1821
|
-
function enrichPathWithNpmGlobalBin(env = process.env) {
|
|
1822
|
-
ensureAgentPath(env);
|
|
1823
|
-
try {
|
|
1824
|
-
const prefix = (0, import_node_child_process2.execFileSync)("npm", ["prefix", "-g"], {
|
|
1825
|
-
encoding: "utf8",
|
|
1826
|
-
env: { ...process.env, ...env },
|
|
1827
|
-
timeout: 8e3,
|
|
1828
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
1829
|
-
}).trim().split(/\r?\n/).find(Boolean);
|
|
1830
|
-
if (prefix) {
|
|
1831
|
-
const binDir = process.platform === "win32" ? prefix : (0, import_node_path8.join)(prefix, "bin");
|
|
1832
|
-
prependPathDir(env, binDir);
|
|
1833
|
-
}
|
|
1834
|
-
} catch {
|
|
1835
|
-
}
|
|
1836
|
-
return env.PATH ?? "";
|
|
1837
|
-
}
|
|
1838
|
-
function posixShellSingleQuote(value) {
|
|
1839
|
-
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
1840
|
-
}
|
|
1841
|
-
function resolveCommandBinarySync(command, whichPath) {
|
|
1842
|
-
const trimmed = command.trim();
|
|
1843
|
-
if (!trimmed) return trimmed;
|
|
1844
|
-
const match = /^(\S+)(\s[\s\S]*)?$/.exec(trimmed);
|
|
1845
|
-
if (!match) return trimmed;
|
|
1846
|
-
const bin = match[1];
|
|
1847
|
-
const rest = match[2] ?? "";
|
|
1848
|
-
if (bin.includes("/") || bin.includes("\\")) return trimmed;
|
|
1849
|
-
const abs = whichPath?.trim().split(/\r?\n/).find(Boolean);
|
|
1850
|
-
if (!abs) return trimmed;
|
|
1851
|
-
return `${abs}${rest}`;
|
|
1852
|
-
}
|
|
1853
|
-
function withExportedPath(command, pathValue) {
|
|
1854
|
-
const trimmed = command.trim();
|
|
1855
|
-
if (!trimmed) return trimmed;
|
|
1856
|
-
if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
|
|
1857
|
-
return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
|
|
1858
|
-
}
|
|
1859
|
-
var import_node_fs8, import_node_child_process2, import_node_os3, import_node_path8, EXTRA_BIN_DIRS;
|
|
1860
|
-
var init_path = __esm({
|
|
1861
|
-
"src/agents/path.ts"() {
|
|
1862
|
-
"use strict";
|
|
1863
|
-
import_node_fs8 = require("fs");
|
|
1864
|
-
import_node_child_process2 = require("child_process");
|
|
1865
|
-
import_node_os3 = require("os");
|
|
1866
|
-
import_node_path8 = require("path");
|
|
1867
|
-
EXTRA_BIN_DIRS = [
|
|
1868
|
-
".local/bin",
|
|
1869
|
-
".cargo/bin",
|
|
1870
|
-
".nvm/current/bin",
|
|
1871
|
-
".asdf/shims",
|
|
1872
|
-
".volta/bin",
|
|
1873
|
-
".npm-global/bin",
|
|
1874
|
-
// fnm default alias (common when shell init is skipped)
|
|
1875
|
-
".local/share/fnm/aliases/default/bin",
|
|
1876
|
-
// pnpm / npm global bins (where `@brightsy/cli` typically lands)
|
|
1877
|
-
"Library/pnpm",
|
|
1878
|
-
".pnpm"
|
|
1879
|
-
];
|
|
1880
|
-
}
|
|
1881
|
-
});
|
|
1882
|
-
|
|
1883
|
-
// src/git/run.ts
|
|
1884
|
-
var run_exports = {};
|
|
1885
|
-
__export(run_exports, {
|
|
1886
|
-
gh: () => gh,
|
|
1887
|
-
git: () => git,
|
|
1888
|
-
resolveGhAuthToken: () => resolveGhAuthToken,
|
|
1889
|
-
run: () => run
|
|
1890
|
-
});
|
|
1891
|
-
async function run(file, args, opts) {
|
|
1892
|
-
ensureAgentPath();
|
|
1893
|
-
try {
|
|
1894
|
-
const result = await (0, import_execa.execa)(file, args, {
|
|
1895
|
-
cwd: opts?.cwd,
|
|
1896
|
-
env: { ...process.env, ...opts?.env },
|
|
1897
|
-
reject: opts?.reject ?? true,
|
|
1898
|
-
...opts?.timeoutMs != null ? { timeout: opts.timeoutMs } : {}
|
|
1899
|
-
});
|
|
1900
|
-
return {
|
|
1901
|
-
stdout: result.stdout ?? "",
|
|
1902
|
-
stderr: result.stderr ?? "",
|
|
1903
|
-
exitCode: result.exitCode ?? 0
|
|
1904
|
-
};
|
|
1905
|
-
} catch (err) {
|
|
1906
|
-
const e = err;
|
|
1907
|
-
if (opts?.reject === false) {
|
|
1908
|
-
return {
|
|
1909
|
-
stdout: String(e.stdout ?? ""),
|
|
1910
|
-
stderr: String(e.stderr ?? ""),
|
|
1911
|
-
exitCode: e.exitCode ?? 1
|
|
1912
|
-
};
|
|
1913
|
-
}
|
|
1914
|
-
throw err;
|
|
1915
|
-
}
|
|
1916
|
-
}
|
|
1917
|
-
async function git(args, cwd, opts) {
|
|
1918
|
-
const prefix = [];
|
|
1919
|
-
if (opts?.config) {
|
|
1920
|
-
for (const [key, value] of Object.entries(opts.config)) {
|
|
1921
|
-
if (!key) continue;
|
|
1922
|
-
prefix.push("-c", `${key}=${value}`);
|
|
1923
|
-
}
|
|
1924
|
-
}
|
|
1925
|
-
return run("git", ["--no-pager", ...prefix, ...args], {
|
|
1926
|
-
cwd,
|
|
1927
|
-
reject: opts?.reject,
|
|
1928
|
-
timeoutMs: opts?.timeoutMs,
|
|
1929
|
-
// Never block forever on a credential/SSH prompt inside MCP / Electron.
|
|
1930
|
-
env: {
|
|
1931
|
-
GIT_TERMINAL_PROMPT: "0",
|
|
1932
|
-
GIT_ASKPASS: process.env.GIT_ASKPASS || "echo",
|
|
1933
|
-
GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND || "ssh -o BatchMode=yes -o ConnectTimeout=15",
|
|
1934
|
-
...opts?.env
|
|
1935
|
-
}
|
|
1936
|
-
});
|
|
1937
|
-
}
|
|
1938
|
-
async function gh(args, cwd, opts) {
|
|
1939
|
-
return run("gh", args, {
|
|
1940
|
-
cwd,
|
|
1941
|
-
reject: opts?.reject,
|
|
1942
|
-
timeoutMs: opts?.timeoutMs
|
|
1943
|
-
});
|
|
1944
|
-
}
|
|
1945
|
-
async function resolveGhAuthToken(cwd) {
|
|
1946
|
-
const result = await gh(["auth", "token"], cwd, { reject: false });
|
|
1947
|
-
if (result.exitCode !== 0) return null;
|
|
1948
|
-
const token = result.stdout.trim();
|
|
1949
|
-
return token || null;
|
|
1950
|
-
}
|
|
1951
|
-
var import_execa;
|
|
1952
|
-
var init_run = __esm({
|
|
1953
|
-
"src/git/run.ts"() {
|
|
1954
|
-
"use strict";
|
|
1955
|
-
import_execa = require("execa");
|
|
1956
|
-
init_path();
|
|
1957
|
-
}
|
|
1958
|
-
});
|
|
1959
|
-
|
|
1960
1735
|
// src/store/secret-vault.ts
|
|
1961
1736
|
function secretVaultPath() {
|
|
1962
|
-
return (0,
|
|
1737
|
+
return (0, import_node_path8.join)(appDataDir(), "secrets.json");
|
|
1963
1738
|
}
|
|
1964
1739
|
function loadSecretVault() {
|
|
1965
1740
|
const parsed = readSecureJson(secretVaultPath());
|
|
@@ -2003,11 +1778,11 @@ function normalizeVault(raw) {
|
|
|
2003
1778
|
}
|
|
2004
1779
|
return out;
|
|
2005
1780
|
}
|
|
2006
|
-
var
|
|
1781
|
+
var import_node_path8;
|
|
2007
1782
|
var init_secret_vault = __esm({
|
|
2008
1783
|
"src/store/secret-vault.ts"() {
|
|
2009
1784
|
"use strict";
|
|
2010
|
-
|
|
1785
|
+
import_node_path8 = require("path");
|
|
2011
1786
|
init_paths();
|
|
2012
1787
|
init_secure_file();
|
|
2013
1788
|
}
|
|
@@ -2108,10 +1883,10 @@ function toPublicAppSettings(settings) {
|
|
|
2108
1883
|
};
|
|
2109
1884
|
}
|
|
2110
1885
|
function appSettingsPath() {
|
|
2111
|
-
return (0,
|
|
1886
|
+
return (0, import_node_path9.join)(appDataDir(), "settings.json");
|
|
2112
1887
|
}
|
|
2113
1888
|
function claudeUserSettingsPath() {
|
|
2114
|
-
return (0,
|
|
1889
|
+
return (0, import_node_path9.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
|
|
2115
1890
|
}
|
|
2116
1891
|
function normalizeClaude(raw) {
|
|
2117
1892
|
if (!raw || typeof raw !== "object") return {};
|
|
@@ -2354,10 +2129,10 @@ function normalizeSettings(raw) {
|
|
|
2354
2129
|
}
|
|
2355
2130
|
function readSettingsFile() {
|
|
2356
2131
|
const path = appSettingsPath();
|
|
2357
|
-
if (!(0,
|
|
2132
|
+
if (!(0, import_node_fs8.existsSync)(path)) return { ...EMPTY_SETTINGS };
|
|
2358
2133
|
try {
|
|
2359
2134
|
chmodOwnerOnly(path);
|
|
2360
|
-
const parsed = JSON.parse((0,
|
|
2135
|
+
const parsed = JSON.parse((0, import_node_fs8.readFileSync)(path, "utf8"));
|
|
2361
2136
|
return normalizeSettings(parsed);
|
|
2362
2137
|
} catch {
|
|
2363
2138
|
return { ...EMPTY_SETTINGS };
|
|
@@ -2742,7 +2517,7 @@ function ensureSlackDeviceIdentity(settings = loadAppSettings()) {
|
|
|
2742
2517
|
}
|
|
2743
2518
|
if (!deviceLabel) {
|
|
2744
2519
|
try {
|
|
2745
|
-
deviceLabel = (0,
|
|
2520
|
+
deviceLabel = (0, import_node_os3.hostname)().split(".")[0]?.trim() || "This Mac";
|
|
2746
2521
|
} catch {
|
|
2747
2522
|
deviceLabel = "This Mac";
|
|
2748
2523
|
}
|
|
@@ -2830,145 +2605,472 @@ function caffeinateWhileRunningEnabled(settings = loadAppSettings()) {
|
|
|
2830
2605
|
function caffeinateWhileSlackListenEnabled(settings = loadAppSettings()) {
|
|
2831
2606
|
return Boolean(settings.advanced.caffeinateWhileSlackListen);
|
|
2832
2607
|
}
|
|
2833
|
-
function caffeinateWhileCloudConnectEnabled(settings = loadAppSettings()) {
|
|
2834
|
-
return caffeinateWhileSlackListenEnabled(settings);
|
|
2608
|
+
function caffeinateWhileCloudConnectEnabled(settings = loadAppSettings()) {
|
|
2609
|
+
return caffeinateWhileSlackListenEnabled(settings);
|
|
2610
|
+
}
|
|
2611
|
+
function deleteBranchOnPurgeEnabled(settings = loadAppSettings()) {
|
|
2612
|
+
return Boolean(settings.advanced.deleteBranchOnPurge);
|
|
2613
|
+
}
|
|
2614
|
+
function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
|
|
2615
|
+
return Boolean(settings.advanced.autoArchiveOnMerge);
|
|
2616
|
+
}
|
|
2617
|
+
function autoCleanupOrphansEnabled(settings = loadAppSettings()) {
|
|
2618
|
+
return Boolean(settings.advanced.autoCleanupOrphans);
|
|
2619
|
+
}
|
|
2620
|
+
function orchestrationQuotaOnLimit(settings = loadAppSettings()) {
|
|
2621
|
+
return settings.advanced.orchestrationQuotaOnLimit ?? "switch_agent";
|
|
2622
|
+
}
|
|
2623
|
+
function orchestrationQuotaFallbackAgent(settings = loadAppSettings()) {
|
|
2624
|
+
const preferred = settings.advanced.orchestrationQuotaFallbackAgent;
|
|
2625
|
+
if (preferred && DEFAULT_AGENTS.has(preferred) && preferred !== "brightsy") {
|
|
2626
|
+
return preferred;
|
|
2627
|
+
}
|
|
2628
|
+
return "cursor";
|
|
2629
|
+
}
|
|
2630
|
+
function maxConcurrentAgents(settings = loadAppSettings()) {
|
|
2631
|
+
const n = settings.advanced.maxConcurrent;
|
|
2632
|
+
if (typeof n === "number" && Number.isFinite(n)) {
|
|
2633
|
+
return Math.max(1, Math.min(32, Math.floor(n)));
|
|
2634
|
+
}
|
|
2635
|
+
return 3;
|
|
2636
|
+
}
|
|
2637
|
+
function resolveClaudeExecutable(settings = loadAppSettings()) {
|
|
2638
|
+
return resolveAgentExecutable("claude", settings);
|
|
2639
|
+
}
|
|
2640
|
+
function resolveAgentExecutable(agent, settings = loadAppSettings()) {
|
|
2641
|
+
const fallback = DEFAULT_CLI_BIN[agent];
|
|
2642
|
+
if (agent === "claude") {
|
|
2643
|
+
const override2 = settings.claude.executablePath?.trim();
|
|
2644
|
+
return override2 || fallback;
|
|
2645
|
+
}
|
|
2646
|
+
if (agent === "codex") {
|
|
2647
|
+
const override2 = settings.codex.executablePath?.trim();
|
|
2648
|
+
return override2 || fallback;
|
|
2649
|
+
}
|
|
2650
|
+
if (agent === "opencode") {
|
|
2651
|
+
const override2 = settings.opencode.executablePath?.trim();
|
|
2652
|
+
return override2 || fallback;
|
|
2653
|
+
}
|
|
2654
|
+
const override = settings.brightsy.executablePath?.trim();
|
|
2655
|
+
return override || fallback;
|
|
2656
|
+
}
|
|
2657
|
+
function updateAgentExecutable(agent, executablePath) {
|
|
2658
|
+
if (agent === "claude") {
|
|
2659
|
+
return updateClaudeSettings({ executablePath });
|
|
2660
|
+
}
|
|
2661
|
+
if (agent === "codex") {
|
|
2662
|
+
return updateCodexSettings({ executablePath });
|
|
2663
|
+
}
|
|
2664
|
+
if (agent === "opencode") {
|
|
2665
|
+
return updateOpencodeSettings({ executablePath });
|
|
2666
|
+
}
|
|
2667
|
+
return updateBrightsySettings({ executablePath });
|
|
2668
|
+
}
|
|
2669
|
+
function claudeChromeEnabled(settings = loadAppSettings()) {
|
|
2670
|
+
return Boolean(settings.claude.chromeEnabled);
|
|
2671
|
+
}
|
|
2672
|
+
function applyAppEnvironment(target = process.env, settings = loadAppSettings()) {
|
|
2673
|
+
for (const [key, value] of Object.entries(settings.environment)) {
|
|
2674
|
+
if (!key || value == null || value === "") continue;
|
|
2675
|
+
if (target[key] == null || target[key] === "") {
|
|
2676
|
+
target[key] = value;
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
return target;
|
|
2680
|
+
}
|
|
2681
|
+
function childEnvWithAppSettings(extra) {
|
|
2682
|
+
const settings = loadAppSettings();
|
|
2683
|
+
const env = stripNestedElectronEnv({ ...process.env });
|
|
2684
|
+
applyAppEnvironment(env, settings);
|
|
2685
|
+
if (extra) {
|
|
2686
|
+
for (const [k, v] of Object.entries(extra)) {
|
|
2687
|
+
if (v != null) env[k] = v;
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
return env;
|
|
2691
|
+
}
|
|
2692
|
+
function harnessEnvKey(harness) {
|
|
2693
|
+
return HARNESS_ENV_KEYS[harness];
|
|
2694
|
+
}
|
|
2695
|
+
var import_node_crypto3, import_node_fs8, import_node_os3, import_node_path9, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
|
|
2696
|
+
var init_app_settings = __esm({
|
|
2697
|
+
"src/store/app-settings.ts"() {
|
|
2698
|
+
"use strict";
|
|
2699
|
+
import_node_crypto3 = require("crypto");
|
|
2700
|
+
import_node_fs8 = require("fs");
|
|
2701
|
+
import_node_os3 = require("os");
|
|
2702
|
+
import_node_path9 = require("path");
|
|
2703
|
+
init_thinking_effort();
|
|
2704
|
+
init_nested_electron_env();
|
|
2705
|
+
init_paths();
|
|
2706
|
+
init_private_file();
|
|
2707
|
+
init_secret_vault();
|
|
2708
|
+
HARNESS_ENV_KEYS = {
|
|
2709
|
+
claude: "ANTHROPIC_API_KEY",
|
|
2710
|
+
codex: "CODEX_API_KEY",
|
|
2711
|
+
cursor: "CURSOR_API_KEY",
|
|
2712
|
+
opencode: null,
|
|
2713
|
+
brightsy: null
|
|
2714
|
+
};
|
|
2715
|
+
DEFAULT_AGENTS = /* @__PURE__ */ new Set([
|
|
2716
|
+
"claude",
|
|
2717
|
+
"codex",
|
|
2718
|
+
"opencode",
|
|
2719
|
+
"brightsy",
|
|
2720
|
+
"cursor"
|
|
2721
|
+
]);
|
|
2722
|
+
GITHUB_GIT_AUTH_MODES = ["auto", "gh", "ssh", "token"];
|
|
2723
|
+
CLOUD_CONNECT_AGENTS = /* @__PURE__ */ new Set([
|
|
2724
|
+
"claude",
|
|
2725
|
+
"codex",
|
|
2726
|
+
"opencode",
|
|
2727
|
+
"cursor"
|
|
2728
|
+
]);
|
|
2729
|
+
ISSUE_SOURCES = /* @__PURE__ */ new Set(["linear", "github"]);
|
|
2730
|
+
GIT_AUTH_MODES = new Set(GITHUB_GIT_AUTH_MODES);
|
|
2731
|
+
EMPTY_SETTINGS = {
|
|
2732
|
+
environment: {},
|
|
2733
|
+
claude: {},
|
|
2734
|
+
codex: {},
|
|
2735
|
+
opencode: {},
|
|
2736
|
+
brightsy: {},
|
|
2737
|
+
integrations: {},
|
|
2738
|
+
defaults: {},
|
|
2739
|
+
advanced: {}
|
|
2740
|
+
};
|
|
2741
|
+
DEFAULT_CLI_BIN = {
|
|
2742
|
+
claude: "claude",
|
|
2743
|
+
codex: "codex",
|
|
2744
|
+
opencode: "opencode",
|
|
2745
|
+
brightsy: "brightsy"
|
|
2746
|
+
};
|
|
2747
|
+
}
|
|
2748
|
+
});
|
|
2749
|
+
|
|
2750
|
+
// src/agents/path.ts
|
|
2751
|
+
function prependPathDir(env, dir) {
|
|
2752
|
+
if (!dir || !(0, import_node_fs9.existsSync)(dir)) return;
|
|
2753
|
+
const current = env.PATH ?? "";
|
|
2754
|
+
const parts = current.split(import_node_path10.delimiter).filter(Boolean);
|
|
2755
|
+
if (parts.includes(dir)) {
|
|
2756
|
+
env.PATH = current;
|
|
2757
|
+
return;
|
|
2758
|
+
}
|
|
2759
|
+
env.PATH = [dir, ...parts].join(import_node_path10.delimiter);
|
|
2760
|
+
}
|
|
2761
|
+
function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os4.homedir)()) {
|
|
2762
|
+
return (0, import_node_path10.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
|
|
2763
|
+
}
|
|
2764
|
+
function isConductorBundledCli(filePath) {
|
|
2765
|
+
const p = (filePath ?? "").replace(/\\/g, "/");
|
|
2766
|
+
return p.includes("/com.conductor.app/bin/") || p.endsWith("/com.conductor.app/bin");
|
|
2767
|
+
}
|
|
2768
|
+
function ensureAgentPath(env = process.env) {
|
|
2769
|
+
const home = env.HOME || env.USERPROFILE || (0, import_node_os4.homedir)();
|
|
2770
|
+
const current = env.PATH ?? "";
|
|
2771
|
+
const parts = current.split(import_node_path10.delimiter).filter(Boolean);
|
|
2772
|
+
const seen = new Set(parts);
|
|
2773
|
+
const extras = [
|
|
2774
|
+
...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path10.join)(home, rel)),
|
|
2775
|
+
"/opt/homebrew/bin",
|
|
2776
|
+
"/usr/local/bin",
|
|
2777
|
+
// Keep after Homebrew/npm so a user-installed CLI still wins.
|
|
2778
|
+
conductorBundledBinDir(home)
|
|
2779
|
+
];
|
|
2780
|
+
for (const dir of extras.reverse()) {
|
|
2781
|
+
if (!dir || seen.has(dir) || !(0, import_node_fs9.existsSync)(dir)) continue;
|
|
2782
|
+
parts.unshift(dir);
|
|
2783
|
+
seen.add(dir);
|
|
2784
|
+
}
|
|
2785
|
+
const next = parts.join(import_node_path10.delimiter);
|
|
2786
|
+
env.PATH = next;
|
|
2787
|
+
return next;
|
|
2788
|
+
}
|
|
2789
|
+
function enrichPathWithNpmGlobalBin(env = process.env) {
|
|
2790
|
+
ensureAgentPath(env);
|
|
2791
|
+
try {
|
|
2792
|
+
const prefix = (0, import_node_child_process2.execFileSync)("npm", ["prefix", "-g"], {
|
|
2793
|
+
encoding: "utf8",
|
|
2794
|
+
env: { ...process.env, ...env },
|
|
2795
|
+
timeout: 8e3,
|
|
2796
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
2797
|
+
}).trim().split(/\r?\n/).find(Boolean);
|
|
2798
|
+
if (prefix) {
|
|
2799
|
+
const binDir = process.platform === "win32" ? prefix : (0, import_node_path10.join)(prefix, "bin");
|
|
2800
|
+
prependPathDir(env, binDir);
|
|
2801
|
+
}
|
|
2802
|
+
} catch {
|
|
2803
|
+
}
|
|
2804
|
+
return env.PATH ?? "";
|
|
2805
|
+
}
|
|
2806
|
+
function posixShellSingleQuote(value) {
|
|
2807
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
2808
|
+
}
|
|
2809
|
+
function resolveCommandBinarySync(command, whichPath) {
|
|
2810
|
+
const trimmed = command.trim();
|
|
2811
|
+
if (!trimmed) return trimmed;
|
|
2812
|
+
const match = /^(\S+)(\s[\s\S]*)?$/.exec(trimmed);
|
|
2813
|
+
if (!match) return trimmed;
|
|
2814
|
+
const bin = match[1];
|
|
2815
|
+
const rest = match[2] ?? "";
|
|
2816
|
+
if (bin.includes("/") || bin.includes("\\")) return trimmed;
|
|
2817
|
+
const abs = whichPath?.trim().split(/\r?\n/).find(Boolean);
|
|
2818
|
+
if (!abs) return trimmed;
|
|
2819
|
+
return `${abs}${rest}`;
|
|
2820
|
+
}
|
|
2821
|
+
function withExportedPath(command, pathValue) {
|
|
2822
|
+
const trimmed = command.trim();
|
|
2823
|
+
if (!trimmed) return trimmed;
|
|
2824
|
+
if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
|
|
2825
|
+
return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
|
|
2826
|
+
}
|
|
2827
|
+
var import_node_fs9, import_node_child_process2, import_node_os4, import_node_path10, EXTRA_BIN_DIRS;
|
|
2828
|
+
var init_path = __esm({
|
|
2829
|
+
"src/agents/path.ts"() {
|
|
2830
|
+
"use strict";
|
|
2831
|
+
import_node_fs9 = require("fs");
|
|
2832
|
+
import_node_child_process2 = require("child_process");
|
|
2833
|
+
import_node_os4 = require("os");
|
|
2834
|
+
import_node_path10 = require("path");
|
|
2835
|
+
EXTRA_BIN_DIRS = [
|
|
2836
|
+
".local/bin",
|
|
2837
|
+
".cargo/bin",
|
|
2838
|
+
".nvm/current/bin",
|
|
2839
|
+
".asdf/shims",
|
|
2840
|
+
".volta/bin",
|
|
2841
|
+
".npm-global/bin",
|
|
2842
|
+
// fnm default alias (common when shell init is skipped)
|
|
2843
|
+
".local/share/fnm/aliases/default/bin",
|
|
2844
|
+
// pnpm / npm global bins (where `@brightsy/cli` typically lands)
|
|
2845
|
+
"Library/pnpm",
|
|
2846
|
+
".pnpm"
|
|
2847
|
+
];
|
|
2848
|
+
}
|
|
2849
|
+
});
|
|
2850
|
+
|
|
2851
|
+
// src/git/run.ts
|
|
2852
|
+
var run_exports = {};
|
|
2853
|
+
__export(run_exports, {
|
|
2854
|
+
gh: () => gh,
|
|
2855
|
+
git: () => git,
|
|
2856
|
+
resolveGhAuthToken: () => resolveGhAuthToken,
|
|
2857
|
+
run: () => run
|
|
2858
|
+
});
|
|
2859
|
+
async function run(file, args, opts) {
|
|
2860
|
+
ensureAgentPath();
|
|
2861
|
+
try {
|
|
2862
|
+
const result = await (0, import_execa.execa)(file, args, {
|
|
2863
|
+
cwd: opts?.cwd,
|
|
2864
|
+
env: { ...process.env, ...opts?.env },
|
|
2865
|
+
reject: opts?.reject ?? true,
|
|
2866
|
+
...opts?.timeoutMs != null ? { timeout: opts.timeoutMs } : {}
|
|
2867
|
+
});
|
|
2868
|
+
return {
|
|
2869
|
+
stdout: result.stdout ?? "",
|
|
2870
|
+
stderr: result.stderr ?? "",
|
|
2871
|
+
exitCode: result.exitCode ?? 0
|
|
2872
|
+
};
|
|
2873
|
+
} catch (err) {
|
|
2874
|
+
const e = err;
|
|
2875
|
+
if (opts?.reject === false) {
|
|
2876
|
+
return {
|
|
2877
|
+
stdout: String(e.stdout ?? ""),
|
|
2878
|
+
stderr: String(e.stderr ?? ""),
|
|
2879
|
+
exitCode: e.exitCode ?? 1
|
|
2880
|
+
};
|
|
2881
|
+
}
|
|
2882
|
+
throw err;
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
async function git(args, cwd, opts) {
|
|
2886
|
+
const prefix = [];
|
|
2887
|
+
if (opts?.config) {
|
|
2888
|
+
for (const [key, value] of Object.entries(opts.config)) {
|
|
2889
|
+
if (!key) continue;
|
|
2890
|
+
prefix.push("-c", `${key}=${value}`);
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
return run("git", ["--no-pager", ...prefix, ...args], {
|
|
2894
|
+
cwd,
|
|
2895
|
+
reject: opts?.reject,
|
|
2896
|
+
timeoutMs: opts?.timeoutMs,
|
|
2897
|
+
// Never block forever on a credential/SSH prompt inside MCP / Electron.
|
|
2898
|
+
env: {
|
|
2899
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
2900
|
+
GIT_ASKPASS: process.env.GIT_ASKPASS || "echo",
|
|
2901
|
+
SSH_ASKPASS: process.env.SSH_ASKPASS || "echo",
|
|
2902
|
+
GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND || "ssh -o BatchMode=yes -o ConnectTimeout=15",
|
|
2903
|
+
GCM_INTERACTIVE: "never",
|
|
2904
|
+
GH_PROMPT_DISABLED: "1",
|
|
2905
|
+
...opts?.env
|
|
2906
|
+
}
|
|
2907
|
+
});
|
|
2835
2908
|
}
|
|
2836
|
-
function
|
|
2837
|
-
return
|
|
2909
|
+
async function gh(args, cwd, opts) {
|
|
2910
|
+
return run("gh", args, {
|
|
2911
|
+
cwd,
|
|
2912
|
+
reject: opts?.reject,
|
|
2913
|
+
timeoutMs: opts?.timeoutMs,
|
|
2914
|
+
env: {
|
|
2915
|
+
GH_PROMPT_DISABLED: "1",
|
|
2916
|
+
GIT_TERMINAL_PROMPT: "0"
|
|
2917
|
+
}
|
|
2918
|
+
});
|
|
2838
2919
|
}
|
|
2839
|
-
function
|
|
2840
|
-
|
|
2920
|
+
async function resolveGhAuthToken(cwd) {
|
|
2921
|
+
const result = await gh(["auth", "token"], cwd, { reject: false, timeoutMs: 8e3 });
|
|
2922
|
+
if (result.exitCode !== 0) return null;
|
|
2923
|
+
const token = result.stdout.trim();
|
|
2924
|
+
return token || null;
|
|
2841
2925
|
}
|
|
2842
|
-
|
|
2843
|
-
|
|
2926
|
+
var import_execa;
|
|
2927
|
+
var init_run = __esm({
|
|
2928
|
+
"src/git/run.ts"() {
|
|
2929
|
+
"use strict";
|
|
2930
|
+
import_execa = require("execa");
|
|
2931
|
+
init_path();
|
|
2932
|
+
}
|
|
2933
|
+
});
|
|
2934
|
+
|
|
2935
|
+
// src/git/git-auth-mode.ts
|
|
2936
|
+
function nonInteractiveGitProcessEnv() {
|
|
2937
|
+
return {
|
|
2938
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
2939
|
+
GIT_ASKPASS: process.env.GIT_ASKPASS?.trim() || "echo",
|
|
2940
|
+
SSH_ASKPASS: process.env.SSH_ASKPASS?.trim() || "echo",
|
|
2941
|
+
GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND?.trim() || "ssh -o BatchMode=yes -o ConnectTimeout=15",
|
|
2942
|
+
GCM_INTERACTIVE: "never",
|
|
2943
|
+
GH_PROMPT_DISABLED: "1"
|
|
2944
|
+
};
|
|
2844
2945
|
}
|
|
2845
|
-
function
|
|
2846
|
-
|
|
2946
|
+
function appendIndexedGitConfig(existing, entries) {
|
|
2947
|
+
const start = Number.parseInt(String(existing?.GIT_CONFIG_COUNT ?? "0"), 10);
|
|
2948
|
+
const count = Number.isFinite(start) && start > 0 ? start : 0;
|
|
2949
|
+
const out = {};
|
|
2950
|
+
entries.forEach((entry, i) => {
|
|
2951
|
+
const n = count + i;
|
|
2952
|
+
out[`GIT_CONFIG_KEY_${n}`] = entry.key;
|
|
2953
|
+
out[`GIT_CONFIG_VALUE_${n}`] = entry.value;
|
|
2954
|
+
});
|
|
2955
|
+
out.GIT_CONFIG_COUNT = String(count + entries.length);
|
|
2956
|
+
return out;
|
|
2847
2957
|
}
|
|
2848
|
-
function
|
|
2849
|
-
|
|
2850
|
-
if (preferred && DEFAULT_AGENTS.has(preferred) && preferred !== "brightsy") {
|
|
2851
|
-
return preferred;
|
|
2852
|
-
}
|
|
2853
|
-
return "cursor";
|
|
2958
|
+
function githubAgentGitEnv(existing) {
|
|
2959
|
+
return appendIndexedGitConfig(existing, HTTPS_REWRITE);
|
|
2854
2960
|
}
|
|
2855
|
-
function
|
|
2856
|
-
const
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2961
|
+
function githubHttpsBearerEnv(existing, token) {
|
|
2962
|
+
const rewrite = githubAgentGitEnv(existing);
|
|
2963
|
+
const header = appendIndexedGitConfig(
|
|
2964
|
+
{ ...existing, ...rewrite },
|
|
2965
|
+
[
|
|
2966
|
+
{
|
|
2967
|
+
key: "http.https://github.com/.extraHeader",
|
|
2968
|
+
value: `AUTHORIZATION: bearer ${token}`
|
|
2969
|
+
}
|
|
2970
|
+
]
|
|
2971
|
+
);
|
|
2972
|
+
return { ...rewrite, ...header };
|
|
2861
2973
|
}
|
|
2862
|
-
function
|
|
2863
|
-
|
|
2974
|
+
function applyGithubGitAuthEnv(existing, opts) {
|
|
2975
|
+
const out = { ...nonInteractiveGitProcessEnv() };
|
|
2976
|
+
if (opts.mode === "ssh") return out;
|
|
2977
|
+
const existingToken = existing?.GH_TOKEN?.trim() || "";
|
|
2978
|
+
const provided = existingToken ? "" : opts.token?.trim() || "";
|
|
2979
|
+
const token = existingToken || provided;
|
|
2980
|
+
Object.assign(
|
|
2981
|
+
out,
|
|
2982
|
+
token ? githubHttpsBearerEnv(existing, token) : githubAgentGitEnv(existing)
|
|
2983
|
+
);
|
|
2984
|
+
if (provided) out.GH_TOKEN = provided;
|
|
2985
|
+
return out;
|
|
2864
2986
|
}
|
|
2865
|
-
function
|
|
2866
|
-
|
|
2867
|
-
if (
|
|
2868
|
-
|
|
2869
|
-
return
|
|
2870
|
-
}
|
|
2871
|
-
|
|
2872
|
-
const override2 = settings.codex.executablePath?.trim();
|
|
2873
|
-
return override2 || fallback;
|
|
2874
|
-
}
|
|
2875
|
-
if (agent === "opencode") {
|
|
2876
|
-
const override2 = settings.opencode.executablePath?.trim();
|
|
2877
|
-
return override2 || fallback;
|
|
2987
|
+
async function resolveGithubAgentToken(mode, cwd) {
|
|
2988
|
+
if (mode === "ssh") return null;
|
|
2989
|
+
if (mode === "token") return getGithubPat();
|
|
2990
|
+
try {
|
|
2991
|
+
return await resolveGhAuthToken(cwd);
|
|
2992
|
+
} catch {
|
|
2993
|
+
return null;
|
|
2878
2994
|
}
|
|
2879
|
-
const override = settings.brightsy.executablePath?.trim();
|
|
2880
|
-
return override || fallback;
|
|
2881
2995
|
}
|
|
2882
|
-
function
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2996
|
+
async function resolveAgentGitAuthEnv(existing, opts) {
|
|
2997
|
+
let mode = "auto";
|
|
2998
|
+
if (opts?.mode) {
|
|
2999
|
+
mode = opts.mode;
|
|
3000
|
+
} else {
|
|
3001
|
+
try {
|
|
3002
|
+
mode = getGithubGitAuthMode();
|
|
3003
|
+
} catch {
|
|
3004
|
+
mode = "auto";
|
|
3005
|
+
}
|
|
2888
3006
|
}
|
|
2889
|
-
|
|
2890
|
-
|
|
3007
|
+
const cwd = opts?.cwd?.trim() || process.cwd();
|
|
3008
|
+
let token = null;
|
|
3009
|
+
try {
|
|
3010
|
+
token = await resolveGithubAgentToken(mode, cwd);
|
|
3011
|
+
} catch {
|
|
3012
|
+
token = null;
|
|
2891
3013
|
}
|
|
2892
|
-
return
|
|
2893
|
-
}
|
|
2894
|
-
function claudeChromeEnabled(settings = loadAppSettings()) {
|
|
2895
|
-
return Boolean(settings.claude.chromeEnabled);
|
|
3014
|
+
return applyGithubGitAuthEnv(existing, { mode, token });
|
|
2896
3015
|
}
|
|
2897
|
-
function
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
3016
|
+
function codexUnattendedGitConfigArgs(sandbox) {
|
|
3017
|
+
const args = [
|
|
3018
|
+
"-c",
|
|
3019
|
+
'shell_environment_policy.inherit="all"',
|
|
3020
|
+
"-c",
|
|
3021
|
+
"shell_environment_policy.ignore_default_excludes=true"
|
|
3022
|
+
];
|
|
3023
|
+
if (sandbox === "workspace-write") {
|
|
3024
|
+
args.push("-c", "sandbox_workspace_write.network_access=true");
|
|
2903
3025
|
}
|
|
2904
|
-
return
|
|
3026
|
+
return args;
|
|
2905
3027
|
}
|
|
2906
|
-
function
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
3028
|
+
function formatGitAuthModeDirective(mode) {
|
|
3029
|
+
switch (mode) {
|
|
3030
|
+
case "gh":
|
|
3031
|
+
return [
|
|
3032
|
+
"Git authentication (Account \u2192 GitHub mode: gh CLI):",
|
|
3033
|
+
"- This process rewrites `git@github.com:` and `ssh://git@github.com/` to HTTPS.",
|
|
3034
|
+
"- `GH_TOKEN` is injected from `gh auth token` (no macOS Keychain prompts). Do not switch remotes to SSH.",
|
|
3035
|
+
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below."
|
|
3036
|
+
].join("\n");
|
|
3037
|
+
case "ssh":
|
|
3038
|
+
return [
|
|
3039
|
+
"Git authentication (Account \u2192 GitHub mode: SSH):",
|
|
3040
|
+
"- Keep SSH remotes (`git@github.com:\u2026`). Do not rewrite them to HTTPS.",
|
|
3041
|
+
"- SSH is batch-mode: it will not prompt for a Keychain password. If push fails with `Permission denied (publickey)`, tell the user to unlock ssh-agent or switch Account \u2192 GitHub to Auto / gh CLI \u2014 do not rewrite remotes yourself.",
|
|
3042
|
+
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below (API still uses `gh`)."
|
|
3043
|
+
].join("\n");
|
|
3044
|
+
case "token":
|
|
3045
|
+
return [
|
|
3046
|
+
"Git authentication (Account \u2192 GitHub mode: personal access token):",
|
|
3047
|
+
"- This process rewrites GitHub SSH remotes to HTTPS.",
|
|
3048
|
+
"- `GH_TOKEN` is set in the environment. Use HTTPS git and `gh`; do not paste the token into commands or chat.",
|
|
3049
|
+
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below."
|
|
3050
|
+
].join("\n");
|
|
3051
|
+
case "auto":
|
|
3052
|
+
default:
|
|
3053
|
+
return [
|
|
3054
|
+
"Git authentication (Account \u2192 GitHub mode: auto):",
|
|
3055
|
+
"- This process rewrites GitHub SSH remotes to HTTPS and authenticates with `GH_TOKEN` from `gh` so git/ssh never prompt the macOS Keychain (required for Slack / unattended Cursor).",
|
|
3056
|
+
"- Do not switch remotes to SSH. Push with `git push -u origin HEAD`.",
|
|
3057
|
+
"- If HTTPS auth fails, tell the user to run `gh auth login` on this Mac or set Account \u2192 GitHub to a PAT \u2014 do not wait for a Keychain dialog."
|
|
3058
|
+
].join("\n");
|
|
2914
3059
|
}
|
|
2915
|
-
return env;
|
|
2916
|
-
}
|
|
2917
|
-
function harnessEnvKey(harness) {
|
|
2918
|
-
return HARNESS_ENV_KEYS[harness];
|
|
2919
3060
|
}
|
|
2920
|
-
var
|
|
2921
|
-
var
|
|
2922
|
-
"src/
|
|
3061
|
+
var HTTPS_REWRITE;
|
|
3062
|
+
var init_git_auth_mode = __esm({
|
|
3063
|
+
"src/git/git-auth-mode.ts"() {
|
|
2923
3064
|
"use strict";
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
HARNESS_ENV_KEYS = {
|
|
2934
|
-
claude: "ANTHROPIC_API_KEY",
|
|
2935
|
-
codex: "CODEX_API_KEY",
|
|
2936
|
-
cursor: "CURSOR_API_KEY",
|
|
2937
|
-
opencode: null,
|
|
2938
|
-
brightsy: null
|
|
2939
|
-
};
|
|
2940
|
-
DEFAULT_AGENTS = /* @__PURE__ */ new Set([
|
|
2941
|
-
"claude",
|
|
2942
|
-
"codex",
|
|
2943
|
-
"opencode",
|
|
2944
|
-
"brightsy",
|
|
2945
|
-
"cursor"
|
|
2946
|
-
]);
|
|
2947
|
-
GITHUB_GIT_AUTH_MODES = ["auto", "gh", "ssh", "token"];
|
|
2948
|
-
CLOUD_CONNECT_AGENTS = /* @__PURE__ */ new Set([
|
|
2949
|
-
"claude",
|
|
2950
|
-
"codex",
|
|
2951
|
-
"opencode",
|
|
2952
|
-
"cursor"
|
|
2953
|
-
]);
|
|
2954
|
-
ISSUE_SOURCES = /* @__PURE__ */ new Set(["linear", "github"]);
|
|
2955
|
-
GIT_AUTH_MODES = new Set(GITHUB_GIT_AUTH_MODES);
|
|
2956
|
-
EMPTY_SETTINGS = {
|
|
2957
|
-
environment: {},
|
|
2958
|
-
claude: {},
|
|
2959
|
-
codex: {},
|
|
2960
|
-
opencode: {},
|
|
2961
|
-
brightsy: {},
|
|
2962
|
-
integrations: {},
|
|
2963
|
-
defaults: {},
|
|
2964
|
-
advanced: {}
|
|
2965
|
-
};
|
|
2966
|
-
DEFAULT_CLI_BIN = {
|
|
2967
|
-
claude: "claude",
|
|
2968
|
-
codex: "codex",
|
|
2969
|
-
opencode: "opencode",
|
|
2970
|
-
brightsy: "brightsy"
|
|
2971
|
-
};
|
|
3065
|
+
init_app_settings();
|
|
3066
|
+
init_run();
|
|
3067
|
+
HTTPS_REWRITE = [
|
|
3068
|
+
{ key: "url.https://github.com/.insteadOf", value: "git@github.com:" },
|
|
3069
|
+
{ key: "url.https://github.com/.insteadOf", value: "ssh://git@github.com/" },
|
|
3070
|
+
// Empty helper disables ~/.gitconfig osxkeychain so GUI agents cannot pop
|
|
3071
|
+
// "git-credential-osxkeychain wants to use the keychain".
|
|
3072
|
+
{ key: "credential.helper", value: "" }
|
|
3073
|
+
];
|
|
2972
3074
|
}
|
|
2973
3075
|
});
|
|
2974
3076
|
|
|
@@ -3429,7 +3531,7 @@ async function originGhRepoEnv(cwd, opts) {
|
|
|
3429
3531
|
await ensureGhPreferOrigin(cwd);
|
|
3430
3532
|
const slug = await resolveGithubRepoSlug(cwd);
|
|
3431
3533
|
const mode = opts?.mode ?? getGithubGitAuthMode();
|
|
3432
|
-
const token = mode === "token" ? getGithubPat() : null;
|
|
3534
|
+
const token = mode === "token" ? getGithubPat() : mode === "ssh" ? null : await resolveGhAuthToken(cwd);
|
|
3433
3535
|
return {
|
|
3434
3536
|
...applyGithubGitAuthEnv(opts?.env, { mode, token }),
|
|
3435
3537
|
...slug ? { GH_REPO: slug } : {}
|
|
@@ -5605,7 +5707,12 @@ function applyNodeLaunch(launch, args) {
|
|
|
5605
5707
|
return { file: launch.file, args, env: launch.env };
|
|
5606
5708
|
}
|
|
5607
5709
|
const wrapped = wrapElectronAsNodeLaunch(launch.file, args);
|
|
5608
|
-
|
|
5710
|
+
if (process.platform === "win32") {
|
|
5711
|
+
return { file: wrapped.file, args: wrapped.args, env: launch.env };
|
|
5712
|
+
}
|
|
5713
|
+
const env = { ...launch.env };
|
|
5714
|
+
delete env.ELECTRON_RUN_AS_NODE;
|
|
5715
|
+
return { file: wrapped.file, args: wrapped.args, env };
|
|
5609
5716
|
}
|
|
5610
5717
|
async function resolveNodeLaunch(scriptPath) {
|
|
5611
5718
|
if (isAsarPath(scriptPath)) {
|
|
@@ -5782,6 +5889,10 @@ async function buildInjectedMcpServers(opts) {
|
|
|
5782
5889
|
if (orchId) {
|
|
5783
5890
|
sideboard.env.SIDEBOARD_ORCHESTRATOR_THREAD_ID = orchId;
|
|
5784
5891
|
}
|
|
5892
|
+
try {
|
|
5893
|
+
Object.assign(sideboard.env, await resolveAgentGitAuthEnv(sideboard.env));
|
|
5894
|
+
} catch {
|
|
5895
|
+
}
|
|
5785
5896
|
servers.push(sideboard);
|
|
5786
5897
|
}
|
|
5787
5898
|
if (opts.includeBrightsy && isBrightsyConnected()) {
|
|
@@ -5804,10 +5915,19 @@ async function buildInjectedMcpServers(opts) {
|
|
|
5804
5915
|
function toCursorMcpServers(servers) {
|
|
5805
5916
|
const out = {};
|
|
5806
5917
|
for (const s of servers) {
|
|
5918
|
+
const env = s.env ? { ...s.env } : void 0;
|
|
5919
|
+
if (env) delete env.ELECTRON_RUN_AS_NODE;
|
|
5920
|
+
let command = s.command;
|
|
5921
|
+
let args = s.args;
|
|
5922
|
+
if (process.platform !== "win32" && !isStrippedElectronLaunch(command, args)) {
|
|
5923
|
+
const wrapped = wrapElectronAsNodeLaunch(command, args ?? []);
|
|
5924
|
+
command = wrapped.file;
|
|
5925
|
+
args = wrapped.args;
|
|
5926
|
+
}
|
|
5807
5927
|
out[s.name] = {
|
|
5808
|
-
command
|
|
5809
|
-
...
|
|
5810
|
-
...
|
|
5928
|
+
command,
|
|
5929
|
+
...args && args.length > 0 ? { args } : {},
|
|
5930
|
+
...env && Object.keys(env).length > 0 ? { env } : {}
|
|
5811
5931
|
};
|
|
5812
5932
|
}
|
|
5813
5933
|
return out;
|
|
@@ -5874,6 +5994,8 @@ var init_injected_mcp = __esm({
|
|
|
5874
5994
|
init_app_settings();
|
|
5875
5995
|
init_paths();
|
|
5876
5996
|
init_node_launch();
|
|
5997
|
+
init_nested_electron_env();
|
|
5998
|
+
init_git_auth_mode();
|
|
5877
5999
|
import_meta = {};
|
|
5878
6000
|
SIDEBOARD_MCP_ALLOWED_TOOLS = [
|
|
5879
6001
|
"mcp__sideboard",
|
|
@@ -6413,6 +6535,7 @@ var init_codex = __esm({
|
|
|
6413
6535
|
init_global_workspace();
|
|
6414
6536
|
init_error_detail();
|
|
6415
6537
|
init_usage();
|
|
6538
|
+
init_git_auth_mode();
|
|
6416
6539
|
init_injected_mcp();
|
|
6417
6540
|
init_turn_input();
|
|
6418
6541
|
init_types();
|
|
@@ -6504,6 +6627,8 @@ var init_codex = __esm({
|
|
|
6504
6627
|
// `codex exec` rejects `--ask-for-approval` (global-only on newer CLIs).
|
|
6505
6628
|
"-c",
|
|
6506
6629
|
'approval_policy="never"',
|
|
6630
|
+
// Seatbelt cannot use the login Keychain; default policy also strips GH_TOKEN.
|
|
6631
|
+
...codexUnattendedGitConfigArgs(mode.codexSandbox),
|
|
6507
6632
|
...model ? ["--model", model] : [],
|
|
6508
6633
|
...mcpOverrides
|
|
6509
6634
|
];
|
|
@@ -8783,6 +8908,7 @@ init_error_detail();
|
|
|
8783
8908
|
var import_node_readline = require("readline");
|
|
8784
8909
|
var import_execa2 = require("execa");
|
|
8785
8910
|
init_worktree();
|
|
8911
|
+
init_git_auth_mode();
|
|
8786
8912
|
init_app_settings();
|
|
8787
8913
|
init_global_workspace();
|
|
8788
8914
|
init_brightsy();
|
|
@@ -9045,14 +9171,16 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
9045
9171
|
);
|
|
9046
9172
|
}
|
|
9047
9173
|
const env = childEnvWithAppSettings(cmd.env);
|
|
9048
|
-
|
|
9049
|
-
|
|
9174
|
+
try {
|
|
9175
|
+
if (isOrchestratorThread(thread)) {
|
|
9176
|
+
Object.assign(env, await resolveAgentGitAuthEnv(env));
|
|
9177
|
+
} else {
|
|
9050
9178
|
const originEnv = await originGhRepoEnv(thread.worktreePath, { env });
|
|
9051
9179
|
Object.assign(env, originEnv);
|
|
9052
|
-
} catch (err) {
|
|
9053
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
9054
|
-
console.warn(`[sideboard] originGhRepoEnv failed (${thread.worktreePath}): ${detail}`);
|
|
9055
9180
|
}
|
|
9181
|
+
} catch (err) {
|
|
9182
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
9183
|
+
console.warn(`[sideboard] git auth env failed (${thread.worktreePath}): ${detail}`);
|
|
9056
9184
|
}
|
|
9057
9185
|
const child = (0, import_execa2.execa)(cmd.file, cmd.args, {
|
|
9058
9186
|
cwd: cmd.cwd,
|
|
@@ -9266,6 +9394,7 @@ var import_execa3 = require("execa");
|
|
|
9266
9394
|
var import_node_readline2 = require("readline");
|
|
9267
9395
|
init_settings();
|
|
9268
9396
|
init_nested_electron_env();
|
|
9397
|
+
init_git_auth_mode();
|
|
9269
9398
|
init_nested_electron_env();
|
|
9270
9399
|
var PORT_RANGE_SIZE = 10;
|
|
9271
9400
|
function matchSimpleGlob(pattern, name) {
|
|
@@ -9439,6 +9568,10 @@ async function spawnWorkspaceScript(command, opts) {
|
|
|
9439
9568
|
},
|
|
9440
9569
|
loginEnv
|
|
9441
9570
|
);
|
|
9571
|
+
try {
|
|
9572
|
+
Object.assign(env, await resolveAgentGitAuthEnv(env, { cwd: opts.worktreePath }));
|
|
9573
|
+
} catch {
|
|
9574
|
+
}
|
|
9442
9575
|
const shell = process.platform === "darwin" ? "zsh" : "bash";
|
|
9443
9576
|
const child = (0, import_execa3.execa)(shell, ["-lc", command], {
|
|
9444
9577
|
cwd: opts.worktreePath,
|
|
@@ -13412,7 +13545,7 @@ var Orchestrator = class {
|
|
|
13412
13545
|
}
|
|
13413
13546
|
let lastStderr = summarizeTurnStderr(stderrTail);
|
|
13414
13547
|
let detail = lastStderr || (exitCode !== 0 ? fallbackTurnFailDetail(assistantText) : "");
|
|
13415
|
-
if (exitCode !== 0 && !assistantText && parts.length === 0 && !this.stoppedTurns.has(threadId) && looksLikeInvalidAgentSession(detail) && this.requireThread(threadId).sessionId && this.requireThread(threadId).agent !== "
|
|
13548
|
+
if (exitCode !== 0 && !assistantText && parts.length === 0 && !this.stoppedTurns.has(threadId) && looksLikeInvalidAgentSession(detail) && this.requireThread(threadId).sessionId && this.requireThread(threadId).agent !== "brightsy") {
|
|
13416
13549
|
updateThread(threadId, { sessionId: null });
|
|
13417
13550
|
pushTurnStderr(
|
|
13418
13551
|
stderrTail,
|