@sideboard-ai/core 0.1.110 → 0.1.115
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 +32 -23
- package/dist/agents/cursor-runner.js +3 -3
- package/dist/{agents-WK54VP7J.js → agents-3X3EFCQY.js} +7 -7
- package/dist/{agents-MQDW3YXL.js → agents-AHAFC6FR.js} +10 -10
- package/dist/{chunk-4EWPKYOU.js → chunk-4OJMZ6P2.js} +2 -2
- package/dist/{chunk-VOJSO3RM.js → chunk-66XTXHR3.js} +277 -49
- package/dist/{chunk-KQBI5HNT.js → chunk-7WC5UWEB.js} +2 -2
- package/dist/{chunk-WIHKHR5R.js → chunk-AXQ4ZWHK.js} +5 -0
- package/dist/{chunk-RSIWPLRG.js → chunk-C6OBY6IC.js} +268 -27
- package/dist/{chunk-EAAB4EK5.js → chunk-DCNR7NAL.js} +44 -32
- package/dist/{chunk-LGXBYZZA.js → chunk-DVM4ID64.js} +69 -13
- package/dist/{chunk-2GO3YKBA.js → chunk-EKIDHL2T.js} +4 -4
- package/dist/{chunk-C4KHDW3U.js → chunk-FZCIQYNQ.js} +1 -1
- package/dist/{chunk-7KWYXGIU.js → chunk-K3TIQXOH.js} +2 -2
- package/dist/{chunk-3KETJKYA.js → chunk-KPIYENTF.js} +69 -13
- package/dist/{chunk-XOZDAVOP.js → chunk-MZ6HJ7VL.js} +52 -35
- package/dist/{chunk-3UOKB6VQ.js → chunk-SLU5JVKD.js} +282 -228
- package/dist/{chunk-VOD3HFLP.js → chunk-XOYQ7LNQ.js} +2 -2
- package/dist/{chunk-7YKXHBIW.js → chunk-YMRT2DU6.js} +3 -3
- package/dist/{chunk-YXDR43ZC.js → chunk-ZMROW673.js} +5 -5
- package/dist/{chunk-YFAXVUY2.js → chunk-ZRCX43LS.js} +2 -2
- package/dist/{chunk-AROMOP3C.js → chunk-ZYEFCSZJ.js} +2 -2
- package/dist/{connected-teams-M5XNXRI5.js → connected-teams-O6D4PM7A.js} +2 -2
- package/dist/{connected-teams-J4I5AKMR.js → connected-teams-ZCOU6KCD.js} +2 -2
- package/dist/{coordinator-prompt-AR66L3N4.js → coordinator-prompt-4KCALEKD.js} +3 -3
- package/dist/{coordinator-prompt-BHMLWL64.js → coordinator-prompt-FML4I5AR.js} +3 -3
- package/dist/{global-workspace-XSUFEIAQ.js → global-workspace-CSWABOG5.js} +4 -4
- package/dist/{global-workspace-SKFODUQQ.js → global-workspace-H4YNASM6.js} +4 -4
- package/dist/index.cjs +825 -443
- package/dist/index.d.cts +53 -1
- package/dist/index.d.ts +53 -1
- package/dist/index.js +33 -15
- package/dist/mcp/run-stdio.cjs +947 -644
- package/dist/mcp/run-stdio.js +18 -14
- package/dist/{orchestrator-SCATSB3O.js → orchestrator-GKLYKLRC.js} +8 -8
- package/dist/{orchestrator-FCZVCKBK.js → orchestrator-TXASYNHT.js} +10 -10
- package/dist/{run-XKTAJRWF.js → run-USF6FRKV.js} +3 -1
- package/dist/{run-CFKZPY7F.js → run-XQKGHQZ2.js} +3 -1
- package/dist/{workspaces-XAQVKTLO.js → workspaces-HJ3EVATC.js} +5 -5
- package/dist/{workspaces-HV3J4TTW.js → workspaces-QG6PGFQR.js} +5 -5
- package/dist/{worktree-XFJED3VU.js → worktree-IW3BX26B.js} +2 -2
- package/dist/{worktree-N2EV24EE.js → worktree-OTFQO2W7.js} +2 -2
- package/package.json +1 -1
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -1419,7 +1419,7 @@ function extractJsonErrorMessage(obj) {
|
|
|
1419
1419
|
}
|
|
1420
1420
|
function isPinnedStderrLine(line) {
|
|
1421
1421
|
if (/^\s*at\s/.test(line)) return false;
|
|
1422
|
-
return /cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|cursor startup failed
|
|
1422
|
+
return /cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|cursor startup failed:|FATAL ERROR|heap out of memory|javascript heap|OOMErrorHandler|FatalProcessOutOfMemory/i.test(
|
|
1423
1423
|
line
|
|
1424
1424
|
);
|
|
1425
1425
|
}
|
|
@@ -1442,12 +1442,17 @@ function looksLikeMinifiedJsDump(line) {
|
|
|
1442
1442
|
function looksLikeNestedElectronCrash(line) {
|
|
1443
1443
|
return /HasCustomHostObject|ElectronInitializeICUandStartNode/i.test(line);
|
|
1444
1444
|
}
|
|
1445
|
-
function
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1445
|
+
function looksLikeNativeEventLoopCrash(text4) {
|
|
1446
|
+
return /uv_run|uv__io_poll|SpinEventLoopInternal/i.test(text4);
|
|
1447
|
+
}
|
|
1448
|
+
function looksLikeV8Oom(text4) {
|
|
1449
|
+
return /javascript heap|reached heap limit|OOMErrorHandler|FatalProcessOutOfMemory|Allocation failed - JavaScript heap/i.test(
|
|
1450
|
+
text4
|
|
1451
|
+
);
|
|
1452
|
+
}
|
|
1453
|
+
function looksLikeHomebrewLibuvCrash(text4) {
|
|
1454
|
+
if (!looksLikeNativeEventLoopCrash(text4)) return false;
|
|
1455
|
+
return /Cellar\/(?:libuv|node)|libuv\.\d+\.dylib/i.test(text4);
|
|
1451
1456
|
}
|
|
1452
1457
|
function clipStderr(text4, maxChars) {
|
|
1453
1458
|
const trimmed = text4.trim();
|
|
@@ -1461,7 +1466,12 @@ function summarizeTurnStderr(tail, maxChars = 500) {
|
|
|
1461
1466
|
const cursorRunFailed = [...tail].reverse().find((line) => /^cursor run failed\b/i.test(line.trim()));
|
|
1462
1467
|
if (cursorRunFailed) return clipStderr(cursorRunFailed, maxChars);
|
|
1463
1468
|
if (tail.some(looksLikeNestedElectronCrash)) return NESTED_ELECTRON_SUMMARY;
|
|
1464
|
-
|
|
1469
|
+
const blob = tail.join("\n");
|
|
1470
|
+
if (looksLikeV8Oom(blob)) return V8_OOM_SUMMARY;
|
|
1471
|
+
if (looksLikeHomebrewLibuvCrash(blob)) return HOMEBREW_LIBUV_SUMMARY;
|
|
1472
|
+
if (looksLikeNativeEventLoopCrash(blob)) {
|
|
1473
|
+
return BUNDLED_NODE_CRASH_SUMMARY;
|
|
1474
|
+
}
|
|
1465
1475
|
if (tail.some(
|
|
1466
1476
|
(line) => /\[resource_exhausted\]|resource_exhausted/i.test(line) || /findFilesWithRipgrep/.test(line)
|
|
1467
1477
|
)) {
|
|
@@ -1487,15 +1497,17 @@ function looksLikeInvalidAgentSession(text4) {
|
|
|
1487
1497
|
function looksLikeRetryableRunnerCrash(text4) {
|
|
1488
1498
|
if (looksLikeAgentFailureMessage(text4)) return false;
|
|
1489
1499
|
if (looksLikeInvalidAgentSession(text4)) return false;
|
|
1500
|
+
if (looksLikeV8Oom(text4)) return false;
|
|
1490
1501
|
const lower = text4.trim().toLowerCase();
|
|
1491
1502
|
if (/cannot find (?:package|module)|err_module_not_found/.test(lower)) return false;
|
|
1492
1503
|
if (!lower) return true;
|
|
1493
|
-
return /uv_run|spineventloopinternal|libuv|homebrew node \+ shared libuv|hascustomhostobject|electroninitializeicuandstartnode|nested chromium|truncated crash dump|connection stalled|sig(?:segv|abrt|ill)|segmentation fault|illegal instruction|fatal error/.test(
|
|
1504
|
+
return /uv_run|spineventloopinternal|libuv|homebrew node \+ shared libuv|cursor runner crashed in node|hascustomhostobject|electroninitializeicuandstartnode|nested chromium|truncated crash dump|connection stalled|sig(?:segv|abrt|ill)|segmentation fault|illegal instruction|fatal error/.test(
|
|
1494
1505
|
lower
|
|
1495
1506
|
);
|
|
1496
1507
|
}
|
|
1497
1508
|
function shouldRetryFailedAgentTurn(detail, opts) {
|
|
1498
1509
|
if (looksLikeInvalidAgentSession(detail) && opts.hasSession) return true;
|
|
1510
|
+
if (looksLikeV8Oom(detail) && opts.hasSession) return true;
|
|
1499
1511
|
return looksLikeRetryableRunnerCrash(detail);
|
|
1500
1512
|
}
|
|
1501
1513
|
function looksLikeAgentFailureMessage(text4) {
|
|
@@ -1542,9 +1554,15 @@ function humanizeAgentFailDetail(detail) {
|
|
|
1542
1554
|
if (/hascustomhostobject|electroninitializeicuandstartnode|nested chromium/i.test(lower)) {
|
|
1543
1555
|
return `${raw} \u2014 retry the turn; if it keeps failing, pick another agent.`;
|
|
1544
1556
|
}
|
|
1545
|
-
if (/
|
|
1557
|
+
if (looksLikeV8Oom(raw) || /javascript heap out of memory/i.test(lower)) {
|
|
1558
|
+
return /ran out of memory/i.test(raw) ? raw : V8_OOM_SUMMARY;
|
|
1559
|
+
}
|
|
1560
|
+
if (/homebrew node \+ shared libuv|Cellar\/(?:libuv|node)|libuv\.\d+\.dylib/i.test(raw)) {
|
|
1546
1561
|
return /brew install node@22/i.test(raw) ? raw : `${raw} \u2014 install Node 22 LTS (\`brew install node@22\`) and retry.`;
|
|
1547
1562
|
}
|
|
1563
|
+
if (/uv_run|spineventloopinternal|uv__io_poll|cursor runner crashed in node/i.test(lower)) {
|
|
1564
|
+
return /retry the turn/i.test(raw) ? raw : BUNDLED_NODE_CRASH_SUMMARY;
|
|
1565
|
+
}
|
|
1548
1566
|
if (/corrupt local agent checkpoint|missing root blob|truncated crash dump/.test(lower)) {
|
|
1549
1567
|
return `${raw} \u2014 retry the turn (Sideboard will start a fresh Cursor session).`;
|
|
1550
1568
|
}
|
|
@@ -1574,17 +1592,266 @@ function formatTurnExitError(exitCode, stderrSummary) {
|
|
|
1574
1592
|
if (looksLikeAgentFailureMessage(raw)) return detail;
|
|
1575
1593
|
return `exit ${code}: ${detail}`;
|
|
1576
1594
|
}
|
|
1577
|
-
var NODE_VERSION_FOOTER, NESTED_ELECTRON_SUMMARY, HOMEBREW_LIBUV_SUMMARY, MINIFIED_DUMP_SUMMARY;
|
|
1595
|
+
var NODE_VERSION_FOOTER, NESTED_ELECTRON_SUMMARY, HOMEBREW_LIBUV_SUMMARY, BUNDLED_NODE_CRASH_SUMMARY, V8_OOM_SUMMARY, MINIFIED_DUMP_SUMMARY;
|
|
1578
1596
|
var init_error_detail = __esm({
|
|
1579
1597
|
"src/agents/error-detail.ts"() {
|
|
1580
1598
|
"use strict";
|
|
1581
1599
|
NODE_VERSION_FOOTER = /^Node\.js v\d+/i;
|
|
1582
1600
|
NESTED_ELECTRON_SUMMARY = "Cursor local agent crashed at Electron startup (nested Chromium / HasCustomHostObject)";
|
|
1583
1601
|
HOMEBREW_LIBUV_SUMMARY = "Cursor runner crashed in Node (Homebrew Node + shared libuv). Install Node 22 LTS (`brew install node@22`) and retry.";
|
|
1602
|
+
BUNDLED_NODE_CRASH_SUMMARY = "Cursor runner crashed in Node. Retry the turn.";
|
|
1603
|
+
V8_OOM_SUMMARY = "Agent ran out of memory (JavaScript heap). If it keeps happening, exclude large files from the project folder.";
|
|
1584
1604
|
MINIFIED_DUMP_SUMMARY = "Cursor local agent crashed during startup (truncated crash dump)";
|
|
1585
1605
|
}
|
|
1586
1606
|
});
|
|
1587
1607
|
|
|
1608
|
+
// src/agents/path.ts
|
|
1609
|
+
function prependPathDir(env, dir) {
|
|
1610
|
+
if (!dir || !(0, import_node_fs10.existsSync)(dir)) return;
|
|
1611
|
+
const current = env.PATH ?? "";
|
|
1612
|
+
const parts = current.split(import_node_path10.delimiter).filter(Boolean);
|
|
1613
|
+
if (parts.includes(dir)) {
|
|
1614
|
+
env.PATH = current;
|
|
1615
|
+
return;
|
|
1616
|
+
}
|
|
1617
|
+
env.PATH = [dir, ...parts].join(import_node_path10.delimiter);
|
|
1618
|
+
}
|
|
1619
|
+
function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os3.homedir)()) {
|
|
1620
|
+
return (0, import_node_path10.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
|
|
1621
|
+
}
|
|
1622
|
+
function isConductorBundledCli(filePath) {
|
|
1623
|
+
const p = (filePath ?? "").replace(/\\/g, "/");
|
|
1624
|
+
return p.includes("/com.conductor.app/bin/") || p.endsWith("/com.conductor.app/bin");
|
|
1625
|
+
}
|
|
1626
|
+
function ensureAgentPath(env = process.env) {
|
|
1627
|
+
const home = env.HOME || env.USERPROFILE || (0, import_node_os3.homedir)();
|
|
1628
|
+
const current = env.PATH ?? "";
|
|
1629
|
+
const parts = current.split(import_node_path10.delimiter).filter(Boolean);
|
|
1630
|
+
const seen = new Set(parts);
|
|
1631
|
+
const extras = [
|
|
1632
|
+
...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path10.join)(home, rel)),
|
|
1633
|
+
"/opt/homebrew/bin",
|
|
1634
|
+
"/usr/local/bin",
|
|
1635
|
+
// Keep after Homebrew/npm so a user-installed CLI still wins.
|
|
1636
|
+
conductorBundledBinDir(home)
|
|
1637
|
+
];
|
|
1638
|
+
for (const dir of extras.reverse()) {
|
|
1639
|
+
if (!dir || seen.has(dir) || !(0, import_node_fs10.existsSync)(dir)) continue;
|
|
1640
|
+
parts.unshift(dir);
|
|
1641
|
+
seen.add(dir);
|
|
1642
|
+
}
|
|
1643
|
+
const next = parts.join(import_node_path10.delimiter);
|
|
1644
|
+
env.PATH = next;
|
|
1645
|
+
return next;
|
|
1646
|
+
}
|
|
1647
|
+
function enrichPathWithNpmGlobalBin(env = process.env) {
|
|
1648
|
+
ensureAgentPath(env);
|
|
1649
|
+
try {
|
|
1650
|
+
const prefix = (0, import_node_child_process2.execFileSync)("npm", ["prefix", "-g"], {
|
|
1651
|
+
encoding: "utf8",
|
|
1652
|
+
env: { ...process.env, ...env },
|
|
1653
|
+
timeout: 8e3,
|
|
1654
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1655
|
+
}).trim().split(/\r?\n/).find(Boolean);
|
|
1656
|
+
if (prefix) {
|
|
1657
|
+
const binDir = process.platform === "win32" ? prefix : (0, import_node_path10.join)(prefix, "bin");
|
|
1658
|
+
prependPathDir(env, binDir);
|
|
1659
|
+
}
|
|
1660
|
+
} catch {
|
|
1661
|
+
}
|
|
1662
|
+
return env.PATH ?? "";
|
|
1663
|
+
}
|
|
1664
|
+
function posixShellSingleQuote(value) {
|
|
1665
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
1666
|
+
}
|
|
1667
|
+
function resolveCommandBinarySync(command, whichPath) {
|
|
1668
|
+
const trimmed = command.trim();
|
|
1669
|
+
if (!trimmed) return trimmed;
|
|
1670
|
+
const match = /^(\S+)(\s[\s\S]*)?$/.exec(trimmed);
|
|
1671
|
+
if (!match) return trimmed;
|
|
1672
|
+
const bin = match[1];
|
|
1673
|
+
const rest = match[2] ?? "";
|
|
1674
|
+
if (bin.includes("/") || bin.includes("\\")) return trimmed;
|
|
1675
|
+
const abs = whichPath?.trim().split(/\r?\n/).find(Boolean);
|
|
1676
|
+
if (!abs) return trimmed;
|
|
1677
|
+
return `${abs}${rest}`;
|
|
1678
|
+
}
|
|
1679
|
+
function withExportedPath(command, pathValue) {
|
|
1680
|
+
const trimmed = command.trim();
|
|
1681
|
+
if (!trimmed) return trimmed;
|
|
1682
|
+
if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
|
|
1683
|
+
return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
|
|
1684
|
+
}
|
|
1685
|
+
var import_node_fs10, import_node_child_process2, import_node_os3, import_node_path10, EXTRA_BIN_DIRS;
|
|
1686
|
+
var init_path = __esm({
|
|
1687
|
+
"src/agents/path.ts"() {
|
|
1688
|
+
"use strict";
|
|
1689
|
+
import_node_fs10 = require("fs");
|
|
1690
|
+
import_node_child_process2 = require("child_process");
|
|
1691
|
+
import_node_os3 = require("os");
|
|
1692
|
+
import_node_path10 = require("path");
|
|
1693
|
+
EXTRA_BIN_DIRS = [
|
|
1694
|
+
".local/bin",
|
|
1695
|
+
".cargo/bin",
|
|
1696
|
+
".nvm/current/bin",
|
|
1697
|
+
".asdf/shims",
|
|
1698
|
+
".volta/bin",
|
|
1699
|
+
".npm-global/bin",
|
|
1700
|
+
// fnm default alias (common when shell init is skipped)
|
|
1701
|
+
".local/share/fnm/aliases/default/bin",
|
|
1702
|
+
// pnpm / npm global bins (where `@brightsy/cli` typically lands)
|
|
1703
|
+
"Library/pnpm",
|
|
1704
|
+
".pnpm"
|
|
1705
|
+
];
|
|
1706
|
+
}
|
|
1707
|
+
});
|
|
1708
|
+
|
|
1709
|
+
// src/git/stale-lock.ts
|
|
1710
|
+
function isIndexLockError(text4) {
|
|
1711
|
+
return /Unable to create ['"][^'"]*index\.lock['"]: File exists/i.test(text4);
|
|
1712
|
+
}
|
|
1713
|
+
function clearStaleIndexLock(gitDir, maxAgeMs = STALE_INDEX_LOCK_MS, now = Date.now()) {
|
|
1714
|
+
const lockPath = (0, import_node_path11.join)(gitDir, "index.lock");
|
|
1715
|
+
try {
|
|
1716
|
+
if (!(0, import_node_fs11.existsSync)(lockPath)) return null;
|
|
1717
|
+
if (now - (0, import_node_fs11.statSync)(lockPath).mtimeMs < maxAgeMs) return null;
|
|
1718
|
+
(0, import_node_fs11.unlinkSync)(lockPath);
|
|
1719
|
+
return lockPath;
|
|
1720
|
+
} catch {
|
|
1721
|
+
return null;
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
function clearStaleIndexLocks(gitDirs, maxAgeMs = STALE_INDEX_LOCK_MS) {
|
|
1725
|
+
const now = Date.now();
|
|
1726
|
+
const removed = [];
|
|
1727
|
+
for (const dir of new Set(gitDirs)) {
|
|
1728
|
+
const cleared = clearStaleIndexLock(dir, maxAgeMs, now);
|
|
1729
|
+
if (cleared) removed.push(cleared);
|
|
1730
|
+
}
|
|
1731
|
+
return removed;
|
|
1732
|
+
}
|
|
1733
|
+
var import_node_fs11, import_node_path11, STALE_INDEX_LOCK_MS;
|
|
1734
|
+
var init_stale_lock = __esm({
|
|
1735
|
+
"src/git/stale-lock.ts"() {
|
|
1736
|
+
"use strict";
|
|
1737
|
+
import_node_fs11 = require("fs");
|
|
1738
|
+
import_node_path11 = require("path");
|
|
1739
|
+
STALE_INDEX_LOCK_MS = 2e4;
|
|
1740
|
+
}
|
|
1741
|
+
});
|
|
1742
|
+
|
|
1743
|
+
// src/git/run.ts
|
|
1744
|
+
var run_exports = {};
|
|
1745
|
+
__export(run_exports, {
|
|
1746
|
+
gh: () => gh,
|
|
1747
|
+
git: () => git,
|
|
1748
|
+
resolveGhAuthToken: () => resolveGhAuthToken,
|
|
1749
|
+
resolveGitDirsForLockRecovery: () => resolveGitDirsForLockRecovery,
|
|
1750
|
+
run: () => run
|
|
1751
|
+
});
|
|
1752
|
+
async function run(file, args, opts) {
|
|
1753
|
+
ensureAgentPath();
|
|
1754
|
+
try {
|
|
1755
|
+
const result = await (0, import_execa2.execa)(file, args, {
|
|
1756
|
+
cwd: opts?.cwd,
|
|
1757
|
+
env: { ...process.env, ...opts?.env },
|
|
1758
|
+
reject: opts?.reject ?? true,
|
|
1759
|
+
...opts?.timeoutMs != null ? { timeout: opts.timeoutMs } : {}
|
|
1760
|
+
});
|
|
1761
|
+
return {
|
|
1762
|
+
stdout: result.stdout ?? "",
|
|
1763
|
+
stderr: result.stderr ?? "",
|
|
1764
|
+
exitCode: result.exitCode ?? 0
|
|
1765
|
+
};
|
|
1766
|
+
} catch (err) {
|
|
1767
|
+
const e = err;
|
|
1768
|
+
if (opts?.reject === false) {
|
|
1769
|
+
return {
|
|
1770
|
+
stdout: String(e.stdout ?? ""),
|
|
1771
|
+
stderr: String(e.stderr ?? ""),
|
|
1772
|
+
exitCode: e.exitCode ?? 1
|
|
1773
|
+
};
|
|
1774
|
+
}
|
|
1775
|
+
throw err;
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
async function resolveGitDirsForLockRecovery(cwd, env = {}) {
|
|
1779
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
1780
|
+
const [gitDir, commonDir] = await Promise.all([
|
|
1781
|
+
run("git", ["rev-parse", "--absolute-git-dir"], { cwd, reject: false, env, timeoutMs: 5e3 }),
|
|
1782
|
+
run("git", ["rev-parse", "--path-format=absolute", "--git-common-dir"], {
|
|
1783
|
+
cwd,
|
|
1784
|
+
reject: false,
|
|
1785
|
+
env,
|
|
1786
|
+
timeoutMs: 5e3
|
|
1787
|
+
})
|
|
1788
|
+
]);
|
|
1789
|
+
if (gitDir.exitCode === 0 && gitDir.stdout.trim()) dirs.add(gitDir.stdout.trim());
|
|
1790
|
+
if (commonDir.exitCode === 0 && commonDir.stdout.trim()) dirs.add(commonDir.stdout.trim());
|
|
1791
|
+
return [...dirs];
|
|
1792
|
+
}
|
|
1793
|
+
async function git(args, cwd, opts) {
|
|
1794
|
+
const prefix = [];
|
|
1795
|
+
if (opts?.config) {
|
|
1796
|
+
for (const [key, value] of Object.entries(opts.config)) {
|
|
1797
|
+
if (!key) continue;
|
|
1798
|
+
prefix.push("-c", `${key}=${value}`);
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
const gitArgs = ["--no-pager", ...prefix, ...args];
|
|
1802
|
+
const env = {
|
|
1803
|
+
// Never block forever on a credential/SSH prompt inside MCP / Electron.
|
|
1804
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
1805
|
+
GIT_ASKPASS: process.env.GIT_ASKPASS || "echo",
|
|
1806
|
+
SSH_ASKPASS: process.env.SSH_ASKPASS || "echo",
|
|
1807
|
+
GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND || "ssh -o BatchMode=yes -o ConnectTimeout=15",
|
|
1808
|
+
GCM_INTERACTIVE: "never",
|
|
1809
|
+
GH_PROMPT_DISABLED: "1",
|
|
1810
|
+
...opts?.env
|
|
1811
|
+
};
|
|
1812
|
+
let result = await run("git", gitArgs, { cwd, reject: false, timeoutMs: opts?.timeoutMs, env });
|
|
1813
|
+
if (result.exitCode !== 0 && isIndexLockError(result.stderr)) {
|
|
1814
|
+
const gitDirs = await resolveGitDirsForLockRecovery(cwd, env);
|
|
1815
|
+
const cleared = clearStaleIndexLocks(gitDirs);
|
|
1816
|
+
if (cleared.length > 0) {
|
|
1817
|
+
result = await run("git", gitArgs, { cwd, reject: false, timeoutMs: opts?.timeoutMs, env });
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
if ((opts?.reject ?? true) && result.exitCode !== 0) {
|
|
1821
|
+
throw new Error(
|
|
1822
|
+
`Command failed with exit code ${result.exitCode}: git ${gitArgs.join(" ")}
|
|
1823
|
+
${result.stderr}`
|
|
1824
|
+
);
|
|
1825
|
+
}
|
|
1826
|
+
return result;
|
|
1827
|
+
}
|
|
1828
|
+
async function gh(args, cwd, opts) {
|
|
1829
|
+
return run("gh", args, {
|
|
1830
|
+
cwd,
|
|
1831
|
+
reject: opts?.reject,
|
|
1832
|
+
timeoutMs: opts?.timeoutMs,
|
|
1833
|
+
env: {
|
|
1834
|
+
GH_PROMPT_DISABLED: "1",
|
|
1835
|
+
GIT_TERMINAL_PROMPT: "0"
|
|
1836
|
+
}
|
|
1837
|
+
});
|
|
1838
|
+
}
|
|
1839
|
+
async function resolveGhAuthToken(cwd) {
|
|
1840
|
+
const result = await gh(["auth", "token"], cwd, { reject: false, timeoutMs: 8e3 });
|
|
1841
|
+
if (result.exitCode !== 0) return null;
|
|
1842
|
+
const token = result.stdout.trim();
|
|
1843
|
+
return token || null;
|
|
1844
|
+
}
|
|
1845
|
+
var import_execa2;
|
|
1846
|
+
var init_run = __esm({
|
|
1847
|
+
"src/git/run.ts"() {
|
|
1848
|
+
"use strict";
|
|
1849
|
+
import_execa2 = require("execa");
|
|
1850
|
+
init_path();
|
|
1851
|
+
init_stale_lock();
|
|
1852
|
+
}
|
|
1853
|
+
});
|
|
1854
|
+
|
|
1588
1855
|
// src/git/team-meta.ts
|
|
1589
1856
|
var SOCCER_TEAM_META;
|
|
1590
1857
|
var init_team_meta = __esm({
|
|
@@ -2486,7 +2753,7 @@ var init_gh_errors = __esm({
|
|
|
2486
2753
|
|
|
2487
2754
|
// src/store/secret-vault.ts
|
|
2488
2755
|
function secretVaultPath() {
|
|
2489
|
-
return (0,
|
|
2756
|
+
return (0, import_node_path12.join)(appDataDir(), "secrets.json");
|
|
2490
2757
|
}
|
|
2491
2758
|
function loadSecretVault() {
|
|
2492
2759
|
const parsed = readSecureJson(secretVaultPath());
|
|
@@ -2530,11 +2797,11 @@ function normalizeVault(raw) {
|
|
|
2530
2797
|
}
|
|
2531
2798
|
return out;
|
|
2532
2799
|
}
|
|
2533
|
-
var
|
|
2800
|
+
var import_node_path12;
|
|
2534
2801
|
var init_secret_vault = __esm({
|
|
2535
2802
|
"src/store/secret-vault.ts"() {
|
|
2536
2803
|
"use strict";
|
|
2537
|
-
|
|
2804
|
+
import_node_path12 = require("path");
|
|
2538
2805
|
init_paths();
|
|
2539
2806
|
init_secure_file();
|
|
2540
2807
|
}
|
|
@@ -2637,10 +2904,10 @@ function toPublicAppSettings(settings) {
|
|
|
2637
2904
|
};
|
|
2638
2905
|
}
|
|
2639
2906
|
function appSettingsPath() {
|
|
2640
|
-
return (0,
|
|
2907
|
+
return (0, import_node_path13.join)(appDataDir(), "settings.json");
|
|
2641
2908
|
}
|
|
2642
2909
|
function claudeUserSettingsPath() {
|
|
2643
|
-
return (0,
|
|
2910
|
+
return (0, import_node_path13.join)((0, import_node_os4.homedir)(), ".claude", "settings.json");
|
|
2644
2911
|
}
|
|
2645
2912
|
function normalizeClaude(raw) {
|
|
2646
2913
|
if (!raw || typeof raw !== "object") return {};
|
|
@@ -2889,10 +3156,10 @@ function normalizeSettings(raw) {
|
|
|
2889
3156
|
}
|
|
2890
3157
|
function readSettingsFile() {
|
|
2891
3158
|
const path = appSettingsPath();
|
|
2892
|
-
if (!(0,
|
|
3159
|
+
if (!(0, import_node_fs12.existsSync)(path)) return { ...EMPTY_SETTINGS };
|
|
2893
3160
|
try {
|
|
2894
3161
|
chmodOwnerOnly(path);
|
|
2895
|
-
const parsed = JSON.parse((0,
|
|
3162
|
+
const parsed = JSON.parse((0, import_node_fs12.readFileSync)(path, "utf8"));
|
|
2896
3163
|
return normalizeSettings(parsed);
|
|
2897
3164
|
} catch {
|
|
2898
3165
|
return { ...EMPTY_SETTINGS };
|
|
@@ -3277,7 +3544,7 @@ function ensureSlackDeviceIdentity(settings = loadAppSettings()) {
|
|
|
3277
3544
|
}
|
|
3278
3545
|
if (!deviceLabel) {
|
|
3279
3546
|
try {
|
|
3280
|
-
deviceLabel = (0,
|
|
3547
|
+
deviceLabel = (0, import_node_os4.hostname)().split(".")[0]?.trim() || "This Mac";
|
|
3281
3548
|
} catch {
|
|
3282
3549
|
deviceLabel = "This Mac";
|
|
3283
3550
|
}
|
|
@@ -3464,14 +3731,14 @@ function childEnvWithAppSettings(extra) {
|
|
|
3464
3731
|
function harnessEnvKey(harness) {
|
|
3465
3732
|
return HARNESS_ENV_KEYS[harness];
|
|
3466
3733
|
}
|
|
3467
|
-
var import_node_crypto3,
|
|
3734
|
+
var import_node_crypto3, import_node_fs12, import_node_os4, import_node_path13, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
|
|
3468
3735
|
var init_app_settings = __esm({
|
|
3469
3736
|
"src/store/app-settings.ts"() {
|
|
3470
3737
|
"use strict";
|
|
3471
3738
|
import_node_crypto3 = require("crypto");
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3739
|
+
import_node_fs12 = require("fs");
|
|
3740
|
+
import_node_os4 = require("os");
|
|
3741
|
+
import_node_path13 = require("path");
|
|
3475
3742
|
init_thinking_effort();
|
|
3476
3743
|
init_nested_electron_env();
|
|
3477
3744
|
init_paths();
|
|
@@ -3523,23 +3790,23 @@ var init_app_settings = __esm({
|
|
|
3523
3790
|
function githubAgentAuthDir() {
|
|
3524
3791
|
const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
|
|
3525
3792
|
if (override) return override;
|
|
3526
|
-
return (0,
|
|
3793
|
+
return (0, import_node_path14.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
|
|
3527
3794
|
}
|
|
3528
3795
|
function githubCredentialStorePath() {
|
|
3529
|
-
return (0,
|
|
3796
|
+
return (0, import_node_path14.join)(githubAgentAuthDir(), "git-credentials");
|
|
3530
3797
|
}
|
|
3531
3798
|
function githubGhConfigDir() {
|
|
3532
|
-
return (0,
|
|
3799
|
+
return (0, import_node_path14.join)(githubAgentAuthDir(), "gh");
|
|
3533
3800
|
}
|
|
3534
3801
|
function writePrivateFile2(file, body) {
|
|
3535
|
-
(0,
|
|
3802
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path14.dirname)(file), { recursive: true, mode: 448 });
|
|
3536
3803
|
try {
|
|
3537
|
-
(0,
|
|
3804
|
+
(0, import_node_fs13.chmodSync)((0, import_node_path14.dirname)(file), 448);
|
|
3538
3805
|
} catch {
|
|
3539
3806
|
}
|
|
3540
|
-
(0,
|
|
3807
|
+
(0, import_node_fs13.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
|
|
3541
3808
|
try {
|
|
3542
|
-
(0,
|
|
3809
|
+
(0, import_node_fs13.chmodSync)(file, 384);
|
|
3543
3810
|
} catch {
|
|
3544
3811
|
}
|
|
3545
3812
|
}
|
|
@@ -3561,228 +3828,43 @@ function ghHostsYml(token, user = "x-access-token") {
|
|
|
3561
3828
|
].join("\n");
|
|
3562
3829
|
}
|
|
3563
3830
|
function materializeGithubAgentAuth(token, user) {
|
|
3564
|
-
const trimmed = token.trim();
|
|
3565
|
-
if (!trimmed) return;
|
|
3566
|
-
const root = githubAgentAuthDir();
|
|
3567
|
-
(0,
|
|
3568
|
-
try {
|
|
3569
|
-
(0,
|
|
3570
|
-
} catch {
|
|
3571
|
-
}
|
|
3572
|
-
writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
|
|
3573
|
-
const ghDir = githubGhConfigDir();
|
|
3574
|
-
(0, import_node_fs11.mkdirSync)(ghDir, { recursive: true, mode: 448 });
|
|
3575
|
-
writePrivateFile2((0, import_node_path12.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
|
|
3576
|
-
writePrivateFile2((0, import_node_path12.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
|
|
3577
|
-
}
|
|
3578
|
-
function githubAgentAuthReady() {
|
|
3579
|
-
return (0, import_node_fs11.existsSync)(githubCredentialStorePath()) && (0, import_node_fs11.existsSync)((0, import_node_path12.join)(githubGhConfigDir(), "hosts.yml"));
|
|
3580
|
-
}
|
|
3581
|
-
function githubCredentialHelperGitConfig() {
|
|
3582
|
-
const file = githubCredentialStorePath();
|
|
3583
|
-
return [
|
|
3584
|
-
{ key: "credential.helper", value: "" },
|
|
3585
|
-
{ key: "credential.helper", value: `store --file=${file}` }
|
|
3586
|
-
];
|
|
3587
|
-
}
|
|
3588
|
-
function githubGhConfigEnv() {
|
|
3589
|
-
return {
|
|
3590
|
-
GH_CONFIG_DIR: githubGhConfigDir(),
|
|
3591
|
-
GH_PROMPT_DISABLED: "1"
|
|
3592
|
-
};
|
|
3593
|
-
}
|
|
3594
|
-
var import_node_fs11, import_node_os4, import_node_path12;
|
|
3595
|
-
var init_github_agent_auth = __esm({
|
|
3596
|
-
"src/git/github-agent-auth.ts"() {
|
|
3597
|
-
"use strict";
|
|
3598
|
-
import_node_fs11 = require("fs");
|
|
3599
|
-
import_node_os4 = require("os");
|
|
3600
|
-
import_node_path12 = require("path");
|
|
3601
|
-
}
|
|
3602
|
-
});
|
|
3603
|
-
|
|
3604
|
-
// src/agents/path.ts
|
|
3605
|
-
function prependPathDir(env, dir) {
|
|
3606
|
-
if (!dir || !(0, import_node_fs12.existsSync)(dir)) return;
|
|
3607
|
-
const current = env.PATH ?? "";
|
|
3608
|
-
const parts = current.split(import_node_path13.delimiter).filter(Boolean);
|
|
3609
|
-
if (parts.includes(dir)) {
|
|
3610
|
-
env.PATH = current;
|
|
3611
|
-
return;
|
|
3612
|
-
}
|
|
3613
|
-
env.PATH = [dir, ...parts].join(import_node_path13.delimiter);
|
|
3614
|
-
}
|
|
3615
|
-
function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os5.homedir)()) {
|
|
3616
|
-
return (0, import_node_path13.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
|
|
3617
|
-
}
|
|
3618
|
-
function isConductorBundledCli(filePath) {
|
|
3619
|
-
const p = (filePath ?? "").replace(/\\/g, "/");
|
|
3620
|
-
return p.includes("/com.conductor.app/bin/") || p.endsWith("/com.conductor.app/bin");
|
|
3621
|
-
}
|
|
3622
|
-
function ensureAgentPath(env = process.env) {
|
|
3623
|
-
const home = env.HOME || env.USERPROFILE || (0, import_node_os5.homedir)();
|
|
3624
|
-
const current = env.PATH ?? "";
|
|
3625
|
-
const parts = current.split(import_node_path13.delimiter).filter(Boolean);
|
|
3626
|
-
const seen = new Set(parts);
|
|
3627
|
-
const extras = [
|
|
3628
|
-
...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path13.join)(home, rel)),
|
|
3629
|
-
"/opt/homebrew/bin",
|
|
3630
|
-
"/usr/local/bin",
|
|
3631
|
-
// Keep after Homebrew/npm so a user-installed CLI still wins.
|
|
3632
|
-
conductorBundledBinDir(home)
|
|
3633
|
-
];
|
|
3634
|
-
for (const dir of extras.reverse()) {
|
|
3635
|
-
if (!dir || seen.has(dir) || !(0, import_node_fs12.existsSync)(dir)) continue;
|
|
3636
|
-
parts.unshift(dir);
|
|
3637
|
-
seen.add(dir);
|
|
3638
|
-
}
|
|
3639
|
-
const next = parts.join(import_node_path13.delimiter);
|
|
3640
|
-
env.PATH = next;
|
|
3641
|
-
return next;
|
|
3642
|
-
}
|
|
3643
|
-
function enrichPathWithNpmGlobalBin(env = process.env) {
|
|
3644
|
-
ensureAgentPath(env);
|
|
3645
|
-
try {
|
|
3646
|
-
const prefix = (0, import_node_child_process2.execFileSync)("npm", ["prefix", "-g"], {
|
|
3647
|
-
encoding: "utf8",
|
|
3648
|
-
env: { ...process.env, ...env },
|
|
3649
|
-
timeout: 8e3,
|
|
3650
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
3651
|
-
}).trim().split(/\r?\n/).find(Boolean);
|
|
3652
|
-
if (prefix) {
|
|
3653
|
-
const binDir = process.platform === "win32" ? prefix : (0, import_node_path13.join)(prefix, "bin");
|
|
3654
|
-
prependPathDir(env, binDir);
|
|
3655
|
-
}
|
|
3656
|
-
} catch {
|
|
3657
|
-
}
|
|
3658
|
-
return env.PATH ?? "";
|
|
3659
|
-
}
|
|
3660
|
-
function posixShellSingleQuote(value) {
|
|
3661
|
-
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
3662
|
-
}
|
|
3663
|
-
function resolveCommandBinarySync(command, whichPath) {
|
|
3664
|
-
const trimmed = command.trim();
|
|
3665
|
-
if (!trimmed) return trimmed;
|
|
3666
|
-
const match = /^(\S+)(\s[\s\S]*)?$/.exec(trimmed);
|
|
3667
|
-
if (!match) return trimmed;
|
|
3668
|
-
const bin = match[1];
|
|
3669
|
-
const rest = match[2] ?? "";
|
|
3670
|
-
if (bin.includes("/") || bin.includes("\\")) return trimmed;
|
|
3671
|
-
const abs = whichPath?.trim().split(/\r?\n/).find(Boolean);
|
|
3672
|
-
if (!abs) return trimmed;
|
|
3673
|
-
return `${abs}${rest}`;
|
|
3674
|
-
}
|
|
3675
|
-
function withExportedPath(command, pathValue) {
|
|
3676
|
-
const trimmed = command.trim();
|
|
3677
|
-
if (!trimmed) return trimmed;
|
|
3678
|
-
if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
|
|
3679
|
-
return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
|
|
3680
|
-
}
|
|
3681
|
-
var import_node_fs12, import_node_child_process2, import_node_os5, import_node_path13, EXTRA_BIN_DIRS;
|
|
3682
|
-
var init_path = __esm({
|
|
3683
|
-
"src/agents/path.ts"() {
|
|
3684
|
-
"use strict";
|
|
3685
|
-
import_node_fs12 = require("fs");
|
|
3686
|
-
import_node_child_process2 = require("child_process");
|
|
3687
|
-
import_node_os5 = require("os");
|
|
3688
|
-
import_node_path13 = require("path");
|
|
3689
|
-
EXTRA_BIN_DIRS = [
|
|
3690
|
-
".local/bin",
|
|
3691
|
-
".cargo/bin",
|
|
3692
|
-
".nvm/current/bin",
|
|
3693
|
-
".asdf/shims",
|
|
3694
|
-
".volta/bin",
|
|
3695
|
-
".npm-global/bin",
|
|
3696
|
-
// fnm default alias (common when shell init is skipped)
|
|
3697
|
-
".local/share/fnm/aliases/default/bin",
|
|
3698
|
-
// pnpm / npm global bins (where `@brightsy/cli` typically lands)
|
|
3699
|
-
"Library/pnpm",
|
|
3700
|
-
".pnpm"
|
|
3701
|
-
];
|
|
3702
|
-
}
|
|
3703
|
-
});
|
|
3704
|
-
|
|
3705
|
-
// src/git/run.ts
|
|
3706
|
-
var run_exports = {};
|
|
3707
|
-
__export(run_exports, {
|
|
3708
|
-
gh: () => gh,
|
|
3709
|
-
git: () => git,
|
|
3710
|
-
resolveGhAuthToken: () => resolveGhAuthToken,
|
|
3711
|
-
run: () => run
|
|
3712
|
-
});
|
|
3713
|
-
async function run(file, args, opts) {
|
|
3714
|
-
ensureAgentPath();
|
|
3715
|
-
try {
|
|
3716
|
-
const result = await (0, import_execa2.execa)(file, args, {
|
|
3717
|
-
cwd: opts?.cwd,
|
|
3718
|
-
env: { ...process.env, ...opts?.env },
|
|
3719
|
-
reject: opts?.reject ?? true,
|
|
3720
|
-
...opts?.timeoutMs != null ? { timeout: opts.timeoutMs } : {}
|
|
3721
|
-
});
|
|
3722
|
-
return {
|
|
3723
|
-
stdout: result.stdout ?? "",
|
|
3724
|
-
stderr: result.stderr ?? "",
|
|
3725
|
-
exitCode: result.exitCode ?? 0
|
|
3726
|
-
};
|
|
3727
|
-
} catch (err) {
|
|
3728
|
-
const e = err;
|
|
3729
|
-
if (opts?.reject === false) {
|
|
3730
|
-
return {
|
|
3731
|
-
stdout: String(e.stdout ?? ""),
|
|
3732
|
-
stderr: String(e.stderr ?? ""),
|
|
3733
|
-
exitCode: e.exitCode ?? 1
|
|
3734
|
-
};
|
|
3735
|
-
}
|
|
3736
|
-
throw err;
|
|
3737
|
-
}
|
|
3738
|
-
}
|
|
3739
|
-
async function git(args, cwd, opts) {
|
|
3740
|
-
const prefix = [];
|
|
3741
|
-
if (opts?.config) {
|
|
3742
|
-
for (const [key, value] of Object.entries(opts.config)) {
|
|
3743
|
-
if (!key) continue;
|
|
3744
|
-
prefix.push("-c", `${key}=${value}`);
|
|
3745
|
-
}
|
|
3831
|
+
const trimmed = token.trim();
|
|
3832
|
+
if (!trimmed) return;
|
|
3833
|
+
const root = githubAgentAuthDir();
|
|
3834
|
+
(0, import_node_fs13.mkdirSync)(root, { recursive: true, mode: 448 });
|
|
3835
|
+
try {
|
|
3836
|
+
(0, import_node_fs13.chmodSync)(root, 448);
|
|
3837
|
+
} catch {
|
|
3746
3838
|
}
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
env: {
|
|
3753
|
-
GIT_TERMINAL_PROMPT: "0",
|
|
3754
|
-
GIT_ASKPASS: process.env.GIT_ASKPASS || "echo",
|
|
3755
|
-
SSH_ASKPASS: process.env.SSH_ASKPASS || "echo",
|
|
3756
|
-
GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND || "ssh -o BatchMode=yes -o ConnectTimeout=15",
|
|
3757
|
-
GCM_INTERACTIVE: "never",
|
|
3758
|
-
GH_PROMPT_DISABLED: "1",
|
|
3759
|
-
...opts?.env
|
|
3760
|
-
}
|
|
3761
|
-
});
|
|
3839
|
+
writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
|
|
3840
|
+
const ghDir = githubGhConfigDir();
|
|
3841
|
+
(0, import_node_fs13.mkdirSync)(ghDir, { recursive: true, mode: 448 });
|
|
3842
|
+
writePrivateFile2((0, import_node_path14.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
|
|
3843
|
+
writePrivateFile2((0, import_node_path14.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
|
|
3762
3844
|
}
|
|
3763
|
-
|
|
3764
|
-
return
|
|
3765
|
-
cwd,
|
|
3766
|
-
reject: opts?.reject,
|
|
3767
|
-
timeoutMs: opts?.timeoutMs,
|
|
3768
|
-
env: {
|
|
3769
|
-
GH_PROMPT_DISABLED: "1",
|
|
3770
|
-
GIT_TERMINAL_PROMPT: "0"
|
|
3771
|
-
}
|
|
3772
|
-
});
|
|
3845
|
+
function githubAgentAuthReady() {
|
|
3846
|
+
return (0, import_node_fs13.existsSync)(githubCredentialStorePath()) && (0, import_node_fs13.existsSync)((0, import_node_path14.join)(githubGhConfigDir(), "hosts.yml"));
|
|
3773
3847
|
}
|
|
3774
|
-
|
|
3775
|
-
const
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3848
|
+
function githubCredentialHelperGitConfig() {
|
|
3849
|
+
const file = githubCredentialStorePath();
|
|
3850
|
+
return [
|
|
3851
|
+
{ key: "credential.helper", value: "" },
|
|
3852
|
+
{ key: "credential.helper", value: `store --file=${file}` }
|
|
3853
|
+
];
|
|
3779
3854
|
}
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3855
|
+
function githubGhConfigEnv() {
|
|
3856
|
+
return {
|
|
3857
|
+
GH_CONFIG_DIR: githubGhConfigDir(),
|
|
3858
|
+
GH_PROMPT_DISABLED: "1"
|
|
3859
|
+
};
|
|
3860
|
+
}
|
|
3861
|
+
var import_node_fs13, import_node_os5, import_node_path14;
|
|
3862
|
+
var init_github_agent_auth = __esm({
|
|
3863
|
+
"src/git/github-agent-auth.ts"() {
|
|
3783
3864
|
"use strict";
|
|
3784
|
-
|
|
3785
|
-
|
|
3865
|
+
import_node_fs13 = require("fs");
|
|
3866
|
+
import_node_os5 = require("os");
|
|
3867
|
+
import_node_path14 = require("path");
|
|
3786
3868
|
}
|
|
3787
3869
|
});
|
|
3788
3870
|
|
|
@@ -3874,7 +3956,7 @@ async function warmGithubAgentAuth(opts) {
|
|
|
3874
3956
|
}
|
|
3875
3957
|
function normalizeWritableRoot(raw) {
|
|
3876
3958
|
const trimmed = raw.trim().replace(/\/+$/, "");
|
|
3877
|
-
return trimmed && (0,
|
|
3959
|
+
return trimmed && (0, import_node_path15.isAbsolute)(trimmed) ? trimmed : null;
|
|
3878
3960
|
}
|
|
3879
3961
|
async function resolveCodexGitWritableRoots(cwd) {
|
|
3880
3962
|
const roots = /* @__PURE__ */ new Set();
|
|
@@ -3951,11 +4033,11 @@ function formatGitAuthModeDirective(mode) {
|
|
|
3951
4033
|
].join("\n");
|
|
3952
4034
|
}
|
|
3953
4035
|
}
|
|
3954
|
-
var
|
|
4036
|
+
var import_node_path15, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
|
|
3955
4037
|
var init_git_auth_mode = __esm({
|
|
3956
4038
|
"src/git/git-auth-mode.ts"() {
|
|
3957
4039
|
"use strict";
|
|
3958
|
-
|
|
4040
|
+
import_node_path15 = require("path");
|
|
3959
4041
|
init_app_settings();
|
|
3960
4042
|
init_github_agent_auth();
|
|
3961
4043
|
init_run();
|
|
@@ -5125,8 +5207,8 @@ function isLocalPrFetchBranch(ref) {
|
|
|
5125
5207
|
}
|
|
5126
5208
|
async function createThreadWorktree(opts) {
|
|
5127
5209
|
let branchName = `thread/${opts.slug}`;
|
|
5128
|
-
const worktreePath = (0,
|
|
5129
|
-
if ((0,
|
|
5210
|
+
const worktreePath = (0, import_node_path16.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
5211
|
+
if ((0, import_node_fs14.existsSync)(worktreePath)) {
|
|
5130
5212
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
5131
5213
|
}
|
|
5132
5214
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -5193,8 +5275,8 @@ ${add.stdout}`;
|
|
|
5193
5275
|
async function createExistingBranchWorktree(opts) {
|
|
5194
5276
|
const branchName = opts.branchName.trim();
|
|
5195
5277
|
if (!branchName) throw new Error("branch name required");
|
|
5196
|
-
const worktreePath = (0,
|
|
5197
|
-
if ((0,
|
|
5278
|
+
const worktreePath = (0, import_node_path16.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
5279
|
+
if ((0, import_node_fs14.existsSync)(worktreePath)) {
|
|
5198
5280
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
5199
5281
|
}
|
|
5200
5282
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -5485,10 +5567,10 @@ function sameRepoPath(a, b) {
|
|
|
5485
5567
|
return normalizeWorktreePath(a) === normalizeWorktreePath(b);
|
|
5486
5568
|
}
|
|
5487
5569
|
function listLocalThreadBranchSlugs(repoPath) {
|
|
5488
|
-
const refsDir = (0,
|
|
5489
|
-
if (!(0,
|
|
5570
|
+
const refsDir = (0, import_node_path16.join)(repoPath, ".git", "refs", "heads", "thread");
|
|
5571
|
+
if (!(0, import_node_fs14.existsSync)(refsDir)) return [];
|
|
5490
5572
|
try {
|
|
5491
|
-
return (0,
|
|
5573
|
+
return (0, import_node_fs14.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
|
|
5492
5574
|
} catch {
|
|
5493
5575
|
return [];
|
|
5494
5576
|
}
|
|
@@ -5496,8 +5578,8 @@ function listLocalThreadBranchSlugs(repoPath) {
|
|
|
5496
5578
|
function collectTakenTeamSlugs(repoPath) {
|
|
5497
5579
|
const taken = /* @__PURE__ */ new Set();
|
|
5498
5580
|
const root = worktreesRoot(repoPath);
|
|
5499
|
-
if ((0,
|
|
5500
|
-
for (const entry of (0,
|
|
5581
|
+
if ((0, import_node_fs14.existsSync)(root)) {
|
|
5582
|
+
for (const entry of (0, import_node_fs14.readdirSync)(root, { withFileTypes: true })) {
|
|
5501
5583
|
if (entry.isDirectory() && entry.name !== ".DS_Store") {
|
|
5502
5584
|
taken.add(normalizeTakenSlug(entry.name));
|
|
5503
5585
|
}
|
|
@@ -5518,18 +5600,18 @@ function allocateTeamSlug(repoPath) {
|
|
|
5518
5600
|
const taken = collectTakenTeamSlugs(repoPath);
|
|
5519
5601
|
for (let attempt = 0; attempt < 32; attempt++) {
|
|
5520
5602
|
const team = allocateTeamName(taken);
|
|
5521
|
-
const path = (0,
|
|
5522
|
-
if (!(0,
|
|
5603
|
+
const path = (0, import_node_path16.join)(worktreesRoot(repoPath), team.slug);
|
|
5604
|
+
if (!(0, import_node_fs14.existsSync)(path)) return team;
|
|
5523
5605
|
taken.add(team.slug);
|
|
5524
5606
|
}
|
|
5525
5607
|
throw new Error("No available soccer team worktree directories left");
|
|
5526
5608
|
}
|
|
5527
|
-
var
|
|
5609
|
+
var import_node_fs14, import_node_path16;
|
|
5528
5610
|
var init_worktree = __esm({
|
|
5529
5611
|
"src/git/worktree.ts"() {
|
|
5530
5612
|
"use strict";
|
|
5531
|
-
|
|
5532
|
-
|
|
5613
|
+
import_node_fs14 = require("fs");
|
|
5614
|
+
import_node_path16 = require("path");
|
|
5533
5615
|
init_paths();
|
|
5534
5616
|
init_thread_store();
|
|
5535
5617
|
init_teams();
|
|
@@ -5664,7 +5746,7 @@ function coordinatorTurnReminder(opts) {
|
|
|
5664
5746
|
function ensureGlobalCoordinatorCwd(opts) {
|
|
5665
5747
|
const dir = globalAgentCwd();
|
|
5666
5748
|
try {
|
|
5667
|
-
(0,
|
|
5749
|
+
(0, import_node_fs15.mkdirSync)(dir, { recursive: true });
|
|
5668
5750
|
} catch {
|
|
5669
5751
|
return dir;
|
|
5670
5752
|
}
|
|
@@ -5672,7 +5754,7 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
5672
5754
|
let orchId = opts?.orchestratorThreadId?.trim() || "";
|
|
5673
5755
|
if (!orchId) {
|
|
5674
5756
|
try {
|
|
5675
|
-
const existing = (0,
|
|
5757
|
+
const existing = (0, import_node_fs15.readFileSync)((0, import_node_path17.join)(dir, "AGENTS.md"), "utf8");
|
|
5676
5758
|
const m = existing.match(
|
|
5677
5759
|
/YOUR orchestration thread id is `([0-9a-f-]{36})`/i
|
|
5678
5760
|
);
|
|
@@ -5714,9 +5796,9 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
5714
5796
|
"Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
|
|
5715
5797
|
].join("\n");
|
|
5716
5798
|
try {
|
|
5717
|
-
(0,
|
|
5799
|
+
(0, import_node_fs15.writeFileSync)((0, import_node_path17.join)(dir, "CLAUDE.md"), `${body}
|
|
5718
5800
|
`, "utf8");
|
|
5719
|
-
(0,
|
|
5801
|
+
(0, import_node_fs15.writeFileSync)((0, import_node_path17.join)(dir, "AGENTS.md"), `${body}
|
|
5720
5802
|
`, "utf8");
|
|
5721
5803
|
} catch {
|
|
5722
5804
|
}
|
|
@@ -5748,12 +5830,12 @@ function coordinatorSystemPrompt(opts) {
|
|
|
5748
5830
|
formatWorkspaceInventory(opts.workspaces)
|
|
5749
5831
|
].join("\n");
|
|
5750
5832
|
}
|
|
5751
|
-
var
|
|
5833
|
+
var import_node_fs15, import_node_path17, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
|
|
5752
5834
|
var init_coordinator_prompt = __esm({
|
|
5753
5835
|
"src/orchestrator/coordinator-prompt.ts"() {
|
|
5754
5836
|
"use strict";
|
|
5755
|
-
|
|
5756
|
-
|
|
5837
|
+
import_node_fs15 = require("fs");
|
|
5838
|
+
import_node_path17 = require("path");
|
|
5757
5839
|
init_worktree();
|
|
5758
5840
|
init_app_settings();
|
|
5759
5841
|
init_paths();
|
|
@@ -5779,7 +5861,7 @@ var init_coordinator_prompt = __esm({
|
|
|
5779
5861
|
"- fork_worktree \u2014 fork a worktree chat into a NEW git worktree + chat (transcript attached); optional agent; leave model unset (Auto) unless you have a reason. Not for orchestration chats.",
|
|
5780
5862
|
"- fork_chat \u2014 fork a worktree chat (same worktree tab) OR a Global orchestration chat (new orchestration tab); optional agent; leave model unset (Auto) unless you have a reason. Remote coordinators: use this to continue another orchestration chat on a different agent after session limits.",
|
|
5781
5863
|
"- send_to_thread \u2014 queue a prompt (start/continue a chat turn); pass force_stop: true to interrupt mid-turn / clear stale queued prompts before replacing with a new request",
|
|
5782
|
-
"- wait_for_turn / get_turn_result \u2014 wait for and read the agent reply. wait_for_turn returns within ~45s even if the child is still working (MCP clients kill longer tool calls). If stillRunning is true, progress is a live snapshot of tools/thinking \u2014 call wait_for_turn again. Do not send \u201Care you stuck?\u201D or assume a hang while lastActivityAt is recent. On status error, lastError (and text) is the failure \u2014 switch agent, tell the user, or retry; do not treat empty text as success.",
|
|
5864
|
+
"- wait_for_turn / get_turn_result \u2014 wait for and read the agent reply. wait_for_turn returns within ~45s even if the child is still working (MCP clients kill longer tool calls). If stillRunning is true, progress is a live snapshot of tools/thinking \u2014 call wait_for_turn again. status=queued with no lastActivityAt means the child has not started yet (concurrency cap) \u2014 keep waiting; do not force_stop or send a check-in. Do not send \u201Care you stuck?\u201D or assume a hang while lastActivityAt is recent. On status error, lastError (and text) is the failure \u2014 switch agent, tell the user, or retry; do not treat empty text as success.",
|
|
5783
5865
|
"- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
|
|
5784
5866
|
"- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
|
|
5785
5867
|
"Setup / run:",
|
|
@@ -6051,32 +6133,32 @@ var init_global_workspace = __esm({
|
|
|
6051
6133
|
|
|
6052
6134
|
// src/brightsy/config.ts
|
|
6053
6135
|
function brightsyConfigPath() {
|
|
6054
|
-
return (0,
|
|
6136
|
+
return (0, import_node_path18.join)((0, import_node_os6.homedir)(), ".brightsy", "config.json");
|
|
6055
6137
|
}
|
|
6056
6138
|
function loadBrightsyConfig() {
|
|
6057
6139
|
const path = brightsyConfigPath();
|
|
6058
|
-
if (!(0,
|
|
6140
|
+
if (!(0, import_node_fs16.existsSync)(path)) {
|
|
6059
6141
|
throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
|
|
6060
6142
|
}
|
|
6061
|
-
const raw = JSON.parse((0,
|
|
6143
|
+
const raw = JSON.parse((0, import_node_fs16.readFileSync)(path, "utf8"));
|
|
6062
6144
|
if (!raw.access_token || !raw.account_id) {
|
|
6063
6145
|
throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
|
|
6064
6146
|
}
|
|
6065
6147
|
return raw;
|
|
6066
6148
|
}
|
|
6067
6149
|
function saveBrightsyConfig(cfg) {
|
|
6068
|
-
(0,
|
|
6150
|
+
(0, import_node_fs16.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
|
|
6069
6151
|
`, {
|
|
6070
6152
|
mode: 384
|
|
6071
6153
|
});
|
|
6072
6154
|
}
|
|
6073
|
-
var
|
|
6155
|
+
var import_node_fs16, import_node_os6, import_node_path18;
|
|
6074
6156
|
var init_config = __esm({
|
|
6075
6157
|
"src/brightsy/config.ts"() {
|
|
6076
6158
|
"use strict";
|
|
6077
|
-
|
|
6159
|
+
import_node_fs16 = require("fs");
|
|
6078
6160
|
import_node_os6 = require("os");
|
|
6079
|
-
|
|
6161
|
+
import_node_path18 = require("path");
|
|
6080
6162
|
}
|
|
6081
6163
|
});
|
|
6082
6164
|
|
|
@@ -6091,22 +6173,22 @@ var init_accounts = __esm({
|
|
|
6091
6173
|
|
|
6092
6174
|
// src/brightsy/connected-teams.ts
|
|
6093
6175
|
function storePath4() {
|
|
6094
|
-
return (0,
|
|
6176
|
+
return (0, import_node_path19.join)(appDataDir(), "brightsy-teams.json");
|
|
6095
6177
|
}
|
|
6096
6178
|
function readStore4() {
|
|
6097
6179
|
const path = storePath4();
|
|
6098
|
-
if (!(0,
|
|
6180
|
+
if (!(0, import_node_fs17.existsSync)(path)) return [];
|
|
6099
6181
|
try {
|
|
6100
|
-
const parsed = JSON.parse((0,
|
|
6182
|
+
const parsed = JSON.parse((0, import_node_fs17.readFileSync)(path, "utf8"));
|
|
6101
6183
|
return Array.isArray(parsed.teams) ? parsed.teams : [];
|
|
6102
6184
|
} catch {
|
|
6103
6185
|
return [];
|
|
6104
6186
|
}
|
|
6105
6187
|
}
|
|
6106
6188
|
function writeStore2(teams) {
|
|
6107
|
-
(0,
|
|
6189
|
+
(0, import_node_fs17.mkdirSync)(appDataDir(), { recursive: true });
|
|
6108
6190
|
const path = storePath4();
|
|
6109
|
-
(0,
|
|
6191
|
+
(0, import_node_fs17.writeFileSync)(path, `${JSON.stringify({ teams }, null, 2)}
|
|
6110
6192
|
`, {
|
|
6111
6193
|
mode: 384
|
|
6112
6194
|
});
|
|
@@ -6218,12 +6300,12 @@ function brightsyMcpServerName(slug) {
|
|
|
6218
6300
|
const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
|
|
6219
6301
|
return `brightsy_${cleaned || "team"}`;
|
|
6220
6302
|
}
|
|
6221
|
-
var
|
|
6303
|
+
var import_node_fs17, import_node_path19;
|
|
6222
6304
|
var init_connected_teams = __esm({
|
|
6223
6305
|
"src/brightsy/connected-teams.ts"() {
|
|
6224
6306
|
"use strict";
|
|
6225
|
-
|
|
6226
|
-
|
|
6307
|
+
import_node_fs17 = require("fs");
|
|
6308
|
+
import_node_path19 = require("path");
|
|
6227
6309
|
init_paths();
|
|
6228
6310
|
init_accounts();
|
|
6229
6311
|
init_config();
|
|
@@ -6554,11 +6636,11 @@ async function syncCliForTarget(accountId) {
|
|
|
6554
6636
|
}
|
|
6555
6637
|
applyConnectedTeamToCli(team);
|
|
6556
6638
|
}
|
|
6557
|
-
var
|
|
6639
|
+
var import_node_fs18, brightsyAdapter;
|
|
6558
6640
|
var init_brightsy = __esm({
|
|
6559
6641
|
"src/agents/brightsy.ts"() {
|
|
6560
6642
|
"use strict";
|
|
6561
|
-
|
|
6643
|
+
import_node_fs18 = require("fs");
|
|
6562
6644
|
init_run();
|
|
6563
6645
|
init_connected_teams();
|
|
6564
6646
|
init_config();
|
|
@@ -6573,7 +6655,7 @@ var init_brightsy = __esm({
|
|
|
6573
6655
|
async detect() {
|
|
6574
6656
|
const brightsy = resolveAgentExecutable("brightsy");
|
|
6575
6657
|
if (brightsy !== "brightsy") {
|
|
6576
|
-
if (!(0,
|
|
6658
|
+
if (!(0, import_node_fs18.existsSync)(brightsy)) {
|
|
6577
6659
|
return {
|
|
6578
6660
|
agent: "brightsy",
|
|
6579
6661
|
installed: false,
|
|
@@ -6742,9 +6824,9 @@ function toolDescription(name, input) {
|
|
|
6742
6824
|
if (/connectedAgentRequest/i.test(name)) {
|
|
6743
6825
|
return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
|
|
6744
6826
|
}
|
|
6745
|
-
if (desc && kind) return `${kind}: ${desc}`;
|
|
6746
|
-
if (desc) return desc
|
|
6747
|
-
return
|
|
6827
|
+
if (desc && kind) return `${kind}: ${desc}${subagentLiveSuffix(input)}`;
|
|
6828
|
+
if (desc) return `${desc}${subagentLiveSuffix(input)}`;
|
|
6829
|
+
return `Subagent${subagentLiveSuffix(input)}`;
|
|
6748
6830
|
}
|
|
6749
6831
|
if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
|
|
6750
6832
|
return str2(input?.title) ? `Artifact ${str2(input?.title)}` : "Artifact";
|
|
@@ -6769,13 +6851,83 @@ function toolDescription(name, input) {
|
|
|
6769
6851
|
}
|
|
6770
6852
|
if (/grep/i.test(name)) return "Search files";
|
|
6771
6853
|
if (/glob/i.test(name)) return "Find files";
|
|
6854
|
+
const compact = n.replace(/[_-]/g, "");
|
|
6855
|
+
if (/^taskoutput$/i.test(compact)) {
|
|
6856
|
+
return str2(input.task_id) ? `Wait for ${str2(input.task_id)}` : "Wait for background task";
|
|
6857
|
+
}
|
|
6858
|
+
if (/^taskstop$/i.test(compact)) {
|
|
6859
|
+
return str2(input.task_id) ? `Stop ${str2(input.task_id)}` : "Stop background task";
|
|
6860
|
+
}
|
|
6861
|
+
if (/^monitor$/i.test(compact)) {
|
|
6862
|
+
const command = str2(input.command);
|
|
6863
|
+
return command ? `Watch ${command.length > 48 ? `${command.slice(0, 45)}\u2026` : command}` : "Watch command";
|
|
6864
|
+
}
|
|
6772
6865
|
return n;
|
|
6773
6866
|
}
|
|
6867
|
+
function subagentLiveSuffix(input) {
|
|
6868
|
+
if (!input) return "";
|
|
6869
|
+
const bits = [];
|
|
6870
|
+
const status = str2(input.live_status);
|
|
6871
|
+
if (status && !/^runn(ing)?$|^working$/i.test(status)) bits.push(status);
|
|
6872
|
+
if (typeof input.live_tool_uses === "number") bits.push(`${input.live_tool_uses} tools`);
|
|
6873
|
+
if (typeof input.live_duration_ms === "number") {
|
|
6874
|
+
bits.push(`${Math.max(0, Math.round(Number(input.live_duration_ms) / 1e3))}s`);
|
|
6875
|
+
}
|
|
6876
|
+
const last = str2(input.live_last_tool);
|
|
6877
|
+
if (last) bits.push(last);
|
|
6878
|
+
return bits.length ? ` \xB7 ${bits.join(" \xB7 ")}` : "";
|
|
6879
|
+
}
|
|
6774
6880
|
function isSubagentToolName(name) {
|
|
6775
6881
|
const n = (name ?? "").trim();
|
|
6776
6882
|
if (/^(task|agent|spawn_agent)$/i.test(n)) return true;
|
|
6777
6883
|
return /connectedAgentRequest/i.test(n);
|
|
6778
6884
|
}
|
|
6885
|
+
function isPollWrapperToolName(name) {
|
|
6886
|
+
const n = (name ?? "").replace(/[_-]/g, "");
|
|
6887
|
+
return /^(taskoutput|taskstop|sleep)$/i.test(n);
|
|
6888
|
+
}
|
|
6889
|
+
function lastTextPart(parts, type) {
|
|
6890
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
6891
|
+
const p = parts[i];
|
|
6892
|
+
if (p.type === type && p.text.trim()) return p.text.trim();
|
|
6893
|
+
}
|
|
6894
|
+
return "";
|
|
6895
|
+
}
|
|
6896
|
+
function toolLabel(tool) {
|
|
6897
|
+
return tool.description || toolDescription(tool.name, tool.input) || tool.name;
|
|
6898
|
+
}
|
|
6899
|
+
function liveActivitySummary(parts, opts) {
|
|
6900
|
+
if (opts?.queued && parts.length === 0) {
|
|
6901
|
+
return "Queued \u2014 waiting for a slot";
|
|
6902
|
+
}
|
|
6903
|
+
const tools = parts.filter((p) => p.type === "tool");
|
|
6904
|
+
const runningSubs = tools.filter(
|
|
6905
|
+
(t) => t.status === "running" && !t.parentId && isSubagentToolName(t.name)
|
|
6906
|
+
);
|
|
6907
|
+
const runningNested = [...tools].reverse().find((t) => t.status === "running" && t.parentId && !isPollWrapperToolName(t.name));
|
|
6908
|
+
const runningTop = [...tools].reverse().find(
|
|
6909
|
+
(t) => t.status === "running" && !t.parentId && !isPollWrapperToolName(t.name) && !isSubagentToolName(t.name)
|
|
6910
|
+
);
|
|
6911
|
+
const runningPoll = [...tools].reverse().find((t) => t.status === "running" && isPollWrapperToolName(t.name));
|
|
6912
|
+
const thinking = lastTextPart(parts, "thinking");
|
|
6913
|
+
const text4 = lastTextPart(parts, "text");
|
|
6914
|
+
if (runningSubs.length > 0) {
|
|
6915
|
+
const heads = runningSubs.map(toolLabel);
|
|
6916
|
+
const head = runningSubs.length === 1 ? heads[0] : `${runningSubs.length} subagents \xB7 ${heads.slice(0, 2).join(" \xB7 ")}`;
|
|
6917
|
+
if (runningNested) return `${head} \xB7 ${toolLabel(runningNested)}`;
|
|
6918
|
+
return head;
|
|
6919
|
+
}
|
|
6920
|
+
if (runningTop) return toolLabel(runningTop);
|
|
6921
|
+
if (runningPoll) return toolLabel(runningPoll);
|
|
6922
|
+
if (thinking) return thinking.length > 96 ? `\u2026${thinking.slice(-96)}` : thinking;
|
|
6923
|
+
if (text4) return "Writing reply\u2026";
|
|
6924
|
+
const last = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? tools.at(-1);
|
|
6925
|
+
if (last) {
|
|
6926
|
+
const label = toolLabel(last);
|
|
6927
|
+
return last.status === "running" ? label : `Finished ${label}`;
|
|
6928
|
+
}
|
|
6929
|
+
return "Working\u2026";
|
|
6930
|
+
}
|
|
6779
6931
|
function messagePartParentId(part) {
|
|
6780
6932
|
if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
|
|
6781
6933
|
return part.parentId;
|
|
@@ -6857,6 +7009,25 @@ function applyAgentEvent(parts, event) {
|
|
|
6857
7009
|
const data = event.data;
|
|
6858
7010
|
if (!data) return parts;
|
|
6859
7011
|
const next = [...parts];
|
|
7012
|
+
if (event.replace) {
|
|
7013
|
+
for (let i = next.length - 1; i >= 0; i--) {
|
|
7014
|
+
const prev = next[i];
|
|
7015
|
+
if (prev?.type === "thinking" && sameParentId(prev.parentId, event.parentId)) {
|
|
7016
|
+
next[i] = {
|
|
7017
|
+
type: "thinking",
|
|
7018
|
+
text: data,
|
|
7019
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
7020
|
+
};
|
|
7021
|
+
return next;
|
|
7022
|
+
}
|
|
7023
|
+
}
|
|
7024
|
+
next.push({
|
|
7025
|
+
type: "thinking",
|
|
7026
|
+
text: data,
|
|
7027
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
7028
|
+
});
|
|
7029
|
+
return next;
|
|
7030
|
+
}
|
|
6860
7031
|
const last = next[next.length - 1];
|
|
6861
7032
|
if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
|
|
6862
7033
|
next[next.length - 1] = {
|
|
@@ -6880,14 +7051,18 @@ function applyAgentEvent(parts, event) {
|
|
|
6880
7051
|
if (existing >= 0) {
|
|
6881
7052
|
const prev = parts[existing];
|
|
6882
7053
|
const next = [...parts];
|
|
6883
|
-
const mergedInput =
|
|
7054
|
+
const mergedInput = {
|
|
7055
|
+
...prev.input ?? {},
|
|
7056
|
+
...input ?? {}
|
|
7057
|
+
};
|
|
7058
|
+
const mergedRecord = Object.keys(mergedInput).length > 0 ? mergedInput : void 0;
|
|
6884
7059
|
next[existing] = {
|
|
6885
7060
|
...prev,
|
|
6886
7061
|
name: event.name || prev.name,
|
|
6887
|
-
input:
|
|
6888
|
-
description: toolDescription(event.name || prev.name,
|
|
6889
|
-
detail: toolDetail(event.name || prev.name,
|
|
6890
|
-
filePath: toolFilePath(
|
|
7062
|
+
input: mergedRecord,
|
|
7063
|
+
description: toolDescription(event.name || prev.name, mergedRecord),
|
|
7064
|
+
detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
|
|
7065
|
+
filePath: toolFilePath(mergedRecord) ?? prev.filePath,
|
|
6891
7066
|
additions: diff.additions ?? prev.additions,
|
|
6892
7067
|
deletions: diff.deletions ?? prev.deletions,
|
|
6893
7068
|
parentId: event.parentId ?? prev.parentId
|
|
@@ -6998,47 +7173,68 @@ function electronResourcesPath() {
|
|
|
6998
7173
|
function packagedCursorRuntimeDir() {
|
|
6999
7174
|
const resources = electronResourcesPath();
|
|
7000
7175
|
if (!resources) return null;
|
|
7001
|
-
const dir = (0,
|
|
7002
|
-
if (!(0,
|
|
7176
|
+
const dir = (0, import_node_path20.join)(resources, "cursor-runtime");
|
|
7177
|
+
if (!(0, import_node_fs19.existsSync)((0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
|
|
7003
7178
|
return dir;
|
|
7004
7179
|
}
|
|
7005
7180
|
function packagedCursorRunnerPath() {
|
|
7006
7181
|
const dir = packagedCursorRuntimeDir();
|
|
7007
|
-
return dir ? (0,
|
|
7182
|
+
return dir ? (0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
|
|
7008
7183
|
}
|
|
7009
7184
|
function packagedMcpDir() {
|
|
7010
7185
|
const resources = electronResourcesPath();
|
|
7011
7186
|
if (!resources) return null;
|
|
7012
|
-
const dir = (0,
|
|
7013
|
-
if (!(0,
|
|
7187
|
+
const dir = (0, import_node_path20.join)(resources, "sideboard-mcp");
|
|
7188
|
+
if (!(0, import_node_fs19.existsSync)((0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
|
|
7014
7189
|
return dir;
|
|
7015
7190
|
}
|
|
7016
7191
|
function packagedMcpStdioPath() {
|
|
7017
7192
|
const dir = packagedMcpDir();
|
|
7018
|
-
return dir ? (0,
|
|
7193
|
+
return dir ? (0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
|
|
7019
7194
|
}
|
|
7020
7195
|
function packagedBundledNodePath() {
|
|
7021
7196
|
const resources = electronResourcesPath();
|
|
7022
7197
|
if (!resources) return null;
|
|
7023
|
-
const bin = (0,
|
|
7024
|
-
if (!(0,
|
|
7198
|
+
const bin = (0, import_node_path20.join)(resources, "node", "bin", "node");
|
|
7199
|
+
if (!(0, import_node_fs19.existsSync)(bin)) return null;
|
|
7025
7200
|
return bin;
|
|
7026
7201
|
}
|
|
7027
7202
|
function packagedCursorRipgrepCandidate(platformPkg, binName) {
|
|
7028
7203
|
const dir = packagedCursorRuntimeDir();
|
|
7029
7204
|
if (!dir) return null;
|
|
7030
|
-
return (0,
|
|
7205
|
+
return (0, import_node_path20.join)(dir, "node_modules", platformPkg, "bin", binName);
|
|
7031
7206
|
}
|
|
7032
|
-
var
|
|
7207
|
+
var import_node_fs19, import_node_path20;
|
|
7033
7208
|
var init_packaged_runtime = __esm({
|
|
7034
7209
|
"src/agents/packaged-runtime.ts"() {
|
|
7035
7210
|
"use strict";
|
|
7036
|
-
|
|
7037
|
-
|
|
7211
|
+
import_node_fs19 = require("fs");
|
|
7212
|
+
import_node_path20 = require("path");
|
|
7038
7213
|
}
|
|
7039
7214
|
});
|
|
7040
7215
|
|
|
7041
7216
|
// src/agents/node-launch.ts
|
|
7217
|
+
function withMaxOldSpaceSize(nodeOptions, heapMb) {
|
|
7218
|
+
const existing = (nodeOptions ?? "").trim();
|
|
7219
|
+
const match = MAX_OLD_SPACE_FLAG.exec(existing);
|
|
7220
|
+
if (match) {
|
|
7221
|
+
const current = match[2] ? Number(match[2]) : 0;
|
|
7222
|
+
if (Number.isFinite(current) && current >= heapMb) return existing;
|
|
7223
|
+
return existing.replace(MAX_OLD_SPACE_FLAG, ` --max-old-space-size=${heapMb}`).trim();
|
|
7224
|
+
}
|
|
7225
|
+
return existing ? `${existing} --max-old-space-size=${heapMb}` : `--max-old-space-size=${heapMb}`;
|
|
7226
|
+
}
|
|
7227
|
+
function applyAgentRunnerHeapEnv(env) {
|
|
7228
|
+
env.NODE_OPTIONS = withMaxOldSpaceSize(
|
|
7229
|
+
env.NODE_OPTIONS,
|
|
7230
|
+
AGENT_RUNNER_MAX_OLD_SPACE_MB
|
|
7231
|
+
);
|
|
7232
|
+
}
|
|
7233
|
+
function envWithAgentHeap(env) {
|
|
7234
|
+
const next = { ...env };
|
|
7235
|
+
applyAgentRunnerHeapEnv(next);
|
|
7236
|
+
return next;
|
|
7237
|
+
}
|
|
7042
7238
|
function isAsarPath(filePath) {
|
|
7043
7239
|
if (/\.asar\.unpacked([/\\]|$)/.test(filePath)) return false;
|
|
7044
7240
|
return /\.asar([/\\]|$)/.test(filePath);
|
|
@@ -7047,7 +7243,7 @@ function unpackedAsarPath(filePath) {
|
|
|
7047
7243
|
if (!isAsarPath(filePath)) return null;
|
|
7048
7244
|
const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
|
|
7049
7245
|
if (unpacked === filePath) return null;
|
|
7050
|
-
return (0,
|
|
7246
|
+
return (0, import_node_fs20.existsSync)(unpacked) ? unpacked : null;
|
|
7051
7247
|
}
|
|
7052
7248
|
function nodeReadableScriptPath(scriptPath) {
|
|
7053
7249
|
return unpackedAsarPath(scriptPath) ?? scriptPath;
|
|
@@ -7087,37 +7283,37 @@ function pickPreferredNode(candidates) {
|
|
|
7087
7283
|
return best;
|
|
7088
7284
|
}
|
|
7089
7285
|
function versionDirNodeBins(root, toBin) {
|
|
7090
|
-
if (!(0,
|
|
7286
|
+
if (!(0, import_node_fs20.existsSync)(root)) return [];
|
|
7091
7287
|
try {
|
|
7092
|
-
return (0,
|
|
7288
|
+
return (0, import_node_fs20.readdirSync)(root).map(toBin);
|
|
7093
7289
|
} catch {
|
|
7094
7290
|
return [];
|
|
7095
7291
|
}
|
|
7096
7292
|
}
|
|
7097
7293
|
function defaultNodeBinCandidates(home = (0, import_node_os7.homedir)()) {
|
|
7098
7294
|
const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
|
|
7099
|
-
(prefix) => PREFERRED_LTS_MAJORS.map((major) => (0,
|
|
7295
|
+
(prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path21.join)(prefix, "opt", `node@${major}`, "bin", "node"))
|
|
7100
7296
|
);
|
|
7101
7297
|
return [
|
|
7102
7298
|
...kegs,
|
|
7103
7299
|
"/opt/homebrew/bin/node",
|
|
7104
7300
|
"/usr/local/bin/node",
|
|
7105
|
-
(0,
|
|
7106
|
-
(0,
|
|
7107
|
-
(0,
|
|
7108
|
-
(0,
|
|
7109
|
-
(0,
|
|
7301
|
+
(0, import_node_path21.join)(home, ".local/share/fnm/aliases/default/bin/node"),
|
|
7302
|
+
(0, import_node_path21.join)(home, ".nvm/current/bin/node"),
|
|
7303
|
+
(0, import_node_path21.join)(home, ".volta/bin/node"),
|
|
7304
|
+
(0, import_node_path21.join)(home, ".asdf/shims/node"),
|
|
7305
|
+
(0, import_node_path21.join)(home, ".local/share/mise/shims/node"),
|
|
7110
7306
|
...versionDirNodeBins(
|
|
7111
|
-
(0,
|
|
7112
|
-
(name) => (0,
|
|
7307
|
+
(0, import_node_path21.join)(home, ".nvm", "versions", "node"),
|
|
7308
|
+
(name) => (0, import_node_path21.join)(home, ".nvm", "versions", "node", name, "bin", "node")
|
|
7113
7309
|
),
|
|
7114
7310
|
...versionDirNodeBins(
|
|
7115
|
-
(0,
|
|
7116
|
-
(name) => (0,
|
|
7311
|
+
(0, import_node_path21.join)(home, ".local/share/fnm", "node-versions"),
|
|
7312
|
+
(name) => (0, import_node_path21.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
|
|
7117
7313
|
),
|
|
7118
7314
|
...versionDirNodeBins(
|
|
7119
|
-
(0,
|
|
7120
|
-
(name) => (0,
|
|
7315
|
+
(0, import_node_path21.join)(home, ".volta", "tools", "image", "node"),
|
|
7316
|
+
(name) => (0, import_node_path21.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
|
|
7121
7317
|
)
|
|
7122
7318
|
];
|
|
7123
7319
|
}
|
|
@@ -7126,10 +7322,10 @@ function uniqueExistingNodeBins(paths) {
|
|
|
7126
7322
|
const out = [];
|
|
7127
7323
|
for (const raw of paths) {
|
|
7128
7324
|
const p = raw.trim();
|
|
7129
|
-
if (!p || !(0,
|
|
7325
|
+
if (!p || !(0, import_node_fs20.existsSync)(p) || isElectronLikeCommand(p)) continue;
|
|
7130
7326
|
let key = p;
|
|
7131
7327
|
try {
|
|
7132
|
-
key = (0,
|
|
7328
|
+
key = (0, import_node_fs20.realpathSync)(p);
|
|
7133
7329
|
} catch {
|
|
7134
7330
|
continue;
|
|
7135
7331
|
}
|
|
@@ -7174,13 +7370,21 @@ async function findSystemNode() {
|
|
|
7174
7370
|
function applyNodeLaunch(launch, args) {
|
|
7175
7371
|
const readableArgs = args.map(nodeReadableScriptPath);
|
|
7176
7372
|
if (!launch.env.ELECTRON_RUN_AS_NODE) {
|
|
7177
|
-
return {
|
|
7373
|
+
return {
|
|
7374
|
+
file: launch.file,
|
|
7375
|
+
args: readableArgs,
|
|
7376
|
+
env: envWithAgentHeap(launch.env)
|
|
7377
|
+
};
|
|
7178
7378
|
}
|
|
7179
7379
|
const wrapped = wrapElectronAsNodeLaunch(launch.file, readableArgs);
|
|
7180
7380
|
if (process.platform === "win32") {
|
|
7181
|
-
return {
|
|
7381
|
+
return {
|
|
7382
|
+
file: wrapped.file,
|
|
7383
|
+
args: wrapped.args,
|
|
7384
|
+
env: envWithAgentHeap(launch.env)
|
|
7385
|
+
};
|
|
7182
7386
|
}
|
|
7183
|
-
const env =
|
|
7387
|
+
const env = envWithAgentHeap(launch.env);
|
|
7184
7388
|
delete env.ELECTRON_RUN_AS_NODE;
|
|
7185
7389
|
return { file: wrapped.file, args: wrapped.args, env };
|
|
7186
7390
|
}
|
|
@@ -7201,16 +7405,18 @@ async function resolveNodeLaunch(scriptPath) {
|
|
|
7201
7405
|
env: { ELECTRON_RUN_AS_NODE: "1" }
|
|
7202
7406
|
};
|
|
7203
7407
|
}
|
|
7204
|
-
var
|
|
7408
|
+
var import_node_fs20, import_node_os7, import_node_path21, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
|
|
7205
7409
|
var init_node_launch = __esm({
|
|
7206
7410
|
"src/agents/node-launch.ts"() {
|
|
7207
7411
|
"use strict";
|
|
7208
|
-
|
|
7412
|
+
import_node_fs20 = require("fs");
|
|
7209
7413
|
import_node_os7 = require("os");
|
|
7210
|
-
|
|
7414
|
+
import_node_path21 = require("path");
|
|
7211
7415
|
init_nested_electron_env();
|
|
7212
7416
|
init_run();
|
|
7213
7417
|
init_packaged_runtime();
|
|
7418
|
+
AGENT_RUNNER_MAX_OLD_SPACE_MB = 8192;
|
|
7419
|
+
MAX_OLD_SPACE_FLAG = /(?:^|\s)(--max[-_]old[-_]space[-_]size)(?:[= ](\d+))?(?=\s|$)/;
|
|
7214
7420
|
PREFERRED_LTS_MAJORS = [24, 22, 20];
|
|
7215
7421
|
}
|
|
7216
7422
|
});
|
|
@@ -7298,37 +7504,37 @@ function corePackageDir() {
|
|
|
7298
7504
|
try {
|
|
7299
7505
|
const url = import_meta.url;
|
|
7300
7506
|
if (typeof url === "string" && url.length > 0) {
|
|
7301
|
-
return (0,
|
|
7507
|
+
return (0, import_node_path22.dirname)((0, import_node_url.fileURLToPath)(url));
|
|
7302
7508
|
}
|
|
7303
7509
|
} catch {
|
|
7304
7510
|
}
|
|
7305
7511
|
try {
|
|
7306
|
-
const req = (0, import_node_module.createRequire)((0,
|
|
7307
|
-
return (0,
|
|
7512
|
+
const req = (0, import_node_module.createRequire)((0, import_node_path22.join)(process.cwd(), "package.json"));
|
|
7513
|
+
return (0, import_node_path22.dirname)(req.resolve("@sideboard-ai/core"));
|
|
7308
7514
|
} catch {
|
|
7309
7515
|
return process.cwd();
|
|
7310
7516
|
}
|
|
7311
7517
|
}
|
|
7312
7518
|
function findSideboardMcpJsEntry() {
|
|
7313
7519
|
const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
|
|
7314
|
-
if (override && (0,
|
|
7520
|
+
if (override && (0, import_node_fs21.existsSync)(override)) return override;
|
|
7315
7521
|
const packaged = packagedMcpStdioPath();
|
|
7316
7522
|
if (packaged) return packaged;
|
|
7317
7523
|
let dir = corePackageDir();
|
|
7318
7524
|
for (let i = 0; i < 10; i++) {
|
|
7319
7525
|
const candidates = [
|
|
7320
|
-
(0,
|
|
7321
|
-
(0,
|
|
7322
|
-
(0,
|
|
7323
|
-
(0,
|
|
7324
|
-
(0,
|
|
7325
|
-
(0,
|
|
7326
|
-
(0,
|
|
7526
|
+
(0, import_node_path22.join)(dir, "mcp/run-stdio.js"),
|
|
7527
|
+
(0, import_node_path22.join)(dir, "mcp/run-stdio.cjs"),
|
|
7528
|
+
(0, import_node_path22.join)(dir, "dist/mcp/run-stdio.js"),
|
|
7529
|
+
(0, import_node_path22.join)(dir, "dist/mcp/run-stdio.cjs"),
|
|
7530
|
+
(0, import_node_path22.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
7531
|
+
(0, import_node_path22.join)(dir, "packages/cli/dist/index.js"),
|
|
7532
|
+
(0, import_node_path22.join)(dir, "cli/dist/index.js")
|
|
7327
7533
|
];
|
|
7328
7534
|
for (const p of candidates) {
|
|
7329
|
-
if ((0,
|
|
7535
|
+
if ((0, import_node_fs21.existsSync)(p) && !isAsarPath(p)) return p;
|
|
7330
7536
|
}
|
|
7331
|
-
const parent = (0,
|
|
7537
|
+
const parent = (0, import_node_path22.dirname)(dir);
|
|
7332
7538
|
if (parent === dir) break;
|
|
7333
7539
|
dir = parent;
|
|
7334
7540
|
}
|
|
@@ -7376,6 +7582,7 @@ async function buildInjectedMcpServers(opts) {
|
|
|
7376
7582
|
);
|
|
7377
7583
|
} catch {
|
|
7378
7584
|
}
|
|
7585
|
+
applyAgentRunnerHeapEnv(sideboard.env);
|
|
7379
7586
|
servers.push(sideboard);
|
|
7380
7587
|
}
|
|
7381
7588
|
if (opts.includeBrightsy && isBrightsyConnected()) {
|
|
@@ -7469,19 +7676,19 @@ function writeMcpServersConfig(servers) {
|
|
|
7469
7676
|
...env ? { env } : {}
|
|
7470
7677
|
};
|
|
7471
7678
|
}
|
|
7472
|
-
const dir = (0,
|
|
7473
|
-
const cfgPath = (0,
|
|
7474
|
-
(0,
|
|
7679
|
+
const dir = (0, import_node_fs21.mkdtempSync)((0, import_node_path22.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
|
|
7680
|
+
const cfgPath = (0, import_node_path22.join)(dir, "mcp.json");
|
|
7681
|
+
(0, import_node_fs21.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
|
|
7475
7682
|
return cfgPath;
|
|
7476
7683
|
}
|
|
7477
|
-
var
|
|
7684
|
+
var import_node_fs21, import_node_module, import_node_os8, import_node_path22, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
|
|
7478
7685
|
var init_injected_mcp = __esm({
|
|
7479
7686
|
"src/agents/injected-mcp.ts"() {
|
|
7480
7687
|
"use strict";
|
|
7481
|
-
|
|
7688
|
+
import_node_fs21 = require("fs");
|
|
7482
7689
|
import_node_module = require("module");
|
|
7483
7690
|
import_node_os8 = require("os");
|
|
7484
|
-
|
|
7691
|
+
import_node_path22 = require("path");
|
|
7485
7692
|
import_node_url = require("url");
|
|
7486
7693
|
init_run();
|
|
7487
7694
|
init_config();
|
|
@@ -7655,6 +7862,80 @@ function claudeParentToolUseId(obj) {
|
|
|
7655
7862
|
}
|
|
7656
7863
|
return void 0;
|
|
7657
7864
|
}
|
|
7865
|
+
function claudeString(obj, key) {
|
|
7866
|
+
const v = obj[key];
|
|
7867
|
+
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
7868
|
+
}
|
|
7869
|
+
function eventsFromClaudeSystem(obj) {
|
|
7870
|
+
const subtype = claudeString(obj, "subtype") ?? "";
|
|
7871
|
+
const parentId = claudeParentToolUseId(obj);
|
|
7872
|
+
if (subtype === "init") {
|
|
7873
|
+
if (parentId) return null;
|
|
7874
|
+
const sid = claudeString(obj, "session_id");
|
|
7875
|
+
return sid ? { type: "session_id", data: sid } : null;
|
|
7876
|
+
}
|
|
7877
|
+
if (subtype === "task_started") {
|
|
7878
|
+
const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id");
|
|
7879
|
+
if (!id) return null;
|
|
7880
|
+
const description = claudeString(obj, "description");
|
|
7881
|
+
const taskType = claudeString(obj, "task_type");
|
|
7882
|
+
const prompt = claudeString(obj, "prompt");
|
|
7883
|
+
return withEventParentId(
|
|
7884
|
+
{
|
|
7885
|
+
type: "tool_use",
|
|
7886
|
+
id,
|
|
7887
|
+
name: taskType || "Agent",
|
|
7888
|
+
input: {
|
|
7889
|
+
...description ? { description } : {},
|
|
7890
|
+
...prompt ? { prompt } : {},
|
|
7891
|
+
...claudeString(obj, "task_id") ? { task_id: claudeString(obj, "task_id") } : {}
|
|
7892
|
+
}
|
|
7893
|
+
},
|
|
7894
|
+
parentId
|
|
7895
|
+
);
|
|
7896
|
+
}
|
|
7897
|
+
if (subtype === "task_notification") {
|
|
7898
|
+
const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id") ?? parentId;
|
|
7899
|
+
if (!id) return null;
|
|
7900
|
+
const status = claudeString(obj, "status") ?? "working";
|
|
7901
|
+
const tools = typeof obj.tool_uses === "number" ? obj.tool_uses : void 0;
|
|
7902
|
+
const durationMs = typeof obj.duration_ms === "number" ? obj.duration_ms : void 0;
|
|
7903
|
+
const lastTool = claudeString(obj, "last_tool") ?? claudeString(obj, "current_tool") ?? claudeString(obj, "tool");
|
|
7904
|
+
const snapshot = [
|
|
7905
|
+
status,
|
|
7906
|
+
tools != null ? `${tools} tools` : null,
|
|
7907
|
+
durationMs != null ? `${Math.round(durationMs / 1e3)}s` : null,
|
|
7908
|
+
lastTool
|
|
7909
|
+
].filter((bit) => Boolean(bit)).join(" \xB7 ");
|
|
7910
|
+
return [
|
|
7911
|
+
{
|
|
7912
|
+
type: "tool_use",
|
|
7913
|
+
id,
|
|
7914
|
+
name: claudeString(obj, "task_type") || "Agent",
|
|
7915
|
+
input: {
|
|
7916
|
+
live_status: status,
|
|
7917
|
+
...tools != null ? { live_tool_uses: tools } : {},
|
|
7918
|
+
...durationMs != null ? { live_duration_ms: durationMs } : {},
|
|
7919
|
+
...lastTool ? { live_last_tool: lastTool } : {}
|
|
7920
|
+
}
|
|
7921
|
+
},
|
|
7922
|
+
withEventParentId(
|
|
7923
|
+
{ type: "thinking", data: snapshot, replace: true },
|
|
7924
|
+
id
|
|
7925
|
+
)
|
|
7926
|
+
];
|
|
7927
|
+
}
|
|
7928
|
+
if (subtype === "api_retry") {
|
|
7929
|
+
const attempt = obj.attempt;
|
|
7930
|
+
const max = obj.max_retries;
|
|
7931
|
+
const delay = obj.retry_delay_ms;
|
|
7932
|
+
return {
|
|
7933
|
+
type: "thinking",
|
|
7934
|
+
data: `API retry ${attempt ?? "?"}/${max ?? "?"}${typeof delay === "number" ? ` (wait ${delay}ms)` : ""}`
|
|
7935
|
+
};
|
|
7936
|
+
}
|
|
7937
|
+
return null;
|
|
7938
|
+
}
|
|
7658
7939
|
function parseIssuesJson(raw) {
|
|
7659
7940
|
const text4 = raw.trim();
|
|
7660
7941
|
const candidates = [text4];
|
|
@@ -7680,11 +7961,11 @@ function parseIssuesJson(raw) {
|
|
|
7680
7961
|
}
|
|
7681
7962
|
return [];
|
|
7682
7963
|
}
|
|
7683
|
-
var
|
|
7964
|
+
var import_node_fs22, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
|
|
7684
7965
|
var init_claude = __esm({
|
|
7685
7966
|
"src/agents/claude.ts"() {
|
|
7686
7967
|
"use strict";
|
|
7687
|
-
|
|
7968
|
+
import_node_fs22 = require("fs");
|
|
7688
7969
|
init_run();
|
|
7689
7970
|
init_app_settings();
|
|
7690
7971
|
init_claude_mcp();
|
|
@@ -7704,8 +7985,14 @@ var init_claude = __esm({
|
|
|
7704
7985
|
"WebSearch",
|
|
7705
7986
|
// Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
|
|
7706
7987
|
"Task",
|
|
7707
|
-
"Agent"
|
|
7988
|
+
"Agent",
|
|
7989
|
+
"TaskOutput",
|
|
7990
|
+
"TaskStop",
|
|
7991
|
+
"EnterWorktree",
|
|
7992
|
+
"ExitWorktree",
|
|
7993
|
+
"Skill"
|
|
7708
7994
|
];
|
|
7995
|
+
CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
|
|
7709
7996
|
CLAUDE_CHROME_ALLOWED_TOOLS = [
|
|
7710
7997
|
"mcp__claude-in-chrome",
|
|
7711
7998
|
"mcp__claude-in-chrome__*",
|
|
@@ -7717,7 +8004,7 @@ var init_claude = __esm({
|
|
|
7717
8004
|
async detect() {
|
|
7718
8005
|
const claude = resolveClaudeExecutable();
|
|
7719
8006
|
if (claude !== "claude") {
|
|
7720
|
-
if (!(0,
|
|
8007
|
+
if (!(0, import_node_fs22.existsSync)(claude)) {
|
|
7721
8008
|
return {
|
|
7722
8009
|
agent: "claude",
|
|
7723
8010
|
installed: false,
|
|
@@ -7834,7 +8121,12 @@ var init_claude = __esm({
|
|
|
7834
8121
|
stdin: useStdin ? `${promptText}
|
|
7835
8122
|
` : void 0,
|
|
7836
8123
|
// Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
|
|
7837
|
-
|
|
8124
|
+
// Raise the -p background-agent wait so long TaskOutput polls are not
|
|
8125
|
+
// abandoned at Claude Code’s 10-minute default.
|
|
8126
|
+
env: {
|
|
8127
|
+
CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
|
|
8128
|
+
CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS)
|
|
8129
|
+
}
|
|
7838
8130
|
};
|
|
7839
8131
|
},
|
|
7840
8132
|
parseEvent(line) {
|
|
@@ -7842,13 +8134,8 @@ var init_claude = __esm({
|
|
|
7842
8134
|
if (!trimmed) return null;
|
|
7843
8135
|
try {
|
|
7844
8136
|
const obj = JSON.parse(trimmed);
|
|
7845
|
-
if (obj.type === "system"
|
|
7846
|
-
|
|
7847
|
-
if (typeof sid === "string") return { type: "session_id", data: sid };
|
|
7848
|
-
return null;
|
|
7849
|
-
}
|
|
7850
|
-
if (obj.type === "system" && typeof obj.session_id === "string") {
|
|
7851
|
-
return { type: "session_id", data: obj.session_id };
|
|
8137
|
+
if (obj.type === "system") {
|
|
8138
|
+
return eventsFromClaudeSystem(obj);
|
|
7852
8139
|
}
|
|
7853
8140
|
if (obj.type === "assistant" || obj.type === "user") {
|
|
7854
8141
|
const parentId = claudeParentToolUseId(obj);
|
|
@@ -7968,7 +8255,7 @@ async function listCodexModels() {
|
|
|
7968
8255
|
if (codex === "codex") {
|
|
7969
8256
|
const which = await run("which", ["codex"], { reject: false });
|
|
7970
8257
|
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
7971
|
-
} else if (!(0,
|
|
8258
|
+
} else if (!(0, import_node_fs23.existsSync)(codex)) {
|
|
7972
8259
|
return FALLBACK_CODEX_MODELS;
|
|
7973
8260
|
}
|
|
7974
8261
|
const listed = await run(codex, ["debug", "models"], { reject: false });
|
|
@@ -8003,12 +8290,12 @@ function usageFromCodex(usage) {
|
|
|
8003
8290
|
}
|
|
8004
8291
|
function codexConfigHasNetworkAccess() {
|
|
8005
8292
|
const candidates = [
|
|
8006
|
-
(0,
|
|
8007
|
-
(0,
|
|
8293
|
+
(0, import_node_path23.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
|
|
8294
|
+
(0, import_node_path23.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
|
|
8008
8295
|
];
|
|
8009
8296
|
for (const path of candidates) {
|
|
8010
|
-
if (!(0,
|
|
8011
|
-
const text4 = (0,
|
|
8297
|
+
if (!(0, import_node_fs23.existsSync)(path)) continue;
|
|
8298
|
+
const text4 = (0, import_node_fs23.readFileSync)(path, "utf8");
|
|
8012
8299
|
if (/network_access\s*=\s*true/.test(text4)) return true;
|
|
8013
8300
|
}
|
|
8014
8301
|
return false;
|
|
@@ -8040,21 +8327,21 @@ function asRecord2(value) {
|
|
|
8040
8327
|
return void 0;
|
|
8041
8328
|
}
|
|
8042
8329
|
function codexLooksAuthenticated() {
|
|
8043
|
-
const authPath = (0,
|
|
8044
|
-
if (!(0,
|
|
8330
|
+
const authPath = (0, import_node_path23.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
|
|
8331
|
+
if (!(0, import_node_fs23.existsSync)(authPath)) return false;
|
|
8045
8332
|
try {
|
|
8046
|
-
return (0,
|
|
8333
|
+
return (0, import_node_fs23.statSync)(authPath).size > 2;
|
|
8047
8334
|
} catch {
|
|
8048
8335
|
return false;
|
|
8049
8336
|
}
|
|
8050
8337
|
}
|
|
8051
|
-
var
|
|
8338
|
+
var import_node_fs23, import_node_os9, import_node_path23, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
8052
8339
|
var init_codex = __esm({
|
|
8053
8340
|
"src/agents/codex.ts"() {
|
|
8054
8341
|
"use strict";
|
|
8055
|
-
|
|
8342
|
+
import_node_fs23 = require("fs");
|
|
8056
8343
|
import_node_os9 = require("os");
|
|
8057
|
-
|
|
8344
|
+
import_node_path23 = require("path");
|
|
8058
8345
|
init_run();
|
|
8059
8346
|
init_app_settings();
|
|
8060
8347
|
init_global_workspace();
|
|
@@ -8079,7 +8366,7 @@ var init_codex = __esm({
|
|
|
8079
8366
|
async detect() {
|
|
8080
8367
|
const codex = resolveAgentExecutable("codex");
|
|
8081
8368
|
if (codex !== "codex") {
|
|
8082
|
-
if (!(0,
|
|
8369
|
+
if (!(0, import_node_fs23.existsSync)(codex)) {
|
|
8083
8370
|
return {
|
|
8084
8371
|
agent: "codex",
|
|
8085
8372
|
installed: false,
|
|
@@ -8268,9 +8555,6 @@ var init_codex = __esm({
|
|
|
8268
8555
|
if (sid && (type === "thread.started" || type === "session" || !type)) {
|
|
8269
8556
|
return { type: "session_id", data: sid };
|
|
8270
8557
|
}
|
|
8271
|
-
if (sid && type.endsWith(".started")) {
|
|
8272
|
-
return { type: "session_id", data: sid };
|
|
8273
|
-
}
|
|
8274
8558
|
if (type === "turn.completed" || type === "turn_completed") {
|
|
8275
8559
|
const usage = usageFromCodex(obj.usage);
|
|
8276
8560
|
return usage ? { type: "usage", data: usage, scope: "turn" } : null;
|
|
@@ -8518,21 +8802,21 @@ function platformRipgrepPackage() {
|
|
|
8518
8802
|
}
|
|
8519
8803
|
function usableRipgrepPath(candidate) {
|
|
8520
8804
|
const raw = candidate?.trim();
|
|
8521
|
-
if (!raw || !(0,
|
|
8805
|
+
if (!raw || !(0, import_node_path24.isAbsolute)(raw)) return null;
|
|
8522
8806
|
const readable = nodeReadableScriptPath(raw);
|
|
8523
|
-
if (!(0,
|
|
8807
|
+
if (!(0, import_node_fs24.existsSync)(readable) || isAsarPath(readable)) return null;
|
|
8524
8808
|
return readable;
|
|
8525
8809
|
}
|
|
8526
8810
|
function walkForBundledRipgrep(startFile) {
|
|
8527
8811
|
if (!startFile) return null;
|
|
8528
8812
|
const pkg = platformRipgrepPackage();
|
|
8529
8813
|
const name = rgBinaryName();
|
|
8530
|
-
let dir = (0,
|
|
8531
|
-
const root = (0,
|
|
8814
|
+
let dir = (0, import_node_path24.dirname)((0, import_node_path24.resolve)(startFile));
|
|
8815
|
+
const root = (0, import_node_path24.parse)(dir).root;
|
|
8532
8816
|
while (dir !== root) {
|
|
8533
|
-
const hit = usableRipgrepPath((0,
|
|
8817
|
+
const hit = usableRipgrepPath((0, import_node_path24.join)(dir, "node_modules", pkg, "bin", name));
|
|
8534
8818
|
if (hit) return hit;
|
|
8535
|
-
const next = (0,
|
|
8819
|
+
const next = (0, import_node_path24.dirname)(dir);
|
|
8536
8820
|
if (next === dir) break;
|
|
8537
8821
|
dir = next;
|
|
8538
8822
|
}
|
|
@@ -8542,7 +8826,7 @@ function requireResolveBundledRipgrep(fromFile) {
|
|
|
8542
8826
|
try {
|
|
8543
8827
|
const req = (0, import_node_module2.createRequire)(fromFile);
|
|
8544
8828
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
8545
|
-
return usableRipgrepPath((0,
|
|
8829
|
+
return usableRipgrepPath((0, import_node_path24.join)((0, import_node_path24.dirname)(pkgJson), "bin", rgBinaryName()));
|
|
8546
8830
|
} catch {
|
|
8547
8831
|
return null;
|
|
8548
8832
|
}
|
|
@@ -8555,24 +8839,24 @@ function resolveCursorRipgrepPath(opts) {
|
|
|
8555
8839
|
packagedCursorRipgrepCandidate(platformRipgrepPackage(), rgBinaryName())
|
|
8556
8840
|
);
|
|
8557
8841
|
if (fromPackaged) return fromPackaged;
|
|
8558
|
-
const start = opts?.startFile?.trim() || process.argv[1] ||
|
|
8842
|
+
const start = opts?.startFile?.trim() || process.argv[1] || // CJS bundle only — ESM has no __filename; argv[1] is the running script.
|
|
8843
|
+
// eslint-disable-next-line camelcase
|
|
8844
|
+
(typeof __filename !== "undefined" ? __filename : "");
|
|
8559
8845
|
return walkForBundledRipgrep(start) ?? requireResolveBundledRipgrep(start);
|
|
8560
8846
|
}
|
|
8561
8847
|
function cursorRipgrepEnv(opts) {
|
|
8562
8848
|
const path = resolveCursorRipgrepPath(opts);
|
|
8563
8849
|
return path ? { [RIPGREP_ENV]: path } : {};
|
|
8564
8850
|
}
|
|
8565
|
-
var
|
|
8851
|
+
var import_node_fs24, import_node_module2, import_node_path24, RIPGREP_ENV;
|
|
8566
8852
|
var init_cursor_ripgrep = __esm({
|
|
8567
8853
|
"src/agents/cursor-ripgrep.ts"() {
|
|
8568
8854
|
"use strict";
|
|
8569
|
-
|
|
8855
|
+
import_node_fs24 = require("fs");
|
|
8570
8856
|
import_node_module2 = require("module");
|
|
8571
|
-
|
|
8572
|
-
import_node_url2 = require("url");
|
|
8857
|
+
import_node_path24 = require("path");
|
|
8573
8858
|
init_node_launch();
|
|
8574
8859
|
init_packaged_runtime();
|
|
8575
|
-
import_meta2 = {};
|
|
8576
8860
|
RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
8577
8861
|
}
|
|
8578
8862
|
});
|
|
@@ -8616,11 +8900,11 @@ function entryDir() {
|
|
|
8616
8900
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
8617
8901
|
if (cjsDir) return cjsDir;
|
|
8618
8902
|
try {
|
|
8619
|
-
return (0,
|
|
8903
|
+
return (0, import_node_path25.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
8620
8904
|
} catch {
|
|
8621
8905
|
try {
|
|
8622
8906
|
const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
|
|
8623
|
-
return (0,
|
|
8907
|
+
return (0, import_node_path25.dirname)(req.resolve("@sideboard-ai/core"));
|
|
8624
8908
|
} catch {
|
|
8625
8909
|
return process.cwd();
|
|
8626
8910
|
}
|
|
@@ -8631,28 +8915,28 @@ function cursorRunnerPath() {
|
|
|
8631
8915
|
if (packaged) return packaged;
|
|
8632
8916
|
const root = entryDir();
|
|
8633
8917
|
const candidates = [
|
|
8634
|
-
(0,
|
|
8635
|
-
(0,
|
|
8918
|
+
(0, import_node_path25.join)(root, "agents", "cursor-runner.js"),
|
|
8919
|
+
(0, import_node_path25.join)(root, "agents", "cursor-runner.cjs"),
|
|
8636
8920
|
// If somehow resolved from package root instead of dist/
|
|
8637
|
-
(0,
|
|
8638
|
-
(0,
|
|
8921
|
+
(0, import_node_path25.join)(root, "dist", "agents", "cursor-runner.js"),
|
|
8922
|
+
(0, import_node_path25.join)(root, "dist", "agents", "cursor-runner.cjs"),
|
|
8639
8923
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
8640
|
-
(0,
|
|
8641
|
-
(0,
|
|
8924
|
+
(0, import_node_path25.join)(root, "cursor-runner.ts"),
|
|
8925
|
+
(0, import_node_path25.join)(root, "src", "agents", "cursor-runner.ts")
|
|
8642
8926
|
];
|
|
8643
8927
|
for (const candidate of candidates) {
|
|
8644
|
-
if ((0,
|
|
8928
|
+
if ((0, import_node_fs25.existsSync)(candidate)) return candidate;
|
|
8645
8929
|
}
|
|
8646
8930
|
return candidates[0];
|
|
8647
8931
|
}
|
|
8648
|
-
var
|
|
8932
|
+
var import_node_fs25, import_node_module3, import_node_path25, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
|
|
8649
8933
|
var init_cursor = __esm({
|
|
8650
8934
|
"src/agents/cursor.ts"() {
|
|
8651
8935
|
"use strict";
|
|
8652
|
-
|
|
8936
|
+
import_node_fs25 = require("fs");
|
|
8653
8937
|
import_node_module3 = require("module");
|
|
8654
|
-
|
|
8655
|
-
|
|
8938
|
+
import_node_path25 = require("path");
|
|
8939
|
+
import_node_url2 = require("url");
|
|
8656
8940
|
import_sdk = require("@cursor/sdk");
|
|
8657
8941
|
init_run();
|
|
8658
8942
|
init_app_settings();
|
|
@@ -8664,7 +8948,7 @@ var init_cursor = __esm({
|
|
|
8664
8948
|
init_packaged_runtime();
|
|
8665
8949
|
init_turn_input();
|
|
8666
8950
|
init_cursor_events();
|
|
8667
|
-
|
|
8951
|
+
import_meta2 = {};
|
|
8668
8952
|
FALLBACK_CURSOR_MODELS = [
|
|
8669
8953
|
{ id: "default", displayName: "Auto" },
|
|
8670
8954
|
{ id: "composer-2.5", displayName: "Composer 2.5" },
|
|
@@ -8801,7 +9085,7 @@ async function listOpencodeModels() {
|
|
|
8801
9085
|
if (opencode === "opencode") {
|
|
8802
9086
|
const which = await run("which", ["opencode"], { reject: false });
|
|
8803
9087
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
8804
|
-
} else if (!(0,
|
|
9088
|
+
} else if (!(0, import_node_fs26.existsSync)(opencode)) {
|
|
8805
9089
|
return FALLBACK_OPENCODE_MODELS;
|
|
8806
9090
|
}
|
|
8807
9091
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -8831,11 +9115,11 @@ function usageFromOpencode(tokens) {
|
|
|
8831
9115
|
cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
|
|
8832
9116
|
};
|
|
8833
9117
|
}
|
|
8834
|
-
var
|
|
9118
|
+
var import_node_fs26, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
|
|
8835
9119
|
var init_opencode = __esm({
|
|
8836
9120
|
"src/agents/opencode.ts"() {
|
|
8837
9121
|
"use strict";
|
|
8838
|
-
|
|
9122
|
+
import_node_fs26 = require("fs");
|
|
8839
9123
|
init_run();
|
|
8840
9124
|
init_app_settings();
|
|
8841
9125
|
init_global_workspace();
|
|
@@ -8862,7 +9146,7 @@ var init_opencode = __esm({
|
|
|
8862
9146
|
async detect() {
|
|
8863
9147
|
const opencode = resolveAgentExecutable("opencode");
|
|
8864
9148
|
if (opencode !== "opencode") {
|
|
8865
|
-
if (!(0,
|
|
9149
|
+
if (!(0, import_node_fs26.existsSync)(opencode)) {
|
|
8866
9150
|
return {
|
|
8867
9151
|
agent: "opencode",
|
|
8868
9152
|
installed: false,
|
|
@@ -8948,7 +9232,8 @@ var init_opencode = __esm({
|
|
|
8948
9232
|
return { type: "stderr", data: detail };
|
|
8949
9233
|
}
|
|
8950
9234
|
const sid = typeof obj.sessionID === "string" && obj.sessionID || typeof obj.sessionId === "string" && obj.sessionId || typeof obj.session_id === "string" && obj.session_id;
|
|
8951
|
-
|
|
9235
|
+
const childSid = str3(obj.childSessionID) ?? str3(obj.childSessionId) ?? str3(obj.parentID) ?? str3(obj.parentId);
|
|
9236
|
+
if (sid && !childSid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
|
|
8952
9237
|
return { type: "session_id", data: sid };
|
|
8953
9238
|
}
|
|
8954
9239
|
if (obj.type === "text") {
|
|
@@ -9679,6 +9964,11 @@ function createAgentStreamCoalescer(emit, opts) {
|
|
|
9679
9964
|
return;
|
|
9680
9965
|
}
|
|
9681
9966
|
if (!event.data) return;
|
|
9967
|
+
if (event.type === "thinking" && event.replace) {
|
|
9968
|
+
flush2();
|
|
9969
|
+
emit(event);
|
|
9970
|
+
return;
|
|
9971
|
+
}
|
|
9682
9972
|
if (pending && pending.type === event.type && parentKey(pending) === parentKey(event)) {
|
|
9683
9973
|
pending.data += event.data;
|
|
9684
9974
|
} else {
|
|
@@ -9735,6 +10025,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
9735
10025
|
}
|
|
9736
10026
|
const env = childEnvWithAppSettings(cmd.env);
|
|
9737
10027
|
applyPromptCacheTtlEnv(thread.agent, env);
|
|
10028
|
+
applyAgentRunnerHeapEnv(env);
|
|
9738
10029
|
try {
|
|
9739
10030
|
if (isOrchestratorThread(thread)) {
|
|
9740
10031
|
mergeAgentGitAuthEnv(env, await resolveAgentGitAuthEnv(env));
|
|
@@ -9842,9 +10133,11 @@ var init_spawn = __esm({
|
|
|
9842
10133
|
init_agents();
|
|
9843
10134
|
init_orchestrator_capable();
|
|
9844
10135
|
init_message_parts();
|
|
10136
|
+
init_node_launch();
|
|
9845
10137
|
init_path();
|
|
9846
10138
|
init_usage();
|
|
9847
10139
|
init_cursor_stream_coalesce();
|
|
10140
|
+
init_node_launch();
|
|
9848
10141
|
}
|
|
9849
10142
|
});
|
|
9850
10143
|
|
|
@@ -10570,21 +10863,21 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
10570
10863
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
10571
10864
|
}
|
|
10572
10865
|
function readTextIfPresent(abs) {
|
|
10573
|
-
if (!(0,
|
|
10866
|
+
if (!(0, import_node_fs27.existsSync)(abs)) return null;
|
|
10574
10867
|
try {
|
|
10575
|
-
const content = (0,
|
|
10868
|
+
const content = (0, import_node_fs27.readFileSync)(abs, "utf8");
|
|
10576
10869
|
return content.trim() ? content : null;
|
|
10577
10870
|
} catch {
|
|
10578
10871
|
return null;
|
|
10579
10872
|
}
|
|
10580
10873
|
}
|
|
10581
10874
|
function readLocalGuidelines(worktreePath) {
|
|
10582
|
-
const localAbs = (0,
|
|
10875
|
+
const localAbs = (0, import_node_path26.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
10583
10876
|
const localContent = readTextIfPresent(localAbs);
|
|
10584
10877
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
10585
10878
|
return { path: REVIEW_REQUEST_PATH, content: localContent };
|
|
10586
10879
|
}
|
|
10587
|
-
const legacyAbs = (0,
|
|
10880
|
+
const legacyAbs = (0, import_node_path26.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
10588
10881
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
10589
10882
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
10590
10883
|
return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
|
|
@@ -10600,20 +10893,20 @@ function skillGuidelines(content, source) {
|
|
|
10600
10893
|
};
|
|
10601
10894
|
}
|
|
10602
10895
|
function ensureReviewSkillFile(worktreePath) {
|
|
10603
|
-
const abs = (0,
|
|
10896
|
+
const abs = (0, import_node_path26.join)(worktreePath, REVIEW_SKILL_PATH);
|
|
10604
10897
|
const existing = readTextIfPresent(abs);
|
|
10605
10898
|
if (existing) {
|
|
10606
10899
|
return { path: REVIEW_SKILL_PATH, content: existing, wrote: false };
|
|
10607
10900
|
}
|
|
10608
|
-
const fromRepo = readTextIfPresent((0,
|
|
10901
|
+
const fromRepo = readTextIfPresent((0, import_node_path26.join)(worktreePath, REPO_REVIEW_PATH));
|
|
10609
10902
|
const fromLocal = readLocalGuidelines(worktreePath)?.content ?? null;
|
|
10610
10903
|
const content = wrapReviewSkillMarkdown(fromRepo ?? fromLocal ?? REVIEW_REQUEST_TEMPLATE);
|
|
10611
|
-
(0,
|
|
10612
|
-
(0,
|
|
10904
|
+
(0, import_node_fs27.mkdirSync)((0, import_node_path26.dirname)(abs), { recursive: true });
|
|
10905
|
+
(0, import_node_fs27.writeFileSync)(abs, content, "utf8");
|
|
10613
10906
|
return { path: REVIEW_SKILL_PATH, content, wrote: true };
|
|
10614
10907
|
}
|
|
10615
10908
|
function resolveReviewGuidelines(worktreePath) {
|
|
10616
|
-
const skillContent = readTextIfPresent((0,
|
|
10909
|
+
const skillContent = readTextIfPresent((0, import_node_path26.join)(worktreePath, REVIEW_SKILL_PATH));
|
|
10617
10910
|
if (skillContent) return skillGuidelines(skillContent, "skill");
|
|
10618
10911
|
const local = readLocalGuidelines(worktreePath);
|
|
10619
10912
|
if (local) {
|
|
@@ -10663,13 +10956,13 @@ async function requestReview(threadRef, send) {
|
|
|
10663
10956
|
const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
|
|
10664
10957
|
return { tab: started, from };
|
|
10665
10958
|
}
|
|
10666
|
-
var import_node_crypto5,
|
|
10959
|
+
var import_node_crypto5, import_node_fs27, import_node_path26, REPO_REVIEW_PATH, REPO_REVIEW_NAME, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
|
|
10667
10960
|
var init_request_review = __esm({
|
|
10668
10961
|
"src/review/request-review.ts"() {
|
|
10669
10962
|
"use strict";
|
|
10670
10963
|
import_node_crypto5 = require("crypto");
|
|
10671
|
-
|
|
10672
|
-
|
|
10964
|
+
import_node_fs27 = require("fs");
|
|
10965
|
+
import_node_path26 = require("path");
|
|
10673
10966
|
init_global_workspace();
|
|
10674
10967
|
init_chat_tabs();
|
|
10675
10968
|
init_thread_store();
|
|
@@ -10694,9 +10987,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
10694
10987
|
return new RegExp(`^${escaped}$`).test(name);
|
|
10695
10988
|
}
|
|
10696
10989
|
function readWorktreeInclude(repoPath) {
|
|
10697
|
-
const path = (0,
|
|
10698
|
-
if (!(0,
|
|
10699
|
-
return (0,
|
|
10990
|
+
const path = (0, import_node_path27.join)(repoPath, ".worktreeinclude");
|
|
10991
|
+
if (!(0, import_node_fs28.existsSync)(path)) return [];
|
|
10992
|
+
return (0, import_node_fs28.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
10700
10993
|
}
|
|
10701
10994
|
function resolveFilesToCopy(repoPath) {
|
|
10702
10995
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -10706,10 +10999,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
10706
10999
|
if (settings?.fileIncludeGlobs?.length) {
|
|
10707
11000
|
const matched = [];
|
|
10708
11001
|
try {
|
|
10709
|
-
for (const entry of (0,
|
|
11002
|
+
for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
10710
11003
|
if (!entry.isFile()) continue;
|
|
10711
11004
|
for (const glob of settings.fileIncludeGlobs) {
|
|
10712
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
11005
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path27.basename)(glob), entry.name)) {
|
|
10713
11006
|
matched.push(entry.name);
|
|
10714
11007
|
break;
|
|
10715
11008
|
}
|
|
@@ -10721,7 +11014,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
10721
11014
|
}
|
|
10722
11015
|
const defaults = [];
|
|
10723
11016
|
try {
|
|
10724
|
-
for (const entry of (0,
|
|
11017
|
+
for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
10725
11018
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
10726
11019
|
defaults.push(entry.name);
|
|
10727
11020
|
}
|
|
@@ -10735,11 +11028,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
10735
11028
|
const patterns = resolveFilesToCopy(repoPath);
|
|
10736
11029
|
const copied = [];
|
|
10737
11030
|
for (const rel of patterns) {
|
|
10738
|
-
const src = (0,
|
|
10739
|
-
if (!(0,
|
|
10740
|
-
const dest = (0,
|
|
10741
|
-
(0,
|
|
10742
|
-
(0,
|
|
11031
|
+
const src = (0, import_node_path27.join)(repoPath, rel);
|
|
11032
|
+
if (!(0, import_node_fs28.existsSync)(src)) continue;
|
|
11033
|
+
const dest = (0, import_node_path27.join)(worktreePath, rel);
|
|
11034
|
+
(0, import_node_fs28.mkdirSync)((0, import_node_path27.dirname)(dest), { recursive: true });
|
|
11035
|
+
(0, import_node_fs28.copyFileSync)(src, dest);
|
|
10743
11036
|
copied.push(rel);
|
|
10744
11037
|
}
|
|
10745
11038
|
return copied;
|
|
@@ -10774,7 +11067,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
10774
11067
|
const env = stripNestedElectronEnv({
|
|
10775
11068
|
...baseEnv ?? process.env
|
|
10776
11069
|
});
|
|
10777
|
-
const name = opts.workspaceName ?? (0,
|
|
11070
|
+
const name = opts.workspaceName ?? (0, import_node_path27.basename)(opts.worktreePath);
|
|
10778
11071
|
const ports = opts.ports ?? [];
|
|
10779
11072
|
const primary = ports[0];
|
|
10780
11073
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -11035,13 +11328,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
11035
11328
|
done: handle.done
|
|
11036
11329
|
};
|
|
11037
11330
|
}
|
|
11038
|
-
var
|
|
11331
|
+
var import_node_fs28, import_node_net, import_node_path27, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
11039
11332
|
var init_conductor = __esm({
|
|
11040
11333
|
"src/hook/conductor.ts"() {
|
|
11041
11334
|
"use strict";
|
|
11042
|
-
|
|
11335
|
+
import_node_fs28 = require("fs");
|
|
11043
11336
|
import_node_net = require("net");
|
|
11044
|
-
|
|
11337
|
+
import_node_path27 = require("path");
|
|
11045
11338
|
import_execa4 = require("execa");
|
|
11046
11339
|
import_node_readline3 = require("readline");
|
|
11047
11340
|
init_settings();
|
|
@@ -11067,9 +11360,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11067
11360
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
11068
11361
|
);
|
|
11069
11362
|
const homeRoot = sideboardWorkspacesDir();
|
|
11070
|
-
if ((0,
|
|
11363
|
+
if ((0, import_node_fs29.existsSync)(homeRoot)) {
|
|
11071
11364
|
try {
|
|
11072
|
-
for (const entry of (0,
|
|
11365
|
+
for (const entry of (0, import_node_fs29.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
11073
11366
|
if (!entry.isDirectory()) continue;
|
|
11074
11367
|
void entry;
|
|
11075
11368
|
}
|
|
@@ -11079,7 +11372,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11079
11372
|
const orphans = [];
|
|
11080
11373
|
const seen = /* @__PURE__ */ new Set();
|
|
11081
11374
|
for (const repoPath of repos) {
|
|
11082
|
-
if (!repoPath || !(0,
|
|
11375
|
+
if (!repoPath || !(0, import_node_fs29.existsSync)(repoPath)) continue;
|
|
11083
11376
|
try {
|
|
11084
11377
|
const wts = await listWorktrees(repoPath);
|
|
11085
11378
|
for (const wt of wts) {
|
|
@@ -11090,7 +11383,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11090
11383
|
seen.add(path);
|
|
11091
11384
|
let mtimeMs = 0;
|
|
11092
11385
|
try {
|
|
11093
|
-
mtimeMs = (0,
|
|
11386
|
+
mtimeMs = (0, import_node_fs29.statSync)(path).mtimeMs;
|
|
11094
11387
|
} catch {
|
|
11095
11388
|
mtimeMs = 0;
|
|
11096
11389
|
}
|
|
@@ -11100,16 +11393,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11100
11393
|
}
|
|
11101
11394
|
try {
|
|
11102
11395
|
const root = worktreesRoot(repoPath);
|
|
11103
|
-
if ((0,
|
|
11104
|
-
for (const entry of (0,
|
|
11396
|
+
if ((0, import_node_fs29.existsSync)(root)) {
|
|
11397
|
+
for (const entry of (0, import_node_fs29.readdirSync)(root, { withFileTypes: true })) {
|
|
11105
11398
|
if (!entry.isDirectory()) continue;
|
|
11106
|
-
const path = (0,
|
|
11399
|
+
const path = (0, import_node_path28.join)(root, entry.name).replace(/\/$/, "");
|
|
11107
11400
|
if (known.has(path) || seen.has(path)) continue;
|
|
11108
|
-
if (!(0,
|
|
11401
|
+
if (!(0, import_node_fs29.existsSync)((0, import_node_path28.join)(path, ".git"))) continue;
|
|
11109
11402
|
seen.add(path);
|
|
11110
11403
|
let mtimeMs = 0;
|
|
11111
11404
|
try {
|
|
11112
|
-
mtimeMs = (0,
|
|
11405
|
+
mtimeMs = (0, import_node_fs29.statSync)(path).mtimeMs;
|
|
11113
11406
|
} catch {
|
|
11114
11407
|
mtimeMs = Date.now();
|
|
11115
11408
|
}
|
|
@@ -11161,12 +11454,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
|
|
|
11161
11454
|
const elapsed = Date.now() - Date.parse(last);
|
|
11162
11455
|
return elapsed >= intervalHours * 36e5;
|
|
11163
11456
|
}
|
|
11164
|
-
var
|
|
11457
|
+
var import_node_fs29, import_node_path28;
|
|
11165
11458
|
var init_orphan_cleanup = __esm({
|
|
11166
11459
|
"src/git/orphan-cleanup.ts"() {
|
|
11167
11460
|
"use strict";
|
|
11168
|
-
|
|
11169
|
-
|
|
11461
|
+
import_node_fs29 = require("fs");
|
|
11462
|
+
import_node_path28 = require("path");
|
|
11170
11463
|
init_worktree();
|
|
11171
11464
|
init_thread_store();
|
|
11172
11465
|
init_paths();
|
|
@@ -11273,38 +11566,38 @@ __export(workspaces_exports, {
|
|
|
11273
11566
|
syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
|
|
11274
11567
|
});
|
|
11275
11568
|
function workspacesFile() {
|
|
11276
|
-
return (0,
|
|
11569
|
+
return (0, import_node_path29.join)(appDataDir(), "workspaces.json");
|
|
11277
11570
|
}
|
|
11278
11571
|
function removedWorkspacesFile() {
|
|
11279
|
-
return (0,
|
|
11572
|
+
return (0, import_node_path29.join)(appDataDir(), "removed-workspaces.json");
|
|
11280
11573
|
}
|
|
11281
11574
|
function readAll() {
|
|
11282
11575
|
const path = workspacesFile();
|
|
11283
|
-
if (!(0,
|
|
11576
|
+
if (!(0, import_node_fs30.existsSync)(path)) return [];
|
|
11284
11577
|
try {
|
|
11285
|
-
const raw = JSON.parse((0,
|
|
11578
|
+
const raw = JSON.parse((0, import_node_fs30.readFileSync)(path, "utf8"));
|
|
11286
11579
|
return Array.isArray(raw) ? raw : [];
|
|
11287
11580
|
} catch {
|
|
11288
11581
|
return [];
|
|
11289
11582
|
}
|
|
11290
11583
|
}
|
|
11291
11584
|
function writeAll(list) {
|
|
11292
|
-
(0,
|
|
11293
|
-
(0,
|
|
11585
|
+
(0, import_node_fs30.mkdirSync)(appDataDir(), { recursive: true });
|
|
11586
|
+
(0, import_node_fs30.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
|
|
11294
11587
|
}
|
|
11295
11588
|
function readRemoved() {
|
|
11296
11589
|
const path = removedWorkspacesFile();
|
|
11297
|
-
if (!(0,
|
|
11590
|
+
if (!(0, import_node_fs30.existsSync)(path)) return /* @__PURE__ */ new Set();
|
|
11298
11591
|
try {
|
|
11299
|
-
const raw = JSON.parse((0,
|
|
11592
|
+
const raw = JSON.parse((0, import_node_fs30.readFileSync)(path, "utf8"));
|
|
11300
11593
|
return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
|
|
11301
11594
|
} catch {
|
|
11302
11595
|
return /* @__PURE__ */ new Set();
|
|
11303
11596
|
}
|
|
11304
11597
|
}
|
|
11305
11598
|
function writeRemoved(paths) {
|
|
11306
|
-
(0,
|
|
11307
|
-
(0,
|
|
11599
|
+
(0, import_node_fs30.mkdirSync)(appDataDir(), { recursive: true });
|
|
11600
|
+
(0, import_node_fs30.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
|
|
11308
11601
|
}
|
|
11309
11602
|
function rememberRemoved(repoPath) {
|
|
11310
11603
|
const next = readRemoved();
|
|
@@ -11327,7 +11620,7 @@ function listWorkspaces() {
|
|
|
11327
11620
|
async function addWorkspace(repoPath) {
|
|
11328
11621
|
const root = await resolveRepoRoot(repoPath);
|
|
11329
11622
|
if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
|
|
11330
|
-
if (!(0,
|
|
11623
|
+
if (!(0, import_node_fs30.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
|
|
11331
11624
|
forgetRemoved(root);
|
|
11332
11625
|
await ensureGhPreferOrigin(root);
|
|
11333
11626
|
const current = readAll();
|
|
@@ -11335,7 +11628,7 @@ async function addWorkspace(repoPath) {
|
|
|
11335
11628
|
if (existing) return existing;
|
|
11336
11629
|
const next = {
|
|
11337
11630
|
path: root,
|
|
11338
|
-
name: (0,
|
|
11631
|
+
name: (0, import_node_path29.basename)(root),
|
|
11339
11632
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
11340
11633
|
};
|
|
11341
11634
|
writeAll([...current, next]);
|
|
@@ -11357,10 +11650,10 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
11357
11650
|
if (!path || path === "/" || isGlobalRepoPath(path) || byPath.has(path) || removed.has(path)) {
|
|
11358
11651
|
continue;
|
|
11359
11652
|
}
|
|
11360
|
-
if (!(0,
|
|
11653
|
+
if (!(0, import_node_fs30.existsSync)(path)) continue;
|
|
11361
11654
|
const ws = {
|
|
11362
11655
|
path,
|
|
11363
|
-
name: (0,
|
|
11656
|
+
name: (0, import_node_path29.basename)(path),
|
|
11364
11657
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
11365
11658
|
};
|
|
11366
11659
|
byPath.set(path, ws);
|
|
@@ -11370,12 +11663,12 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
11370
11663
|
if (dirty) writeAll(next);
|
|
11371
11664
|
return next.sort((a, b) => a.name.localeCompare(b.name));
|
|
11372
11665
|
}
|
|
11373
|
-
var
|
|
11666
|
+
var import_node_fs30, import_node_path29;
|
|
11374
11667
|
var init_workspaces2 = __esm({
|
|
11375
11668
|
"src/store/workspaces.ts"() {
|
|
11376
11669
|
"use strict";
|
|
11377
|
-
|
|
11378
|
-
|
|
11670
|
+
import_node_fs30 = require("fs");
|
|
11671
|
+
import_node_path29 = require("path");
|
|
11379
11672
|
init_paths();
|
|
11380
11673
|
init_global_workspace();
|
|
11381
11674
|
init_worktree();
|
|
@@ -11388,12 +11681,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
11388
11681
|
if (!url) throw new Error("Clone URL is required");
|
|
11389
11682
|
let name = opts.name?.trim();
|
|
11390
11683
|
if (!name) {
|
|
11391
|
-
const leaf = (0,
|
|
11684
|
+
const leaf = (0, import_node_path30.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
11392
11685
|
name = leaf || "repo";
|
|
11393
11686
|
}
|
|
11394
11687
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
11395
|
-
const dest = (0,
|
|
11396
|
-
if ((0,
|
|
11688
|
+
const dest = (0, import_node_path30.join)(sideboardReposDir(), name);
|
|
11689
|
+
if ((0, import_node_fs31.existsSync)(dest)) {
|
|
11397
11690
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
11398
11691
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
11399
11692
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -11408,12 +11701,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
11408
11701
|
const workspace = await ensureWorkspace(repoPath);
|
|
11409
11702
|
return { repoPath, workspace };
|
|
11410
11703
|
}
|
|
11411
|
-
var
|
|
11704
|
+
var import_node_fs31, import_node_path30, import_execa6;
|
|
11412
11705
|
var init_clone_repo = __esm({
|
|
11413
11706
|
"src/git/clone-repo.ts"() {
|
|
11414
11707
|
"use strict";
|
|
11415
|
-
|
|
11416
|
-
|
|
11708
|
+
import_node_fs31 = require("fs");
|
|
11709
|
+
import_node_path30 = require("path");
|
|
11417
11710
|
import_execa6 = require("execa");
|
|
11418
11711
|
init_paths();
|
|
11419
11712
|
init_workspaces2();
|
|
@@ -11423,11 +11716,11 @@ var init_clone_repo = __esm({
|
|
|
11423
11716
|
|
|
11424
11717
|
// src/store/desktop-host.ts
|
|
11425
11718
|
function desktopHostPidPath() {
|
|
11426
|
-
return (0,
|
|
11719
|
+
return (0, import_node_path31.join)(appDataDir(), "desktop-host.pid");
|
|
11427
11720
|
}
|
|
11428
11721
|
function readDesktopHostPid() {
|
|
11429
11722
|
try {
|
|
11430
|
-
const pid = Number.parseInt((0,
|
|
11723
|
+
const pid = Number.parseInt((0, import_node_fs32.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
|
|
11431
11724
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
11432
11725
|
return pid;
|
|
11433
11726
|
} catch {
|
|
@@ -11453,12 +11746,12 @@ function thisProcessShouldDrainAgentQueues() {
|
|
|
11453
11746
|
if (isThisProcessDesktopHost()) return true;
|
|
11454
11747
|
return !isDesktopHostAlive();
|
|
11455
11748
|
}
|
|
11456
|
-
var
|
|
11749
|
+
var import_node_fs32, import_node_path31;
|
|
11457
11750
|
var init_desktop_host = __esm({
|
|
11458
11751
|
"src/store/desktop-host.ts"() {
|
|
11459
11752
|
"use strict";
|
|
11460
|
-
|
|
11461
|
-
|
|
11753
|
+
import_node_fs32 = require("fs");
|
|
11754
|
+
import_node_path31 = require("path");
|
|
11462
11755
|
init_paths();
|
|
11463
11756
|
}
|
|
11464
11757
|
});
|
|
@@ -11508,7 +11801,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
11508
11801
|
});
|
|
11509
11802
|
await requireAgent(resolved.agent);
|
|
11510
11803
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
11511
|
-
if (!(0,
|
|
11804
|
+
if (!(0, import_node_fs33.existsSync)(repoPath)) {
|
|
11512
11805
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
11513
11806
|
}
|
|
11514
11807
|
if (input.cowboy) {
|
|
@@ -11631,11 +11924,11 @@ async function listLinearIssues(agent, repoPath) {
|
|
|
11631
11924
|
}
|
|
11632
11925
|
return adapter.listLinearIssues(repoPath);
|
|
11633
11926
|
}
|
|
11634
|
-
var
|
|
11927
|
+
var import_node_fs33;
|
|
11635
11928
|
var init_create = __esm({
|
|
11636
11929
|
"src/threads/create.ts"() {
|
|
11637
11930
|
"use strict";
|
|
11638
|
-
|
|
11931
|
+
import_node_fs33 = require("fs");
|
|
11639
11932
|
init_detect();
|
|
11640
11933
|
init_worktree();
|
|
11641
11934
|
init_conductor();
|
|
@@ -11680,21 +11973,13 @@ function summarizeTurnLive(parts) {
|
|
|
11680
11973
|
(p) => p.type === "tool"
|
|
11681
11974
|
);
|
|
11682
11975
|
const lastTool = tools[tools.length - 1];
|
|
11683
|
-
const
|
|
11684
|
-
const
|
|
11976
|
+
const interesting = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? lastTool;
|
|
11977
|
+
const lastToolLabel = interesting ? interesting.description || toolDescription(interesting.name, interesting.input) || interesting.name : void 0;
|
|
11685
11978
|
const thinking = lastText(parts, "thinking");
|
|
11686
11979
|
const text4 = lastText(parts, "text");
|
|
11687
11980
|
const excerptRaw = thinking || text4;
|
|
11688
11981
|
const excerpt = excerptRaw.length > 280 ? `${excerptRaw.slice(-280)}` : excerptRaw || void 0;
|
|
11689
|
-
|
|
11690
|
-
if (lastToolLabel) {
|
|
11691
|
-
const verb = running ? lastToolLabel : `Finished ${lastToolLabel}`;
|
|
11692
|
-
summary = tools.length > 1 ? `${verb} (${tools.length} tools)` : verb;
|
|
11693
|
-
} else if (thinking) {
|
|
11694
|
-
summary = "Thinking\u2026";
|
|
11695
|
-
} else if (text4) {
|
|
11696
|
-
summary = "Writing reply\u2026";
|
|
11697
|
-
}
|
|
11982
|
+
const summary = liveActivitySummary(parts);
|
|
11698
11983
|
return {
|
|
11699
11984
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11700
11985
|
summary,
|
|
@@ -11744,20 +12029,20 @@ function writeTurnLive(threadId, progress) {
|
|
|
11744
12029
|
const path = threadLivePath(threadId);
|
|
11745
12030
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
11746
12031
|
try {
|
|
11747
|
-
(0,
|
|
11748
|
-
(0,
|
|
12032
|
+
(0, import_node_fs34.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
|
|
12033
|
+
(0, import_node_fs34.renameSync)(tmp, path);
|
|
11749
12034
|
} catch {
|
|
11750
12035
|
try {
|
|
11751
|
-
(0,
|
|
12036
|
+
(0, import_node_fs34.unlinkSync)(tmp);
|
|
11752
12037
|
} catch {
|
|
11753
12038
|
}
|
|
11754
12039
|
}
|
|
11755
12040
|
}
|
|
11756
12041
|
function readTurnLive(threadId) {
|
|
11757
12042
|
const path = threadLivePath(threadId);
|
|
11758
|
-
if (!(0,
|
|
12043
|
+
if (!(0, import_node_fs34.existsSync)(path)) return null;
|
|
11759
12044
|
try {
|
|
11760
|
-
const raw = JSON.parse((0,
|
|
12045
|
+
const raw = JSON.parse((0, import_node_fs34.readFileSync)(path, "utf8"));
|
|
11761
12046
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
11762
12047
|
return raw;
|
|
11763
12048
|
} catch {
|
|
@@ -11769,17 +12054,17 @@ function clearTurnLive(threadId) {
|
|
|
11769
12054
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
11770
12055
|
buffers.delete(threadId);
|
|
11771
12056
|
const path = threadLivePath(threadId);
|
|
11772
|
-
if (!(0,
|
|
12057
|
+
if (!(0, import_node_fs34.existsSync)(path)) return;
|
|
11773
12058
|
try {
|
|
11774
|
-
(0,
|
|
12059
|
+
(0, import_node_fs34.unlinkSync)(path);
|
|
11775
12060
|
} catch {
|
|
11776
12061
|
}
|
|
11777
12062
|
}
|
|
11778
|
-
var
|
|
12063
|
+
var import_node_fs34, buffers, FLUSH_MS, MAX_PARTS;
|
|
11779
12064
|
var init_turn_live = __esm({
|
|
11780
12065
|
"src/store/turn-live.ts"() {
|
|
11781
12066
|
"use strict";
|
|
11782
|
-
|
|
12067
|
+
import_node_fs34 = require("fs");
|
|
11783
12068
|
init_message_parts();
|
|
11784
12069
|
init_paths();
|
|
11785
12070
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -11956,8 +12241,12 @@ var init_quota_failover = __esm({
|
|
|
11956
12241
|
});
|
|
11957
12242
|
|
|
11958
12243
|
// src/threads/adopt.ts
|
|
12244
|
+
function thisModuleFile() {
|
|
12245
|
+
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
12246
|
+
return cjsFile || process.argv[1] || (0, import_node_path32.join)(process.cwd(), "package.json");
|
|
12247
|
+
}
|
|
11959
12248
|
function openReadonlySqlite(file) {
|
|
11960
|
-
const req = (0, import_node_module4.createRequire)(
|
|
12249
|
+
const req = (0, import_node_module4.createRequire)(thisModuleFile());
|
|
11961
12250
|
const Database = req("better-sqlite3");
|
|
11962
12251
|
return new Database(file, { readonly: true, fileMustExist: true });
|
|
11963
12252
|
}
|
|
@@ -11972,21 +12261,21 @@ function mapAgentType(raw) {
|
|
|
11972
12261
|
return null;
|
|
11973
12262
|
}
|
|
11974
12263
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
11975
|
-
if (!workspacePath || !(0,
|
|
12264
|
+
if (!workspacePath || !(0, import_node_fs35.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
11976
12265
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
11977
12266
|
let best = null;
|
|
11978
12267
|
let hashes;
|
|
11979
12268
|
try {
|
|
11980
|
-
hashes = (0,
|
|
12269
|
+
hashes = (0, import_node_fs35.readdirSync)(CURSOR_SDK_STORE);
|
|
11981
12270
|
} catch {
|
|
11982
12271
|
return null;
|
|
11983
12272
|
}
|
|
11984
12273
|
for (const hash of hashes) {
|
|
11985
|
-
const agentsFile = (0,
|
|
11986
|
-
if (!(0,
|
|
12274
|
+
const agentsFile = (0, import_node_path32.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
12275
|
+
if (!(0, import_node_fs35.existsSync)(agentsFile)) continue;
|
|
11987
12276
|
let text4;
|
|
11988
12277
|
try {
|
|
11989
|
-
text4 = (0,
|
|
12278
|
+
text4 = (0, import_node_fs35.readFileSync)(agentsFile, "utf8");
|
|
11990
12279
|
} catch {
|
|
11991
12280
|
continue;
|
|
11992
12281
|
}
|
|
@@ -12010,7 +12299,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
12010
12299
|
return best?.agentId ?? null;
|
|
12011
12300
|
}
|
|
12012
12301
|
async function adoptThread(input) {
|
|
12013
|
-
if (!(0,
|
|
12302
|
+
if (!(0, import_node_fs35.existsSync)(input.worktreePath)) {
|
|
12014
12303
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
12015
12304
|
}
|
|
12016
12305
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -12034,18 +12323,18 @@ async function adoptThread(input) {
|
|
|
12034
12323
|
return thread;
|
|
12035
12324
|
}
|
|
12036
12325
|
function listConductorWorkspaces() {
|
|
12037
|
-
if (!(0,
|
|
12326
|
+
if (!(0, import_node_fs35.existsSync)(CONDUCTOR_DB)) {
|
|
12038
12327
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
12039
12328
|
}
|
|
12040
|
-
const tmp = (0,
|
|
12041
|
-
const snapshot = (0,
|
|
12329
|
+
const tmp = (0, import_node_fs35.mkdtempSync)((0, import_node_path32.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
|
|
12330
|
+
const snapshot = (0, import_node_path32.join)(tmp, "conductor.db");
|
|
12042
12331
|
try {
|
|
12043
|
-
(0,
|
|
12332
|
+
(0, import_node_fs35.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
12044
12333
|
for (const suffix of ["-wal", "-shm"]) {
|
|
12045
12334
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
12046
|
-
if ((0,
|
|
12335
|
+
if ((0, import_node_fs35.existsSync)(src)) {
|
|
12047
12336
|
try {
|
|
12048
|
-
(0,
|
|
12337
|
+
(0, import_node_fs35.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
12049
12338
|
} catch {
|
|
12050
12339
|
}
|
|
12051
12340
|
}
|
|
@@ -12121,22 +12410,22 @@ function listConductorWorkspaces() {
|
|
|
12121
12410
|
db.close();
|
|
12122
12411
|
}
|
|
12123
12412
|
} finally {
|
|
12124
|
-
(0,
|
|
12413
|
+
(0, import_node_fs35.rmSync)(tmp, { recursive: true, force: true });
|
|
12125
12414
|
}
|
|
12126
12415
|
}
|
|
12127
12416
|
function importConductorWorkspace(workspaceId) {
|
|
12128
|
-
if (!(0,
|
|
12417
|
+
if (!(0, import_node_fs35.existsSync)(CONDUCTOR_DB)) {
|
|
12129
12418
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
12130
12419
|
}
|
|
12131
|
-
const tmp = (0,
|
|
12132
|
-
const snapshot = (0,
|
|
12420
|
+
const tmp = (0, import_node_fs35.mkdtempSync)((0, import_node_path32.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
|
|
12421
|
+
const snapshot = (0, import_node_path32.join)(tmp, "conductor.db");
|
|
12133
12422
|
try {
|
|
12134
|
-
(0,
|
|
12423
|
+
(0, import_node_fs35.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
12135
12424
|
for (const suffix of ["-wal", "-shm"]) {
|
|
12136
12425
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
12137
|
-
if ((0,
|
|
12426
|
+
if ((0, import_node_fs35.existsSync)(src)) {
|
|
12138
12427
|
try {
|
|
12139
|
-
(0,
|
|
12428
|
+
(0, import_node_fs35.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
12140
12429
|
} catch {
|
|
12141
12430
|
}
|
|
12142
12431
|
}
|
|
@@ -12154,7 +12443,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
12154
12443
|
).get(workspaceId);
|
|
12155
12444
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
12156
12445
|
const worktreePath = String(row.workspacePath);
|
|
12157
|
-
if (!(0,
|
|
12446
|
+
if (!(0, import_node_fs35.existsSync)(worktreePath)) {
|
|
12158
12447
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
12159
12448
|
}
|
|
12160
12449
|
let sessionId = null;
|
|
@@ -12217,32 +12506,31 @@ function importConductorWorkspace(workspaceId) {
|
|
|
12217
12506
|
db.close();
|
|
12218
12507
|
}
|
|
12219
12508
|
} finally {
|
|
12220
|
-
(0,
|
|
12509
|
+
(0, import_node_fs35.rmSync)(tmp, { recursive: true, force: true });
|
|
12221
12510
|
}
|
|
12222
12511
|
}
|
|
12223
12512
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
12224
12513
|
return importConductorWorkspace(workspaceId);
|
|
12225
12514
|
}
|
|
12226
|
-
var import_node_child_process3,
|
|
12515
|
+
var import_node_child_process3, import_node_fs35, import_node_os10, import_node_path32, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
|
|
12227
12516
|
var init_adopt = __esm({
|
|
12228
12517
|
"src/threads/adopt.ts"() {
|
|
12229
12518
|
"use strict";
|
|
12230
12519
|
import_node_child_process3 = require("child_process");
|
|
12231
|
-
|
|
12520
|
+
import_node_fs35 = require("fs");
|
|
12232
12521
|
import_node_os10 = require("os");
|
|
12233
|
-
|
|
12522
|
+
import_node_path32 = require("path");
|
|
12234
12523
|
import_node_module4 = require("module");
|
|
12235
12524
|
init_worktree();
|
|
12236
12525
|
init_thread_store();
|
|
12237
|
-
|
|
12238
|
-
CONDUCTOR_APP_SUPPORT = (0, import_node_path31.join)(
|
|
12526
|
+
CONDUCTOR_APP_SUPPORT = (0, import_node_path32.join)(
|
|
12239
12527
|
process.env.HOME ?? "",
|
|
12240
12528
|
"Library",
|
|
12241
12529
|
"Application Support",
|
|
12242
12530
|
"com.conductor.app"
|
|
12243
12531
|
);
|
|
12244
|
-
CONDUCTOR_DB = (0,
|
|
12245
|
-
CURSOR_SDK_STORE = (0,
|
|
12532
|
+
CONDUCTOR_DB = (0, import_node_path32.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
12533
|
+
CURSOR_SDK_STORE = (0, import_node_path32.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
12246
12534
|
}
|
|
12247
12535
|
});
|
|
12248
12536
|
|
|
@@ -12309,7 +12597,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
12309
12597
|
let createdWorktree = false;
|
|
12310
12598
|
const trees = await listWorktrees(repoPath);
|
|
12311
12599
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
12312
|
-
if (checkedOut?.path && (0,
|
|
12600
|
+
if (checkedOut?.path && (0, import_node_fs36.existsSync)(checkedOut.path)) {
|
|
12313
12601
|
if (input.reuseExistingWorktree !== false) {
|
|
12314
12602
|
worktreePath = checkedOut.path;
|
|
12315
12603
|
} else {
|
|
@@ -12451,7 +12739,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
12451
12739
|
async function createPrStack(input, onSetupLine) {
|
|
12452
12740
|
await requireAgent(input.agent);
|
|
12453
12741
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
12454
|
-
if (!(0,
|
|
12742
|
+
if (!(0, import_node_fs36.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
12455
12743
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
12456
12744
|
const status = await detectGhStack(repoPath);
|
|
12457
12745
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -12518,7 +12806,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
12518
12806
|
}
|
|
12519
12807
|
}
|
|
12520
12808
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
12521
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
12809
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs36.existsSync)(bootstrap.worktreePath)) {
|
|
12522
12810
|
try {
|
|
12523
12811
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
12524
12812
|
deleteBranch: bootstrap.branchName
|
|
@@ -12528,11 +12816,11 @@ async function createPrStack(input, onSetupLine) {
|
|
|
12528
12816
|
}
|
|
12529
12817
|
return { stack, threads, createdThreadIds };
|
|
12530
12818
|
}
|
|
12531
|
-
var
|
|
12819
|
+
var import_node_fs36;
|
|
12532
12820
|
var init_stack_layers = __esm({
|
|
12533
12821
|
"src/threads/stack-layers.ts"() {
|
|
12534
12822
|
"use strict";
|
|
12535
|
-
|
|
12823
|
+
import_node_fs36 = require("fs");
|
|
12536
12824
|
init_detect();
|
|
12537
12825
|
init_run();
|
|
12538
12826
|
init_stack();
|
|
@@ -12545,7 +12833,7 @@ var init_stack_layers = __esm({
|
|
|
12545
12833
|
|
|
12546
12834
|
// src/diff/diff.ts
|
|
12547
12835
|
async function inspectGitWorktree(worktreePath) {
|
|
12548
|
-
if (!worktreePath || !(0,
|
|
12836
|
+
if (!worktreePath || !(0, import_node_fs37.existsSync)(worktreePath)) return "missing_worktree";
|
|
12549
12837
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
12550
12838
|
reject: false
|
|
12551
12839
|
});
|
|
@@ -12553,7 +12841,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
12553
12841
|
return "ok";
|
|
12554
12842
|
}
|
|
12555
12843
|
async function initializeGitRepository(worktreePath) {
|
|
12556
|
-
if (!worktreePath || !(0,
|
|
12844
|
+
if (!worktreePath || !(0, import_node_fs37.existsSync)(worktreePath)) {
|
|
12557
12845
|
throw new Error("Worktree not found");
|
|
12558
12846
|
}
|
|
12559
12847
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -12687,11 +12975,11 @@ new file mode 100644
|
|
|
12687
12975
|
};
|
|
12688
12976
|
}
|
|
12689
12977
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
12690
|
-
const abs = (0,
|
|
12978
|
+
const abs = (0, import_node_path33.join)(worktreePath, path);
|
|
12691
12979
|
try {
|
|
12692
|
-
const st = (0,
|
|
12980
|
+
const st = (0, import_node_fs37.statSync)(abs);
|
|
12693
12981
|
if (st.isFile() && st.size > maxHunk) {
|
|
12694
|
-
const buf = (0,
|
|
12982
|
+
const buf = (0, import_node_fs37.readFileSync)(abs).subarray(0, maxHunk);
|
|
12695
12983
|
return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
|
|
12696
12984
|
}
|
|
12697
12985
|
} catch {
|
|
@@ -13180,8 +13468,8 @@ function isImageRelativePath(relativePath) {
|
|
|
13180
13468
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
13181
13469
|
assertSafeRelativePath(relativePath);
|
|
13182
13470
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
13183
|
-
const abs = (0,
|
|
13184
|
-
const st = (0,
|
|
13471
|
+
const abs = (0, import_node_path33.join)(worktreePath, relativePath);
|
|
13472
|
+
const st = (0, import_node_fs37.statSync)(abs);
|
|
13185
13473
|
if (!st.isFile()) {
|
|
13186
13474
|
throw new Error(`Not a file: ${relativePath}`);
|
|
13187
13475
|
}
|
|
@@ -13190,7 +13478,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
13190
13478
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
13191
13479
|
);
|
|
13192
13480
|
}
|
|
13193
|
-
const buf = (0,
|
|
13481
|
+
const buf = (0, import_node_fs37.readFileSync)(abs);
|
|
13194
13482
|
return {
|
|
13195
13483
|
path: relativePath,
|
|
13196
13484
|
contentBase64: buf.toString("base64"),
|
|
@@ -13200,12 +13488,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
13200
13488
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
13201
13489
|
assertSafeRelativePath(relativePath);
|
|
13202
13490
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
13203
|
-
const abs = (0,
|
|
13204
|
-
const st = (0,
|
|
13491
|
+
const abs = (0, import_node_path33.join)(worktreePath, relativePath);
|
|
13492
|
+
const st = (0, import_node_fs37.statSync)(abs);
|
|
13205
13493
|
if (!st.isFile()) {
|
|
13206
13494
|
throw new Error(`Not a file: ${relativePath}`);
|
|
13207
13495
|
}
|
|
13208
|
-
const buf = (0,
|
|
13496
|
+
const buf = (0, import_node_fs37.readFileSync)(abs);
|
|
13209
13497
|
if (isImageRelativePath(relativePath)) {
|
|
13210
13498
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
13211
13499
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -13248,9 +13536,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
13248
13536
|
}
|
|
13249
13537
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
13250
13538
|
assertSafeRelativePath(relativePath);
|
|
13251
|
-
const abs = (0,
|
|
13252
|
-
(0,
|
|
13253
|
-
(0,
|
|
13539
|
+
const abs = (0, import_node_path33.join)(worktreePath, relativePath);
|
|
13540
|
+
(0, import_node_fs37.mkdirSync)((0, import_node_path33.dirname)(abs), { recursive: true });
|
|
13541
|
+
(0, import_node_fs37.writeFileSync)(abs, content, "utf8");
|
|
13254
13542
|
return { path: relativePath };
|
|
13255
13543
|
}
|
|
13256
13544
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -13267,12 +13555,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
13267
13555
|
truncated: full.files.length > maxFiles
|
|
13268
13556
|
};
|
|
13269
13557
|
}
|
|
13270
|
-
var
|
|
13558
|
+
var import_node_fs37, import_node_path33, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS, DEFAULT_UPLOAD_MAX_BYTES;
|
|
13271
13559
|
var init_diff = __esm({
|
|
13272
13560
|
"src/diff/diff.ts"() {
|
|
13273
13561
|
"use strict";
|
|
13274
|
-
|
|
13275
|
-
|
|
13562
|
+
import_node_fs37 = require("fs");
|
|
13563
|
+
import_node_path33 = require("path");
|
|
13276
13564
|
init_run();
|
|
13277
13565
|
init_worktree();
|
|
13278
13566
|
mergeBaseCache = /* @__PURE__ */ new Map();
|
|
@@ -13440,7 +13728,7 @@ function parseFrontmatter(content) {
|
|
|
13440
13728
|
}
|
|
13441
13729
|
function readSkill(skillMd, source) {
|
|
13442
13730
|
try {
|
|
13443
|
-
const content = (0,
|
|
13731
|
+
const content = (0, import_node_fs38.readFileSync)(skillMd, "utf8");
|
|
13444
13732
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
13445
13733
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
13446
13734
|
const name = fmName || dirName;
|
|
@@ -13459,19 +13747,19 @@ function readSkill(skillMd, source) {
|
|
|
13459
13747
|
}
|
|
13460
13748
|
}
|
|
13461
13749
|
function scanSkillsDir(dir, source, out) {
|
|
13462
|
-
if (!(0,
|
|
13750
|
+
if (!(0, import_node_fs38.existsSync)(dir)) return;
|
|
13463
13751
|
let entries;
|
|
13464
13752
|
try {
|
|
13465
|
-
entries = (0,
|
|
13753
|
+
entries = (0, import_node_fs38.readdirSync)(dir);
|
|
13466
13754
|
} catch {
|
|
13467
13755
|
return;
|
|
13468
13756
|
}
|
|
13469
13757
|
for (const entry of entries) {
|
|
13470
13758
|
if (entry.startsWith(".")) continue;
|
|
13471
|
-
const skillMd = (0,
|
|
13472
|
-
if (!(0,
|
|
13759
|
+
const skillMd = (0, import_node_path34.join)(dir, entry, "SKILL.md");
|
|
13760
|
+
if (!(0, import_node_fs38.existsSync)(skillMd)) continue;
|
|
13473
13761
|
try {
|
|
13474
|
-
if (!(0,
|
|
13762
|
+
if (!(0, import_node_fs38.statSync)(skillMd).isFile()) continue;
|
|
13475
13763
|
} catch {
|
|
13476
13764
|
continue;
|
|
13477
13765
|
}
|
|
@@ -13480,24 +13768,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
13480
13768
|
}
|
|
13481
13769
|
}
|
|
13482
13770
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
13483
|
-
if (!(0,
|
|
13771
|
+
if (!(0, import_node_fs38.existsSync)(pluginsRoot)) return;
|
|
13484
13772
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
13485
13773
|
if (depth > 7) return;
|
|
13486
13774
|
let entries;
|
|
13487
13775
|
try {
|
|
13488
|
-
entries = (0,
|
|
13776
|
+
entries = (0, import_node_fs38.readdirSync)(dir);
|
|
13489
13777
|
} catch {
|
|
13490
13778
|
return;
|
|
13491
13779
|
}
|
|
13492
13780
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
13493
|
-
const skill = readSkill((0,
|
|
13781
|
+
const skill = readSkill((0, import_node_path34.join)(dir, "SKILL.md"), "cli");
|
|
13494
13782
|
if (skill) out.push(skill);
|
|
13495
13783
|
}
|
|
13496
13784
|
for (const entry of entries) {
|
|
13497
13785
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
13498
|
-
const full = (0,
|
|
13786
|
+
const full = (0, import_node_path34.join)(dir, entry);
|
|
13499
13787
|
try {
|
|
13500
|
-
if (!(0,
|
|
13788
|
+
if (!(0, import_node_fs38.statSync)(full).isDirectory()) continue;
|
|
13501
13789
|
} catch {
|
|
13502
13790
|
continue;
|
|
13503
13791
|
}
|
|
@@ -13515,17 +13803,17 @@ function discoverSkills(worktreePath) {
|
|
|
13515
13803
|
const home = (0, import_node_os11.homedir)();
|
|
13516
13804
|
const collected = [];
|
|
13517
13805
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
13518
|
-
scanSkillsDir((0,
|
|
13806
|
+
scanSkillsDir((0, import_node_path34.join)(worktreePath, rel), "workspace", collected);
|
|
13519
13807
|
}
|
|
13520
13808
|
for (const abs of [
|
|
13521
|
-
(0,
|
|
13522
|
-
(0,
|
|
13523
|
-
(0,
|
|
13524
|
-
(0,
|
|
13809
|
+
(0, import_node_path34.join)(home, ".claude/skills"),
|
|
13810
|
+
(0, import_node_path34.join)(home, ".cursor/skills"),
|
|
13811
|
+
(0, import_node_path34.join)(home, ".sideboard/skills"),
|
|
13812
|
+
(0, import_node_path34.join)(home, ".brightsy/skills")
|
|
13525
13813
|
]) {
|
|
13526
13814
|
scanSkillsDir(abs, "user", collected);
|
|
13527
13815
|
}
|
|
13528
|
-
scanClaudePluginSkills((0,
|
|
13816
|
+
scanClaudePluginSkills((0, import_node_path34.join)(home, ".claude/plugins"), collected);
|
|
13529
13817
|
const rank = { workspace: 0, user: 1, cli: 2 };
|
|
13530
13818
|
const byCommand = /* @__PURE__ */ new Map();
|
|
13531
13819
|
for (const skill of collected) {
|
|
@@ -13537,7 +13825,7 @@ function discoverSkills(worktreePath) {
|
|
|
13537
13825
|
return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
|
|
13538
13826
|
}
|
|
13539
13827
|
function readSkillBody(skillPath, maxChars = 12e3) {
|
|
13540
|
-
const raw = (0,
|
|
13828
|
+
const raw = (0, import_node_fs38.readFileSync)(skillPath, "utf8");
|
|
13541
13829
|
if (raw.startsWith("---")) {
|
|
13542
13830
|
const end = raw.indexOf("\n---", 3);
|
|
13543
13831
|
if (end >= 0) {
|
|
@@ -13551,13 +13839,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
13551
13839
|
|
|
13552
13840
|
\u2026(truncated)` : raw;
|
|
13553
13841
|
}
|
|
13554
|
-
var
|
|
13842
|
+
var import_node_fs38, import_node_os11, import_node_path34;
|
|
13555
13843
|
var init_discover = __esm({
|
|
13556
13844
|
"src/skills/discover.ts"() {
|
|
13557
13845
|
"use strict";
|
|
13558
|
-
|
|
13846
|
+
import_node_fs38 = require("fs");
|
|
13559
13847
|
import_node_os11 = require("os");
|
|
13560
|
-
|
|
13848
|
+
import_node_path34 = require("path");
|
|
13561
13849
|
}
|
|
13562
13850
|
});
|
|
13563
13851
|
|
|
@@ -13648,7 +13936,7 @@ var init_expand = __esm({
|
|
|
13648
13936
|
|
|
13649
13937
|
// src/composer/stage-files.ts
|
|
13650
13938
|
function fileExtension(filePath) {
|
|
13651
|
-
const base = (0,
|
|
13939
|
+
const base = (0, import_node_path35.basename)(filePath).toLowerCase();
|
|
13652
13940
|
return base.includes(".") ? base.split(".").pop() || "" : "";
|
|
13653
13941
|
}
|
|
13654
13942
|
function isImageFilePath(filePath) {
|
|
@@ -13658,22 +13946,22 @@ function imageMimeType(filePath) {
|
|
|
13658
13946
|
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
13659
13947
|
}
|
|
13660
13948
|
function ensureAttachmentsDir(worktreePath) {
|
|
13661
|
-
const dir = (0,
|
|
13662
|
-
(0,
|
|
13663
|
-
const gi = (0,
|
|
13664
|
-
if (!(0,
|
|
13665
|
-
(0,
|
|
13949
|
+
const dir = (0, import_node_path35.join)(worktreePath, ATTACHMENTS_DIR);
|
|
13950
|
+
(0, import_node_fs39.mkdirSync)(dir, { recursive: true });
|
|
13951
|
+
const gi = (0, import_node_path35.join)(dir, ".gitignore");
|
|
13952
|
+
if (!(0, import_node_fs39.existsSync)(gi)) {
|
|
13953
|
+
(0, import_node_fs39.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
|
|
13666
13954
|
}
|
|
13667
13955
|
return dir;
|
|
13668
13956
|
}
|
|
13669
13957
|
function uniqueAttachmentName(dir, originalName) {
|
|
13670
13958
|
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
13671
|
-
if (!(0,
|
|
13672
|
-
const ext = (0,
|
|
13959
|
+
if (!(0, import_node_fs39.existsSync)((0, import_node_path35.join)(dir, safe))) return safe;
|
|
13960
|
+
const ext = (0, import_node_path35.extname)(safe);
|
|
13673
13961
|
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
13674
13962
|
for (let i = 1; i < 1e4; i++) {
|
|
13675
13963
|
const candidate = `${stem}-${i}${ext}`;
|
|
13676
|
-
if (!(0,
|
|
13964
|
+
if (!(0, import_node_fs39.existsSync)((0, import_node_path35.join)(dir, candidate))) return candidate;
|
|
13677
13965
|
}
|
|
13678
13966
|
return `${stem}-${(0, import_node_crypto7.randomUUID)()}${ext}`;
|
|
13679
13967
|
}
|
|
@@ -13729,15 +14017,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
|
13729
14017
|
const dir = ensureAttachmentsDir(worktreePath);
|
|
13730
14018
|
const out = [];
|
|
13731
14019
|
for (const abs of absolutePaths) {
|
|
13732
|
-
const originalName = (0,
|
|
14020
|
+
const originalName = (0, import_node_path35.basename)(abs);
|
|
13733
14021
|
try {
|
|
13734
|
-
const st = (0,
|
|
14022
|
+
const st = (0, import_node_fs39.statSync)(abs);
|
|
13735
14023
|
if (!st.isFile()) continue;
|
|
13736
14024
|
const name = uniqueAttachmentName(dir, originalName);
|
|
13737
|
-
const destAbs = (0,
|
|
13738
|
-
(0,
|
|
14025
|
+
const destAbs = (0, import_node_path35.join)(dir, name);
|
|
14026
|
+
(0, import_node_fs39.copyFileSync)(abs, destAbs);
|
|
13739
14027
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
13740
|
-
const buf = (0,
|
|
14028
|
+
const buf = (0, import_node_fs39.readFileSync)(destAbs);
|
|
13741
14029
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
13742
14030
|
} catch (err) {
|
|
13743
14031
|
out.push({
|
|
@@ -13759,8 +14047,8 @@ function stageBuffersAsAttachments(worktreePath, buffers2) {
|
|
|
13759
14047
|
try {
|
|
13760
14048
|
const buf = Buffer.from(item.dataBase64, "base64");
|
|
13761
14049
|
const name = uniqueAttachmentName(dir, originalName);
|
|
13762
|
-
const destAbs = (0,
|
|
13763
|
-
(0,
|
|
14050
|
+
const destAbs = (0, import_node_path35.join)(dir, name);
|
|
14051
|
+
(0, import_node_fs39.writeFileSync)(destAbs, buf);
|
|
13764
14052
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
13765
14053
|
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
13766
14054
|
} catch (err) {
|
|
@@ -13780,18 +14068,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
13780
14068
|
if (!rel || rel.includes("..") || rel.startsWith("/")) {
|
|
13781
14069
|
out.push({
|
|
13782
14070
|
id: (0, import_node_crypto7.randomUUID)(),
|
|
13783
|
-
name: (0,
|
|
14071
|
+
name: (0, import_node_path35.basename)(rel) || "file",
|
|
13784
14072
|
kind: "file",
|
|
13785
14073
|
content: `(invalid path: ${rel})`
|
|
13786
14074
|
});
|
|
13787
14075
|
continue;
|
|
13788
14076
|
}
|
|
13789
|
-
const name = (0,
|
|
14077
|
+
const name = (0, import_node_path35.basename)(rel);
|
|
13790
14078
|
try {
|
|
13791
|
-
const abs = (0,
|
|
13792
|
-
const st = (0,
|
|
14079
|
+
const abs = (0, import_node_path35.join)(worktreePath, rel);
|
|
14080
|
+
const st = (0, import_node_fs39.statSync)(abs);
|
|
13793
14081
|
if (!st.isFile()) continue;
|
|
13794
|
-
const buf = (0,
|
|
14082
|
+
const buf = (0, import_node_fs39.readFileSync)(abs);
|
|
13795
14083
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
13796
14084
|
} catch (err) {
|
|
13797
14085
|
out.push({
|
|
@@ -13804,12 +14092,12 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
13804
14092
|
}
|
|
13805
14093
|
return out;
|
|
13806
14094
|
}
|
|
13807
|
-
var
|
|
14095
|
+
var import_node_fs39, import_node_path35, import_node_crypto7, IMAGE_EXTENSIONS2, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES;
|
|
13808
14096
|
var init_stage_files = __esm({
|
|
13809
14097
|
"src/composer/stage-files.ts"() {
|
|
13810
14098
|
"use strict";
|
|
13811
|
-
|
|
13812
|
-
|
|
14099
|
+
import_node_fs39 = require("fs");
|
|
14100
|
+
import_node_path35 = require("path");
|
|
13813
14101
|
import_node_crypto7 = require("crypto");
|
|
13814
14102
|
init_workspace_scratch();
|
|
13815
14103
|
IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
@@ -13978,12 +14266,12 @@ function formatArtifactDirective() {
|
|
|
13978
14266
|
function formatUiReminder() {
|
|
13979
14267
|
return "Sideboard UI: html fence or present_artifact / present_schema / present_files; ask_user only for a real multiple-choice (not hellos or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
|
|
13980
14268
|
}
|
|
13981
|
-
var
|
|
14269
|
+
var import_node_fs40, import_node_path36;
|
|
13982
14270
|
var init_instructions = __esm({
|
|
13983
14271
|
"src/agents/instructions.ts"() {
|
|
13984
14272
|
"use strict";
|
|
13985
|
-
|
|
13986
|
-
|
|
14273
|
+
import_node_fs40 = require("fs");
|
|
14274
|
+
import_node_path36 = require("path");
|
|
13987
14275
|
init_git_auth_mode();
|
|
13988
14276
|
init_worktree_labels();
|
|
13989
14277
|
}
|
|
@@ -14059,40 +14347,40 @@ __export(plan_file_exports, {
|
|
|
14059
14347
|
writePlanFile: () => writePlanFile
|
|
14060
14348
|
});
|
|
14061
14349
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
14062
|
-
const gitignoreAbs = (0,
|
|
14063
|
-
if ((0,
|
|
14064
|
-
(0,
|
|
14065
|
-
(0,
|
|
14350
|
+
const gitignoreAbs = (0, import_node_path37.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
14351
|
+
if ((0, import_node_fs41.existsSync)(gitignoreAbs)) return;
|
|
14352
|
+
(0, import_node_fs41.mkdirSync)((0, import_node_path37.dirname)(gitignoreAbs), { recursive: true });
|
|
14353
|
+
(0, import_node_fs41.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
14066
14354
|
}
|
|
14067
14355
|
function planFileAbs(worktreePath) {
|
|
14068
|
-
return (0,
|
|
14356
|
+
return (0, import_node_path37.join)(worktreePath, PLAN_FILE_REL);
|
|
14069
14357
|
}
|
|
14070
14358
|
function readTextIfPresent2(abs) {
|
|
14071
|
-
if (!(0,
|
|
14359
|
+
if (!(0, import_node_fs41.existsSync)(abs)) return null;
|
|
14072
14360
|
try {
|
|
14073
|
-
const content = (0,
|
|
14361
|
+
const content = (0, import_node_fs41.readFileSync)(abs, "utf8");
|
|
14074
14362
|
return content.trim() ? content : null;
|
|
14075
14363
|
} catch {
|
|
14076
14364
|
return null;
|
|
14077
14365
|
}
|
|
14078
14366
|
}
|
|
14079
14367
|
function readPlanFile(worktreePath) {
|
|
14080
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
14368
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path37.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path37.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
14081
14369
|
}
|
|
14082
14370
|
function writePlanFile(worktreePath, content) {
|
|
14083
14371
|
ensureAttachmentsGitignore(worktreePath);
|
|
14084
14372
|
const abs = planFileAbs(worktreePath);
|
|
14085
|
-
(0,
|
|
14373
|
+
(0, import_node_fs41.mkdirSync)((0, import_node_path37.dirname)(abs), { recursive: true });
|
|
14086
14374
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
14087
|
-
(0,
|
|
14375
|
+
(0, import_node_fs41.writeFileSync)(abs, body, "utf8");
|
|
14088
14376
|
return PLAN_FILE_REL;
|
|
14089
14377
|
}
|
|
14090
|
-
var
|
|
14378
|
+
var import_node_fs41, import_node_path37;
|
|
14091
14379
|
var init_plan_file = __esm({
|
|
14092
14380
|
"src/plan/plan-file.ts"() {
|
|
14093
14381
|
"use strict";
|
|
14094
|
-
|
|
14095
|
-
|
|
14382
|
+
import_node_fs41 = require("fs");
|
|
14383
|
+
import_node_path37 = require("path");
|
|
14096
14384
|
init_workspace_scratch();
|
|
14097
14385
|
init_plan_present();
|
|
14098
14386
|
init_plan_present();
|
|
@@ -14152,7 +14440,7 @@ function setCaffeinateHoldHooks(next) {
|
|
|
14152
14440
|
hooks = next;
|
|
14153
14441
|
}
|
|
14154
14442
|
function caffeinateHoldPath() {
|
|
14155
|
-
return (0,
|
|
14443
|
+
return (0, import_node_path38.join)(appDataDir(), "caffeinate-hold.json");
|
|
14156
14444
|
}
|
|
14157
14445
|
function processAlive(pid) {
|
|
14158
14446
|
if (hooks.processAlive) return hooks.processAlive(pid);
|
|
@@ -14186,9 +14474,9 @@ function uniqueIds(ids) {
|
|
|
14186
14474
|
}
|
|
14187
14475
|
function readHold() {
|
|
14188
14476
|
const path = caffeinateHoldPath();
|
|
14189
|
-
if (!(0,
|
|
14477
|
+
if (!(0, import_node_fs42.existsSync)(path)) return null;
|
|
14190
14478
|
try {
|
|
14191
|
-
const parsed = JSON.parse((0,
|
|
14479
|
+
const parsed = JSON.parse((0, import_node_fs42.readFileSync)(path, "utf8"));
|
|
14192
14480
|
if (typeof parsed?.pid === "number" && parsed.pid > 0) {
|
|
14193
14481
|
return {
|
|
14194
14482
|
pid: parsed.pid,
|
|
@@ -14210,7 +14498,7 @@ function writeHold(pid, threadIds) {
|
|
|
14210
14498
|
}
|
|
14211
14499
|
function clearHold() {
|
|
14212
14500
|
try {
|
|
14213
|
-
(0,
|
|
14501
|
+
(0, import_node_fs42.unlinkSync)(caffeinateHoldPath());
|
|
14214
14502
|
} catch {
|
|
14215
14503
|
}
|
|
14216
14504
|
}
|
|
@@ -14295,13 +14583,13 @@ function releaseCaffeinateHoldForThread(threadId) {
|
|
|
14295
14583
|
}
|
|
14296
14584
|
return setCaffeinateHold(false, { threadId: id });
|
|
14297
14585
|
}
|
|
14298
|
-
var import_node_child_process4,
|
|
14586
|
+
var import_node_child_process4, import_node_fs42, import_node_path38, hooks;
|
|
14299
14587
|
var init_caffeinate_hold = __esm({
|
|
14300
14588
|
"src/store/caffeinate-hold.ts"() {
|
|
14301
14589
|
"use strict";
|
|
14302
14590
|
import_node_child_process4 = require("child_process");
|
|
14303
|
-
|
|
14304
|
-
|
|
14591
|
+
import_node_fs42 = require("fs");
|
|
14592
|
+
import_node_path38 = require("path");
|
|
14305
14593
|
init_paths();
|
|
14306
14594
|
init_private_file();
|
|
14307
14595
|
hooks = {};
|
|
@@ -14310,7 +14598,7 @@ var init_caffeinate_hold = __esm({
|
|
|
14310
14598
|
|
|
14311
14599
|
// src/store/schedules.ts
|
|
14312
14600
|
function schedulesPath() {
|
|
14313
|
-
return (0,
|
|
14601
|
+
return (0, import_node_path39.join)(appDataDir(), "schedules.json");
|
|
14314
14602
|
}
|
|
14315
14603
|
function parseDurationMs(every) {
|
|
14316
14604
|
const m = every.trim().match(DURATION_RE);
|
|
@@ -14410,9 +14698,9 @@ function normalizeTask(raw) {
|
|
|
14410
14698
|
}
|
|
14411
14699
|
function readAll2() {
|
|
14412
14700
|
const path = schedulesPath();
|
|
14413
|
-
if (!(0,
|
|
14701
|
+
if (!(0, import_node_fs43.existsSync)(path)) return [];
|
|
14414
14702
|
try {
|
|
14415
|
-
const parsed = JSON.parse((0,
|
|
14703
|
+
const parsed = JSON.parse((0, import_node_fs43.readFileSync)(path, "utf8"));
|
|
14416
14704
|
if (!Array.isArray(parsed)) return [];
|
|
14417
14705
|
return parsed.map((row) => {
|
|
14418
14706
|
try {
|
|
@@ -14524,13 +14812,13 @@ function recordScheduleRun(id, result) {
|
|
|
14524
14812
|
writeAll2(rows);
|
|
14525
14813
|
return next;
|
|
14526
14814
|
}
|
|
14527
|
-
var import_node_crypto8,
|
|
14815
|
+
var import_node_crypto8, import_node_fs43, import_node_path39, import_croner, DURATION_RE, UNIT_MS;
|
|
14528
14816
|
var init_schedules = __esm({
|
|
14529
14817
|
"src/store/schedules.ts"() {
|
|
14530
14818
|
"use strict";
|
|
14531
14819
|
import_node_crypto8 = require("crypto");
|
|
14532
|
-
|
|
14533
|
-
|
|
14820
|
+
import_node_fs43 = require("fs");
|
|
14821
|
+
import_node_path39 = require("path");
|
|
14534
14822
|
import_croner = require("croner");
|
|
14535
14823
|
init_orchestrator_capable();
|
|
14536
14824
|
init_paths();
|
|
@@ -14678,10 +14966,10 @@ __export(cursor_recover_exports, {
|
|
|
14678
14966
|
function recoverFinishedCursorRun(opts) {
|
|
14679
14967
|
const agentId = opts.agentId.trim();
|
|
14680
14968
|
if (!agentId) return null;
|
|
14681
|
-
const runsPath = (0,
|
|
14682
|
-
if (!(0,
|
|
14969
|
+
const runsPath = (0, import_node_path40.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
|
|
14970
|
+
if (!(0, import_node_fs44.existsSync)(runsPath)) return null;
|
|
14683
14971
|
try {
|
|
14684
|
-
const lines = (0,
|
|
14972
|
+
const lines = (0, import_node_fs44.readFileSync)(runsPath, "utf8").split("\n");
|
|
14685
14973
|
let best = null;
|
|
14686
14974
|
for (const line of lines) {
|
|
14687
14975
|
const trimmed = line.trim();
|
|
@@ -14707,12 +14995,12 @@ function recoverFinishedCursorRun(opts) {
|
|
|
14707
14995
|
return null;
|
|
14708
14996
|
}
|
|
14709
14997
|
}
|
|
14710
|
-
var
|
|
14998
|
+
var import_node_fs44, import_node_path40;
|
|
14711
14999
|
var init_cursor_recover = __esm({
|
|
14712
15000
|
"src/agents/cursor-recover.ts"() {
|
|
14713
15001
|
"use strict";
|
|
14714
|
-
|
|
14715
|
-
|
|
15002
|
+
import_node_fs44 = require("fs");
|
|
15003
|
+
import_node_path40 = require("path");
|
|
14716
15004
|
init_paths();
|
|
14717
15005
|
}
|
|
14718
15006
|
});
|
|
@@ -14843,14 +15131,16 @@ async function startOrchestration(opts) {
|
|
|
14843
15131
|
}
|
|
14844
15132
|
return updated;
|
|
14845
15133
|
}
|
|
14846
|
-
var import_node_events,
|
|
15134
|
+
var import_node_events, import_node_fs45, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
|
|
14847
15135
|
var init_orchestrator = __esm({
|
|
14848
15136
|
"src/orchestrator/orchestrator.ts"() {
|
|
14849
15137
|
"use strict";
|
|
14850
15138
|
import_node_events = require("events");
|
|
14851
15139
|
init_outbound_watch();
|
|
14852
|
-
|
|
15140
|
+
import_node_fs45 = require("fs");
|
|
14853
15141
|
init_error_detail();
|
|
15142
|
+
init_run();
|
|
15143
|
+
init_stale_lock();
|
|
14854
15144
|
init_spawn();
|
|
14855
15145
|
init_agents();
|
|
14856
15146
|
init_worktree();
|
|
@@ -14966,7 +15256,7 @@ var init_orchestrator = __esm({
|
|
|
14966
15256
|
}
|
|
14967
15257
|
continue;
|
|
14968
15258
|
}
|
|
14969
|
-
if (!(0,
|
|
15259
|
+
if (!(0, import_node_fs45.existsSync)(thread.worktreePath)) {
|
|
14970
15260
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
14971
15261
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
14972
15262
|
continue;
|
|
@@ -15559,7 +15849,15 @@ var init_orchestrator = __esm({
|
|
|
15559
15849
|
hasSession: Boolean(this.requireThread(threadId).sessionId)
|
|
15560
15850
|
})) {
|
|
15561
15851
|
updateThread(threadId, { sessionId: null });
|
|
15562
|
-
|
|
15852
|
+
try {
|
|
15853
|
+
const gitDirs = await resolveGitDirsForLockRecovery(thread.worktreePath);
|
|
15854
|
+
const clearedLocks = clearStaleIndexLocks(gitDirs, 2e3);
|
|
15855
|
+
if (clearedLocks.length > 0) {
|
|
15856
|
+
pushTurnStderr(stderrTail, "Cleared a stale git lock left by the crashed agent process");
|
|
15857
|
+
}
|
|
15858
|
+
} catch {
|
|
15859
|
+
}
|
|
15860
|
+
const retryNote = looksLikeInvalidAgentSession(detail) ? "Agent session missing \u2014 starting a fresh session" : looksLikeV8Oom(detail) ? "Agent ran out of memory \u2014 starting a fresh session" : "Agent runner crashed \u2014 restarting Node once";
|
|
15563
15861
|
pushTurnStderr(stderrTail, retryNote);
|
|
15564
15862
|
this.emit({
|
|
15565
15863
|
type: "turn_output",
|
|
@@ -16031,13 +16329,14 @@ var init_orchestrator = __esm({
|
|
|
16031
16329
|
const text4 = (lastAgent?.text ?? "").trim() || (thread.status === "error" ? lastError ?? "" : "");
|
|
16032
16330
|
const stillRunning = thread.status === "running" || thread.status === "queued";
|
|
16033
16331
|
const live = stillRunning ? readTurnLive(thread.id) : null;
|
|
16332
|
+
const queuedHint = thread.status === "queued" && !live?.summary ? "Queued \u2014 waiting for a concurrency slot" : null;
|
|
16034
16333
|
return {
|
|
16035
16334
|
text: text4,
|
|
16036
16335
|
status: thread.status,
|
|
16037
16336
|
sessionId: thread.sessionId,
|
|
16038
16337
|
lastError,
|
|
16039
16338
|
stillRunning,
|
|
16040
|
-
progress: live?.summary ??
|
|
16339
|
+
progress: live?.summary ?? queuedHint,
|
|
16041
16340
|
lastActivityAt: live?.updatedAt ?? null
|
|
16042
16341
|
};
|
|
16043
16342
|
}
|
|
@@ -16554,7 +16853,7 @@ var init_orchestrator = __esm({
|
|
|
16554
16853
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
16555
16854
|
return restored2;
|
|
16556
16855
|
}
|
|
16557
|
-
if (!(0,
|
|
16856
|
+
if (!(0, import_node_fs45.existsSync)(thread.worktreePath)) {
|
|
16558
16857
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
16559
16858
|
throw new Error(
|
|
16560
16859
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -16634,7 +16933,7 @@ init_nested_electron_env();
|
|
|
16634
16933
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
16635
16934
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
16636
16935
|
var import_zod4 = require("zod");
|
|
16637
|
-
var
|
|
16936
|
+
var import_node_path41 = require("path");
|
|
16638
16937
|
init_orchestrator();
|
|
16639
16938
|
init_worktree();
|
|
16640
16939
|
|
|
@@ -17141,6 +17440,10 @@ function mcpWaitForTurnTimeoutMs(requested) {
|
|
|
17141
17440
|
return Math.min(Math.max(1e3, Math.floor(n)), MCP_WAIT_FOR_TURN_MAX_MS);
|
|
17142
17441
|
}
|
|
17143
17442
|
var MCP_WAIT_STILL_RUNNING_HINT = "Child is still working. Call wait_for_turn again. Do not send a check-in prompt or assume a hang while progress is updating.";
|
|
17443
|
+
var MCP_WAIT_QUEUED_HINT = "Child is queued waiting for a concurrency slot \u2014 it has not started yet. Call wait_for_turn again. Do not send a check-in prompt, force_stop, or assume it failed to start.";
|
|
17444
|
+
function mcpWaitStillRunningHint(status) {
|
|
17445
|
+
return status === "queued" ? MCP_WAIT_QUEUED_HINT : MCP_WAIT_STILL_RUNNING_HINT;
|
|
17446
|
+
}
|
|
17144
17447
|
|
|
17145
17448
|
// src/mcp/server.ts
|
|
17146
17449
|
init_turn_live();
|
|
@@ -17987,7 +18290,7 @@ async function startMcpServer() {
|
|
|
17987
18290
|
async () => {
|
|
17988
18291
|
const threads = orch.getThreads(true);
|
|
17989
18292
|
const lines = threads.map((t) => {
|
|
17990
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
18293
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path41.basename)(t.repoPath) || t.repoPath;
|
|
17991
18294
|
const live = t.status === "running" || t.status === "queued" ? readTurnLive(t.id) : null;
|
|
17992
18295
|
const progress = live?.summary ? ` ${live.summary}` : "";
|
|
17993
18296
|
return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title} sideboard://thread/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}${progress}`;
|
|
@@ -18023,7 +18326,7 @@ async function startMcpServer() {
|
|
|
18023
18326
|
prUrl: t.prUrl,
|
|
18024
18327
|
lastError: t.lastError ?? null,
|
|
18025
18328
|
stillRunning: t.status === "running" || t.status === "queued",
|
|
18026
|
-
progress: live?.summary ?? null,
|
|
18329
|
+
progress: live?.summary ?? (t.status === "queued" ? "Queued \u2014 waiting for a concurrency slot" : null),
|
|
18027
18330
|
lastActivityAt: live?.updatedAt ?? null
|
|
18028
18331
|
};
|
|
18029
18332
|
return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
|
|
@@ -18357,7 +18660,7 @@ async function startMcpServer() {
|
|
|
18357
18660
|
);
|
|
18358
18661
|
server.tool(
|
|
18359
18662
|
"wait_for_turn",
|
|
18360
|
-
"Wait until the thread finishes its current/queued turn, or return early with a live progress snapshot. MCP clients often kill tools around 60s, so this returns within 45s even while the child is still working. If stillRunning is true, progress is tools/thinking \
|
|
18663
|
+
"Wait until the thread finishes its current/queued turn, or return early with a live progress snapshot. MCP clients often kill tools around 60s, so this returns within 45s even while the child is still working. If stillRunning is true, progress is tools/thinking (or \u201Cqueued, waiting for a concurrency slot\u201D if it has not started). Call wait_for_turn again. Do not send a check-in prompt, force_stop, or assume a hang. On status error, lastError/text is the failure.",
|
|
18361
18664
|
{
|
|
18362
18665
|
ref: import_zod4.z.string(),
|
|
18363
18666
|
timeoutMs: import_zod4.z.number().optional()
|
|
@@ -18379,7 +18682,7 @@ async function startMcpServer() {
|
|
|
18379
18682
|
stillRunning: result.stillRunning,
|
|
18380
18683
|
progress: result.progress,
|
|
18381
18684
|
lastActivityAt: result.lastActivityAt,
|
|
18382
|
-
hint: result.stillRunning ?
|
|
18685
|
+
hint: result.stillRunning ? mcpWaitStillRunningHint(result.status) : void 0
|
|
18383
18686
|
})
|
|
18384
18687
|
}
|
|
18385
18688
|
]
|
|
@@ -18398,7 +18701,7 @@ async function startMcpServer() {
|
|
|
18398
18701
|
type: "text",
|
|
18399
18702
|
text: JSON.stringify({
|
|
18400
18703
|
...result,
|
|
18401
|
-
hint: result.stillRunning ?
|
|
18704
|
+
hint: result.stillRunning ? mcpWaitStillRunningHint(result.status) : void 0
|
|
18402
18705
|
})
|
|
18403
18706
|
}
|
|
18404
18707
|
]
|