@sideboard-ai/core 0.1.111 → 0.1.116
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 +51 -21
- package/dist/agents/cursor-runner.js +3 -3
- package/dist/{agents-NN22A4G5.js → agents-7NIX44RB.js} +7 -7
- package/dist/{agents-GH3FWDW2.js → agents-DU7DHY7A.js} +10 -10
- package/dist/{chunk-JTQQPJAU.js → chunk-4HOFVKPC.js} +52 -38
- package/dist/{chunk-4EWPKYOU.js → chunk-4OJMZ6P2.js} +2 -2
- package/dist/{chunk-NC3U42ZP.js → chunk-5KSLD4MU.js} +317 -33
- package/dist/{chunk-KQBI5HNT.js → chunk-7WC5UWEB.js} +2 -2
- package/dist/{chunk-WIHKHR5R.js → chunk-AXQ4ZWHK.js} +5 -0
- package/dist/{chunk-LGXBYZZA.js → chunk-DVM4ID64.js} +69 -13
- package/dist/{chunk-DMJKOFTO.js → chunk-DWP25N32.js} +44 -35
- package/dist/{chunk-2GO3YKBA.js → chunk-EKIDHL2T.js} +4 -4
- package/dist/{chunk-C4KHDW3U.js → chunk-FZCIQYNQ.js} +1 -1
- package/dist/{chunk-363Z34PY.js → chunk-GBY7OOMB.js} +273 -218
- package/dist/{chunk-7KWYXGIU.js → chunk-K3TIQXOH.js} +2 -2
- package/dist/{chunk-3KETJKYA.js → chunk-KPIYENTF.js} +69 -13
- package/dist/{chunk-KVFNTWFG.js → chunk-OFF5AFCR.js} +300 -43
- 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 +855 -440
- package/dist/index.d.cts +59 -1
- package/dist/index.d.ts +59 -1
- package/dist/index.js +37 -17
- package/dist/mcp/run-stdio.cjs +966 -635
- package/dist/mcp/run-stdio.js +20 -16
- package/dist/{orchestrator-4T2SXDZ7.js → orchestrator-NXPANCZA.js} +8 -8
- package/dist/{orchestrator-EP57AB5W.js → orchestrator-ZY4RUJKT.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
|
@@ -1507,6 +1507,7 @@ function looksLikeRetryableRunnerCrash(text4) {
|
|
|
1507
1507
|
}
|
|
1508
1508
|
function shouldRetryFailedAgentTurn(detail, opts) {
|
|
1509
1509
|
if (looksLikeInvalidAgentSession(detail) && opts.hasSession) return true;
|
|
1510
|
+
if (looksLikeV8Oom(detail) && opts.hasSession) return true;
|
|
1510
1511
|
return looksLikeRetryableRunnerCrash(detail);
|
|
1511
1512
|
}
|
|
1512
1513
|
function looksLikeAgentFailureMessage(text4) {
|
|
@@ -1599,11 +1600,258 @@ var init_error_detail = __esm({
|
|
|
1599
1600
|
NESTED_ELECTRON_SUMMARY = "Cursor local agent crashed at Electron startup (nested Chromium / HasCustomHostObject)";
|
|
1600
1601
|
HOMEBREW_LIBUV_SUMMARY = "Cursor runner crashed in Node (Homebrew Node + shared libuv). Install Node 22 LTS (`brew install node@22`) and retry.";
|
|
1601
1602
|
BUNDLED_NODE_CRASH_SUMMARY = "Cursor runner crashed in Node. Retry the turn.";
|
|
1602
|
-
V8_OOM_SUMMARY = "
|
|
1603
|
+
V8_OOM_SUMMARY = "Agent ran out of memory (JavaScript heap). If it keeps happening, exclude large files from the project folder.";
|
|
1603
1604
|
MINIFIED_DUMP_SUMMARY = "Cursor local agent crashed during startup (truncated crash dump)";
|
|
1604
1605
|
}
|
|
1605
1606
|
});
|
|
1606
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
|
+
|
|
1607
1855
|
// src/git/team-meta.ts
|
|
1608
1856
|
var SOCCER_TEAM_META;
|
|
1609
1857
|
var init_team_meta = __esm({
|
|
@@ -2505,7 +2753,7 @@ var init_gh_errors = __esm({
|
|
|
2505
2753
|
|
|
2506
2754
|
// src/store/secret-vault.ts
|
|
2507
2755
|
function secretVaultPath() {
|
|
2508
|
-
return (0,
|
|
2756
|
+
return (0, import_node_path12.join)(appDataDir(), "secrets.json");
|
|
2509
2757
|
}
|
|
2510
2758
|
function loadSecretVault() {
|
|
2511
2759
|
const parsed = readSecureJson(secretVaultPath());
|
|
@@ -2549,11 +2797,11 @@ function normalizeVault(raw) {
|
|
|
2549
2797
|
}
|
|
2550
2798
|
return out;
|
|
2551
2799
|
}
|
|
2552
|
-
var
|
|
2800
|
+
var import_node_path12;
|
|
2553
2801
|
var init_secret_vault = __esm({
|
|
2554
2802
|
"src/store/secret-vault.ts"() {
|
|
2555
2803
|
"use strict";
|
|
2556
|
-
|
|
2804
|
+
import_node_path12 = require("path");
|
|
2557
2805
|
init_paths();
|
|
2558
2806
|
init_secure_file();
|
|
2559
2807
|
}
|
|
@@ -2656,10 +2904,10 @@ function toPublicAppSettings(settings) {
|
|
|
2656
2904
|
};
|
|
2657
2905
|
}
|
|
2658
2906
|
function appSettingsPath() {
|
|
2659
|
-
return (0,
|
|
2907
|
+
return (0, import_node_path13.join)(appDataDir(), "settings.json");
|
|
2660
2908
|
}
|
|
2661
2909
|
function claudeUserSettingsPath() {
|
|
2662
|
-
return (0,
|
|
2910
|
+
return (0, import_node_path13.join)((0, import_node_os4.homedir)(), ".claude", "settings.json");
|
|
2663
2911
|
}
|
|
2664
2912
|
function normalizeClaude(raw) {
|
|
2665
2913
|
if (!raw || typeof raw !== "object") return {};
|
|
@@ -2908,10 +3156,10 @@ function normalizeSettings(raw) {
|
|
|
2908
3156
|
}
|
|
2909
3157
|
function readSettingsFile() {
|
|
2910
3158
|
const path = appSettingsPath();
|
|
2911
|
-
if (!(0,
|
|
3159
|
+
if (!(0, import_node_fs12.existsSync)(path)) return { ...EMPTY_SETTINGS };
|
|
2912
3160
|
try {
|
|
2913
3161
|
chmodOwnerOnly(path);
|
|
2914
|
-
const parsed = JSON.parse((0,
|
|
3162
|
+
const parsed = JSON.parse((0, import_node_fs12.readFileSync)(path, "utf8"));
|
|
2915
3163
|
return normalizeSettings(parsed);
|
|
2916
3164
|
} catch {
|
|
2917
3165
|
return { ...EMPTY_SETTINGS };
|
|
@@ -3296,7 +3544,7 @@ function ensureSlackDeviceIdentity(settings = loadAppSettings()) {
|
|
|
3296
3544
|
}
|
|
3297
3545
|
if (!deviceLabel) {
|
|
3298
3546
|
try {
|
|
3299
|
-
deviceLabel = (0,
|
|
3547
|
+
deviceLabel = (0, import_node_os4.hostname)().split(".")[0]?.trim() || "This Mac";
|
|
3300
3548
|
} catch {
|
|
3301
3549
|
deviceLabel = "This Mac";
|
|
3302
3550
|
}
|
|
@@ -3483,14 +3731,14 @@ function childEnvWithAppSettings(extra) {
|
|
|
3483
3731
|
function harnessEnvKey(harness) {
|
|
3484
3732
|
return HARNESS_ENV_KEYS[harness];
|
|
3485
3733
|
}
|
|
3486
|
-
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;
|
|
3487
3735
|
var init_app_settings = __esm({
|
|
3488
3736
|
"src/store/app-settings.ts"() {
|
|
3489
3737
|
"use strict";
|
|
3490
3738
|
import_node_crypto3 = require("crypto");
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3739
|
+
import_node_fs12 = require("fs");
|
|
3740
|
+
import_node_os4 = require("os");
|
|
3741
|
+
import_node_path13 = require("path");
|
|
3494
3742
|
init_thinking_effort();
|
|
3495
3743
|
init_nested_electron_env();
|
|
3496
3744
|
init_paths();
|
|
@@ -3542,23 +3790,23 @@ var init_app_settings = __esm({
|
|
|
3542
3790
|
function githubAgentAuthDir() {
|
|
3543
3791
|
const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
|
|
3544
3792
|
if (override) return override;
|
|
3545
|
-
return (0,
|
|
3793
|
+
return (0, import_node_path14.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
|
|
3546
3794
|
}
|
|
3547
3795
|
function githubCredentialStorePath() {
|
|
3548
|
-
return (0,
|
|
3796
|
+
return (0, import_node_path14.join)(githubAgentAuthDir(), "git-credentials");
|
|
3549
3797
|
}
|
|
3550
3798
|
function githubGhConfigDir() {
|
|
3551
|
-
return (0,
|
|
3799
|
+
return (0, import_node_path14.join)(githubAgentAuthDir(), "gh");
|
|
3552
3800
|
}
|
|
3553
3801
|
function writePrivateFile2(file, body) {
|
|
3554
|
-
(0,
|
|
3802
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path14.dirname)(file), { recursive: true, mode: 448 });
|
|
3555
3803
|
try {
|
|
3556
|
-
(0,
|
|
3804
|
+
(0, import_node_fs13.chmodSync)((0, import_node_path14.dirname)(file), 448);
|
|
3557
3805
|
} catch {
|
|
3558
3806
|
}
|
|
3559
|
-
(0,
|
|
3807
|
+
(0, import_node_fs13.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
|
|
3560
3808
|
try {
|
|
3561
|
-
(0,
|
|
3809
|
+
(0, import_node_fs13.chmodSync)(file, 384);
|
|
3562
3810
|
} catch {
|
|
3563
3811
|
}
|
|
3564
3812
|
}
|
|
@@ -3583,225 +3831,40 @@ function materializeGithubAgentAuth(token, user) {
|
|
|
3583
3831
|
const trimmed = token.trim();
|
|
3584
3832
|
if (!trimmed) return;
|
|
3585
3833
|
const root = githubAgentAuthDir();
|
|
3586
|
-
(0,
|
|
3834
|
+
(0, import_node_fs13.mkdirSync)(root, { recursive: true, mode: 448 });
|
|
3587
3835
|
try {
|
|
3588
|
-
(0,
|
|
3836
|
+
(0, import_node_fs13.chmodSync)(root, 448);
|
|
3589
3837
|
} catch {
|
|
3590
3838
|
}
|
|
3591
3839
|
writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
|
|
3592
|
-
const ghDir = githubGhConfigDir();
|
|
3593
|
-
(0,
|
|
3594
|
-
writePrivateFile2((0,
|
|
3595
|
-
writePrivateFile2((0,
|
|
3596
|
-
}
|
|
3597
|
-
function githubAgentAuthReady() {
|
|
3598
|
-
return (0, import_node_fs11.existsSync)(githubCredentialStorePath()) && (0, import_node_fs11.existsSync)((0, import_node_path12.join)(githubGhConfigDir(), "hosts.yml"));
|
|
3599
|
-
}
|
|
3600
|
-
function githubCredentialHelperGitConfig() {
|
|
3601
|
-
const file = githubCredentialStorePath();
|
|
3602
|
-
return [
|
|
3603
|
-
{ key: "credential.helper", value: "" },
|
|
3604
|
-
{ key: "credential.helper", value: `store --file=${file}` }
|
|
3605
|
-
];
|
|
3606
|
-
}
|
|
3607
|
-
function githubGhConfigEnv() {
|
|
3608
|
-
return {
|
|
3609
|
-
GH_CONFIG_DIR: githubGhConfigDir(),
|
|
3610
|
-
GH_PROMPT_DISABLED: "1"
|
|
3611
|
-
};
|
|
3612
|
-
}
|
|
3613
|
-
var import_node_fs11, import_node_os4, import_node_path12;
|
|
3614
|
-
var init_github_agent_auth = __esm({
|
|
3615
|
-
"src/git/github-agent-auth.ts"() {
|
|
3616
|
-
"use strict";
|
|
3617
|
-
import_node_fs11 = require("fs");
|
|
3618
|
-
import_node_os4 = require("os");
|
|
3619
|
-
import_node_path12 = require("path");
|
|
3620
|
-
}
|
|
3621
|
-
});
|
|
3622
|
-
|
|
3623
|
-
// src/agents/path.ts
|
|
3624
|
-
function prependPathDir(env, dir) {
|
|
3625
|
-
if (!dir || !(0, import_node_fs12.existsSync)(dir)) return;
|
|
3626
|
-
const current = env.PATH ?? "";
|
|
3627
|
-
const parts = current.split(import_node_path13.delimiter).filter(Boolean);
|
|
3628
|
-
if (parts.includes(dir)) {
|
|
3629
|
-
env.PATH = current;
|
|
3630
|
-
return;
|
|
3631
|
-
}
|
|
3632
|
-
env.PATH = [dir, ...parts].join(import_node_path13.delimiter);
|
|
3633
|
-
}
|
|
3634
|
-
function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os5.homedir)()) {
|
|
3635
|
-
return (0, import_node_path13.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
|
|
3636
|
-
}
|
|
3637
|
-
function isConductorBundledCli(filePath) {
|
|
3638
|
-
const p = (filePath ?? "").replace(/\\/g, "/");
|
|
3639
|
-
return p.includes("/com.conductor.app/bin/") || p.endsWith("/com.conductor.app/bin");
|
|
3640
|
-
}
|
|
3641
|
-
function ensureAgentPath(env = process.env) {
|
|
3642
|
-
const home = env.HOME || env.USERPROFILE || (0, import_node_os5.homedir)();
|
|
3643
|
-
const current = env.PATH ?? "";
|
|
3644
|
-
const parts = current.split(import_node_path13.delimiter).filter(Boolean);
|
|
3645
|
-
const seen = new Set(parts);
|
|
3646
|
-
const extras = [
|
|
3647
|
-
...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path13.join)(home, rel)),
|
|
3648
|
-
"/opt/homebrew/bin",
|
|
3649
|
-
"/usr/local/bin",
|
|
3650
|
-
// Keep after Homebrew/npm so a user-installed CLI still wins.
|
|
3651
|
-
conductorBundledBinDir(home)
|
|
3652
|
-
];
|
|
3653
|
-
for (const dir of extras.reverse()) {
|
|
3654
|
-
if (!dir || seen.has(dir) || !(0, import_node_fs12.existsSync)(dir)) continue;
|
|
3655
|
-
parts.unshift(dir);
|
|
3656
|
-
seen.add(dir);
|
|
3657
|
-
}
|
|
3658
|
-
const next = parts.join(import_node_path13.delimiter);
|
|
3659
|
-
env.PATH = next;
|
|
3660
|
-
return next;
|
|
3661
|
-
}
|
|
3662
|
-
function enrichPathWithNpmGlobalBin(env = process.env) {
|
|
3663
|
-
ensureAgentPath(env);
|
|
3664
|
-
try {
|
|
3665
|
-
const prefix = (0, import_node_child_process2.execFileSync)("npm", ["prefix", "-g"], {
|
|
3666
|
-
encoding: "utf8",
|
|
3667
|
-
env: { ...process.env, ...env },
|
|
3668
|
-
timeout: 8e3,
|
|
3669
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
3670
|
-
}).trim().split(/\r?\n/).find(Boolean);
|
|
3671
|
-
if (prefix) {
|
|
3672
|
-
const binDir = process.platform === "win32" ? prefix : (0, import_node_path13.join)(prefix, "bin");
|
|
3673
|
-
prependPathDir(env, binDir);
|
|
3674
|
-
}
|
|
3675
|
-
} catch {
|
|
3676
|
-
}
|
|
3677
|
-
return env.PATH ?? "";
|
|
3678
|
-
}
|
|
3679
|
-
function posixShellSingleQuote(value) {
|
|
3680
|
-
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
3681
|
-
}
|
|
3682
|
-
function resolveCommandBinarySync(command, whichPath) {
|
|
3683
|
-
const trimmed = command.trim();
|
|
3684
|
-
if (!trimmed) return trimmed;
|
|
3685
|
-
const match = /^(\S+)(\s[\s\S]*)?$/.exec(trimmed);
|
|
3686
|
-
if (!match) return trimmed;
|
|
3687
|
-
const bin = match[1];
|
|
3688
|
-
const rest = match[2] ?? "";
|
|
3689
|
-
if (bin.includes("/") || bin.includes("\\")) return trimmed;
|
|
3690
|
-
const abs = whichPath?.trim().split(/\r?\n/).find(Boolean);
|
|
3691
|
-
if (!abs) return trimmed;
|
|
3692
|
-
return `${abs}${rest}`;
|
|
3693
|
-
}
|
|
3694
|
-
function withExportedPath(command, pathValue) {
|
|
3695
|
-
const trimmed = command.trim();
|
|
3696
|
-
if (!trimmed) return trimmed;
|
|
3697
|
-
if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
|
|
3698
|
-
return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
|
|
3699
|
-
}
|
|
3700
|
-
var import_node_fs12, import_node_child_process2, import_node_os5, import_node_path13, EXTRA_BIN_DIRS;
|
|
3701
|
-
var init_path = __esm({
|
|
3702
|
-
"src/agents/path.ts"() {
|
|
3703
|
-
"use strict";
|
|
3704
|
-
import_node_fs12 = require("fs");
|
|
3705
|
-
import_node_child_process2 = require("child_process");
|
|
3706
|
-
import_node_os5 = require("os");
|
|
3707
|
-
import_node_path13 = require("path");
|
|
3708
|
-
EXTRA_BIN_DIRS = [
|
|
3709
|
-
".local/bin",
|
|
3710
|
-
".cargo/bin",
|
|
3711
|
-
".nvm/current/bin",
|
|
3712
|
-
".asdf/shims",
|
|
3713
|
-
".volta/bin",
|
|
3714
|
-
".npm-global/bin",
|
|
3715
|
-
// fnm default alias (common when shell init is skipped)
|
|
3716
|
-
".local/share/fnm/aliases/default/bin",
|
|
3717
|
-
// pnpm / npm global bins (where `@brightsy/cli` typically lands)
|
|
3718
|
-
"Library/pnpm",
|
|
3719
|
-
".pnpm"
|
|
3720
|
-
];
|
|
3721
|
-
}
|
|
3722
|
-
});
|
|
3723
|
-
|
|
3724
|
-
// src/git/run.ts
|
|
3725
|
-
var run_exports = {};
|
|
3726
|
-
__export(run_exports, {
|
|
3727
|
-
gh: () => gh,
|
|
3728
|
-
git: () => git,
|
|
3729
|
-
resolveGhAuthToken: () => resolveGhAuthToken,
|
|
3730
|
-
run: () => run
|
|
3731
|
-
});
|
|
3732
|
-
async function run(file, args, opts) {
|
|
3733
|
-
ensureAgentPath();
|
|
3734
|
-
try {
|
|
3735
|
-
const result = await (0, import_execa2.execa)(file, args, {
|
|
3736
|
-
cwd: opts?.cwd,
|
|
3737
|
-
env: { ...process.env, ...opts?.env },
|
|
3738
|
-
reject: opts?.reject ?? true,
|
|
3739
|
-
...opts?.timeoutMs != null ? { timeout: opts.timeoutMs } : {}
|
|
3740
|
-
});
|
|
3741
|
-
return {
|
|
3742
|
-
stdout: result.stdout ?? "",
|
|
3743
|
-
stderr: result.stderr ?? "",
|
|
3744
|
-
exitCode: result.exitCode ?? 0
|
|
3745
|
-
};
|
|
3746
|
-
} catch (err) {
|
|
3747
|
-
const e = err;
|
|
3748
|
-
if (opts?.reject === false) {
|
|
3749
|
-
return {
|
|
3750
|
-
stdout: String(e.stdout ?? ""),
|
|
3751
|
-
stderr: String(e.stderr ?? ""),
|
|
3752
|
-
exitCode: e.exitCode ?? 1
|
|
3753
|
-
};
|
|
3754
|
-
}
|
|
3755
|
-
throw err;
|
|
3756
|
-
}
|
|
3757
|
-
}
|
|
3758
|
-
async function git(args, cwd, opts) {
|
|
3759
|
-
const prefix = [];
|
|
3760
|
-
if (opts?.config) {
|
|
3761
|
-
for (const [key, value] of Object.entries(opts.config)) {
|
|
3762
|
-
if (!key) continue;
|
|
3763
|
-
prefix.push("-c", `${key}=${value}`);
|
|
3764
|
-
}
|
|
3765
|
-
}
|
|
3766
|
-
return run("git", ["--no-pager", ...prefix, ...args], {
|
|
3767
|
-
cwd,
|
|
3768
|
-
reject: opts?.reject,
|
|
3769
|
-
timeoutMs: opts?.timeoutMs,
|
|
3770
|
-
// Never block forever on a credential/SSH prompt inside MCP / Electron.
|
|
3771
|
-
env: {
|
|
3772
|
-
GIT_TERMINAL_PROMPT: "0",
|
|
3773
|
-
GIT_ASKPASS: process.env.GIT_ASKPASS || "echo",
|
|
3774
|
-
SSH_ASKPASS: process.env.SSH_ASKPASS || "echo",
|
|
3775
|
-
GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND || "ssh -o BatchMode=yes -o ConnectTimeout=15",
|
|
3776
|
-
GCM_INTERACTIVE: "never",
|
|
3777
|
-
GH_PROMPT_DISABLED: "1",
|
|
3778
|
-
...opts?.env
|
|
3779
|
-
}
|
|
3780
|
-
});
|
|
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");
|
|
3781
3844
|
}
|
|
3782
|
-
|
|
3783
|
-
return
|
|
3784
|
-
cwd,
|
|
3785
|
-
reject: opts?.reject,
|
|
3786
|
-
timeoutMs: opts?.timeoutMs,
|
|
3787
|
-
env: {
|
|
3788
|
-
GH_PROMPT_DISABLED: "1",
|
|
3789
|
-
GIT_TERMINAL_PROMPT: "0"
|
|
3790
|
-
}
|
|
3791
|
-
});
|
|
3845
|
+
function githubAgentAuthReady() {
|
|
3846
|
+
return (0, import_node_fs13.existsSync)(githubCredentialStorePath()) && (0, import_node_fs13.existsSync)((0, import_node_path14.join)(githubGhConfigDir(), "hosts.yml"));
|
|
3792
3847
|
}
|
|
3793
|
-
|
|
3794
|
-
const
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3848
|
+
function githubCredentialHelperGitConfig() {
|
|
3849
|
+
const file = githubCredentialStorePath();
|
|
3850
|
+
return [
|
|
3851
|
+
{ key: "credential.helper", value: "" },
|
|
3852
|
+
{ key: "credential.helper", value: `store --file=${file}` }
|
|
3853
|
+
];
|
|
3798
3854
|
}
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
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"() {
|
|
3802
3864
|
"use strict";
|
|
3803
|
-
|
|
3804
|
-
|
|
3865
|
+
import_node_fs13 = require("fs");
|
|
3866
|
+
import_node_os5 = require("os");
|
|
3867
|
+
import_node_path14 = require("path");
|
|
3805
3868
|
}
|
|
3806
3869
|
});
|
|
3807
3870
|
|
|
@@ -3893,7 +3956,7 @@ async function warmGithubAgentAuth(opts) {
|
|
|
3893
3956
|
}
|
|
3894
3957
|
function normalizeWritableRoot(raw) {
|
|
3895
3958
|
const trimmed = raw.trim().replace(/\/+$/, "");
|
|
3896
|
-
return trimmed && (0,
|
|
3959
|
+
return trimmed && (0, import_node_path15.isAbsolute)(trimmed) ? trimmed : null;
|
|
3897
3960
|
}
|
|
3898
3961
|
async function resolveCodexGitWritableRoots(cwd) {
|
|
3899
3962
|
const roots = /* @__PURE__ */ new Set();
|
|
@@ -3970,11 +4033,11 @@ function formatGitAuthModeDirective(mode) {
|
|
|
3970
4033
|
].join("\n");
|
|
3971
4034
|
}
|
|
3972
4035
|
}
|
|
3973
|
-
var
|
|
4036
|
+
var import_node_path15, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
|
|
3974
4037
|
var init_git_auth_mode = __esm({
|
|
3975
4038
|
"src/git/git-auth-mode.ts"() {
|
|
3976
4039
|
"use strict";
|
|
3977
|
-
|
|
4040
|
+
import_node_path15 = require("path");
|
|
3978
4041
|
init_app_settings();
|
|
3979
4042
|
init_github_agent_auth();
|
|
3980
4043
|
init_run();
|
|
@@ -5144,8 +5207,8 @@ function isLocalPrFetchBranch(ref) {
|
|
|
5144
5207
|
}
|
|
5145
5208
|
async function createThreadWorktree(opts) {
|
|
5146
5209
|
let branchName = `thread/${opts.slug}`;
|
|
5147
|
-
const worktreePath = (0,
|
|
5148
|
-
if ((0,
|
|
5210
|
+
const worktreePath = (0, import_node_path16.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
5211
|
+
if ((0, import_node_fs14.existsSync)(worktreePath)) {
|
|
5149
5212
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
5150
5213
|
}
|
|
5151
5214
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -5212,8 +5275,8 @@ ${add.stdout}`;
|
|
|
5212
5275
|
async function createExistingBranchWorktree(opts) {
|
|
5213
5276
|
const branchName = opts.branchName.trim();
|
|
5214
5277
|
if (!branchName) throw new Error("branch name required");
|
|
5215
|
-
const worktreePath = (0,
|
|
5216
|
-
if ((0,
|
|
5278
|
+
const worktreePath = (0, import_node_path16.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
5279
|
+
if ((0, import_node_fs14.existsSync)(worktreePath)) {
|
|
5217
5280
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
5218
5281
|
}
|
|
5219
5282
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -5504,10 +5567,10 @@ function sameRepoPath(a, b) {
|
|
|
5504
5567
|
return normalizeWorktreePath(a) === normalizeWorktreePath(b);
|
|
5505
5568
|
}
|
|
5506
5569
|
function listLocalThreadBranchSlugs(repoPath) {
|
|
5507
|
-
const refsDir = (0,
|
|
5508
|
-
if (!(0,
|
|
5570
|
+
const refsDir = (0, import_node_path16.join)(repoPath, ".git", "refs", "heads", "thread");
|
|
5571
|
+
if (!(0, import_node_fs14.existsSync)(refsDir)) return [];
|
|
5509
5572
|
try {
|
|
5510
|
-
return (0,
|
|
5573
|
+
return (0, import_node_fs14.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
|
|
5511
5574
|
} catch {
|
|
5512
5575
|
return [];
|
|
5513
5576
|
}
|
|
@@ -5515,8 +5578,8 @@ function listLocalThreadBranchSlugs(repoPath) {
|
|
|
5515
5578
|
function collectTakenTeamSlugs(repoPath) {
|
|
5516
5579
|
const taken = /* @__PURE__ */ new Set();
|
|
5517
5580
|
const root = worktreesRoot(repoPath);
|
|
5518
|
-
if ((0,
|
|
5519
|
-
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 })) {
|
|
5520
5583
|
if (entry.isDirectory() && entry.name !== ".DS_Store") {
|
|
5521
5584
|
taken.add(normalizeTakenSlug(entry.name));
|
|
5522
5585
|
}
|
|
@@ -5537,18 +5600,18 @@ function allocateTeamSlug(repoPath) {
|
|
|
5537
5600
|
const taken = collectTakenTeamSlugs(repoPath);
|
|
5538
5601
|
for (let attempt = 0; attempt < 32; attempt++) {
|
|
5539
5602
|
const team = allocateTeamName(taken);
|
|
5540
|
-
const path = (0,
|
|
5541
|
-
if (!(0,
|
|
5603
|
+
const path = (0, import_node_path16.join)(worktreesRoot(repoPath), team.slug);
|
|
5604
|
+
if (!(0, import_node_fs14.existsSync)(path)) return team;
|
|
5542
5605
|
taken.add(team.slug);
|
|
5543
5606
|
}
|
|
5544
5607
|
throw new Error("No available soccer team worktree directories left");
|
|
5545
5608
|
}
|
|
5546
|
-
var
|
|
5609
|
+
var import_node_fs14, import_node_path16;
|
|
5547
5610
|
var init_worktree = __esm({
|
|
5548
5611
|
"src/git/worktree.ts"() {
|
|
5549
5612
|
"use strict";
|
|
5550
|
-
|
|
5551
|
-
|
|
5613
|
+
import_node_fs14 = require("fs");
|
|
5614
|
+
import_node_path16 = require("path");
|
|
5552
5615
|
init_paths();
|
|
5553
5616
|
init_thread_store();
|
|
5554
5617
|
init_teams();
|
|
@@ -5683,7 +5746,7 @@ function coordinatorTurnReminder(opts) {
|
|
|
5683
5746
|
function ensureGlobalCoordinatorCwd(opts) {
|
|
5684
5747
|
const dir = globalAgentCwd();
|
|
5685
5748
|
try {
|
|
5686
|
-
(0,
|
|
5749
|
+
(0, import_node_fs15.mkdirSync)(dir, { recursive: true });
|
|
5687
5750
|
} catch {
|
|
5688
5751
|
return dir;
|
|
5689
5752
|
}
|
|
@@ -5691,7 +5754,7 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
5691
5754
|
let orchId = opts?.orchestratorThreadId?.trim() || "";
|
|
5692
5755
|
if (!orchId) {
|
|
5693
5756
|
try {
|
|
5694
|
-
const existing = (0,
|
|
5757
|
+
const existing = (0, import_node_fs15.readFileSync)((0, import_node_path17.join)(dir, "AGENTS.md"), "utf8");
|
|
5695
5758
|
const m = existing.match(
|
|
5696
5759
|
/YOUR orchestration thread id is `([0-9a-f-]{36})`/i
|
|
5697
5760
|
);
|
|
@@ -5733,9 +5796,9 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
5733
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."
|
|
5734
5797
|
].join("\n");
|
|
5735
5798
|
try {
|
|
5736
|
-
(0,
|
|
5799
|
+
(0, import_node_fs15.writeFileSync)((0, import_node_path17.join)(dir, "CLAUDE.md"), `${body}
|
|
5737
5800
|
`, "utf8");
|
|
5738
|
-
(0,
|
|
5801
|
+
(0, import_node_fs15.writeFileSync)((0, import_node_path17.join)(dir, "AGENTS.md"), `${body}
|
|
5739
5802
|
`, "utf8");
|
|
5740
5803
|
} catch {
|
|
5741
5804
|
}
|
|
@@ -5767,12 +5830,12 @@ function coordinatorSystemPrompt(opts) {
|
|
|
5767
5830
|
formatWorkspaceInventory(opts.workspaces)
|
|
5768
5831
|
].join("\n");
|
|
5769
5832
|
}
|
|
5770
|
-
var
|
|
5833
|
+
var import_node_fs15, import_node_path17, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
|
|
5771
5834
|
var init_coordinator_prompt = __esm({
|
|
5772
5835
|
"src/orchestrator/coordinator-prompt.ts"() {
|
|
5773
5836
|
"use strict";
|
|
5774
|
-
|
|
5775
|
-
|
|
5837
|
+
import_node_fs15 = require("fs");
|
|
5838
|
+
import_node_path17 = require("path");
|
|
5776
5839
|
init_worktree();
|
|
5777
5840
|
init_app_settings();
|
|
5778
5841
|
init_paths();
|
|
@@ -5798,7 +5861,7 @@ var init_coordinator_prompt = __esm({
|
|
|
5798
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.",
|
|
5799
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.",
|
|
5800
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",
|
|
5801
|
-
"- 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.",
|
|
5802
5865
|
"- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
|
|
5803
5866
|
"- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
|
|
5804
5867
|
"Setup / run:",
|
|
@@ -6070,32 +6133,32 @@ var init_global_workspace = __esm({
|
|
|
6070
6133
|
|
|
6071
6134
|
// src/brightsy/config.ts
|
|
6072
6135
|
function brightsyConfigPath() {
|
|
6073
|
-
return (0,
|
|
6136
|
+
return (0, import_node_path18.join)((0, import_node_os6.homedir)(), ".brightsy", "config.json");
|
|
6074
6137
|
}
|
|
6075
6138
|
function loadBrightsyConfig() {
|
|
6076
6139
|
const path = brightsyConfigPath();
|
|
6077
|
-
if (!(0,
|
|
6140
|
+
if (!(0, import_node_fs16.existsSync)(path)) {
|
|
6078
6141
|
throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
|
|
6079
6142
|
}
|
|
6080
|
-
const raw = JSON.parse((0,
|
|
6143
|
+
const raw = JSON.parse((0, import_node_fs16.readFileSync)(path, "utf8"));
|
|
6081
6144
|
if (!raw.access_token || !raw.account_id) {
|
|
6082
6145
|
throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
|
|
6083
6146
|
}
|
|
6084
6147
|
return raw;
|
|
6085
6148
|
}
|
|
6086
6149
|
function saveBrightsyConfig(cfg) {
|
|
6087
|
-
(0,
|
|
6150
|
+
(0, import_node_fs16.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
|
|
6088
6151
|
`, {
|
|
6089
6152
|
mode: 384
|
|
6090
6153
|
});
|
|
6091
6154
|
}
|
|
6092
|
-
var
|
|
6155
|
+
var import_node_fs16, import_node_os6, import_node_path18;
|
|
6093
6156
|
var init_config = __esm({
|
|
6094
6157
|
"src/brightsy/config.ts"() {
|
|
6095
6158
|
"use strict";
|
|
6096
|
-
|
|
6159
|
+
import_node_fs16 = require("fs");
|
|
6097
6160
|
import_node_os6 = require("os");
|
|
6098
|
-
|
|
6161
|
+
import_node_path18 = require("path");
|
|
6099
6162
|
}
|
|
6100
6163
|
});
|
|
6101
6164
|
|
|
@@ -6110,22 +6173,22 @@ var init_accounts = __esm({
|
|
|
6110
6173
|
|
|
6111
6174
|
// src/brightsy/connected-teams.ts
|
|
6112
6175
|
function storePath4() {
|
|
6113
|
-
return (0,
|
|
6176
|
+
return (0, import_node_path19.join)(appDataDir(), "brightsy-teams.json");
|
|
6114
6177
|
}
|
|
6115
6178
|
function readStore4() {
|
|
6116
6179
|
const path = storePath4();
|
|
6117
|
-
if (!(0,
|
|
6180
|
+
if (!(0, import_node_fs17.existsSync)(path)) return [];
|
|
6118
6181
|
try {
|
|
6119
|
-
const parsed = JSON.parse((0,
|
|
6182
|
+
const parsed = JSON.parse((0, import_node_fs17.readFileSync)(path, "utf8"));
|
|
6120
6183
|
return Array.isArray(parsed.teams) ? parsed.teams : [];
|
|
6121
6184
|
} catch {
|
|
6122
6185
|
return [];
|
|
6123
6186
|
}
|
|
6124
6187
|
}
|
|
6125
6188
|
function writeStore2(teams) {
|
|
6126
|
-
(0,
|
|
6189
|
+
(0, import_node_fs17.mkdirSync)(appDataDir(), { recursive: true });
|
|
6127
6190
|
const path = storePath4();
|
|
6128
|
-
(0,
|
|
6191
|
+
(0, import_node_fs17.writeFileSync)(path, `${JSON.stringify({ teams }, null, 2)}
|
|
6129
6192
|
`, {
|
|
6130
6193
|
mode: 384
|
|
6131
6194
|
});
|
|
@@ -6237,12 +6300,12 @@ function brightsyMcpServerName(slug) {
|
|
|
6237
6300
|
const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
|
|
6238
6301
|
return `brightsy_${cleaned || "team"}`;
|
|
6239
6302
|
}
|
|
6240
|
-
var
|
|
6303
|
+
var import_node_fs17, import_node_path19;
|
|
6241
6304
|
var init_connected_teams = __esm({
|
|
6242
6305
|
"src/brightsy/connected-teams.ts"() {
|
|
6243
6306
|
"use strict";
|
|
6244
|
-
|
|
6245
|
-
|
|
6307
|
+
import_node_fs17 = require("fs");
|
|
6308
|
+
import_node_path19 = require("path");
|
|
6246
6309
|
init_paths();
|
|
6247
6310
|
init_accounts();
|
|
6248
6311
|
init_config();
|
|
@@ -6573,11 +6636,11 @@ async function syncCliForTarget(accountId) {
|
|
|
6573
6636
|
}
|
|
6574
6637
|
applyConnectedTeamToCli(team);
|
|
6575
6638
|
}
|
|
6576
|
-
var
|
|
6639
|
+
var import_node_fs18, brightsyAdapter;
|
|
6577
6640
|
var init_brightsy = __esm({
|
|
6578
6641
|
"src/agents/brightsy.ts"() {
|
|
6579
6642
|
"use strict";
|
|
6580
|
-
|
|
6643
|
+
import_node_fs18 = require("fs");
|
|
6581
6644
|
init_run();
|
|
6582
6645
|
init_connected_teams();
|
|
6583
6646
|
init_config();
|
|
@@ -6592,7 +6655,7 @@ var init_brightsy = __esm({
|
|
|
6592
6655
|
async detect() {
|
|
6593
6656
|
const brightsy = resolveAgentExecutable("brightsy");
|
|
6594
6657
|
if (brightsy !== "brightsy") {
|
|
6595
|
-
if (!(0,
|
|
6658
|
+
if (!(0, import_node_fs18.existsSync)(brightsy)) {
|
|
6596
6659
|
return {
|
|
6597
6660
|
agent: "brightsy",
|
|
6598
6661
|
installed: false,
|
|
@@ -6761,9 +6824,9 @@ function toolDescription(name, input) {
|
|
|
6761
6824
|
if (/connectedAgentRequest/i.test(name)) {
|
|
6762
6825
|
return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
|
|
6763
6826
|
}
|
|
6764
|
-
if (desc && kind) return `${kind}: ${desc}`;
|
|
6765
|
-
if (desc) return desc
|
|
6766
|
-
return
|
|
6827
|
+
if (desc && kind) return `${kind}: ${desc}${subagentLiveSuffix(input)}`;
|
|
6828
|
+
if (desc) return `${desc}${subagentLiveSuffix(input)}`;
|
|
6829
|
+
return `Subagent${subagentLiveSuffix(input)}`;
|
|
6767
6830
|
}
|
|
6768
6831
|
if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
|
|
6769
6832
|
return str2(input?.title) ? `Artifact ${str2(input?.title)}` : "Artifact";
|
|
@@ -6788,13 +6851,83 @@ function toolDescription(name, input) {
|
|
|
6788
6851
|
}
|
|
6789
6852
|
if (/grep/i.test(name)) return "Search files";
|
|
6790
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
|
+
}
|
|
6791
6865
|
return n;
|
|
6792
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
|
+
}
|
|
6793
6880
|
function isSubagentToolName(name) {
|
|
6794
6881
|
const n = (name ?? "").trim();
|
|
6795
6882
|
if (/^(task|agent|spawn_agent)$/i.test(n)) return true;
|
|
6796
6883
|
return /connectedAgentRequest/i.test(n);
|
|
6797
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
|
+
}
|
|
6798
6931
|
function messagePartParentId(part) {
|
|
6799
6932
|
if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
|
|
6800
6933
|
return part.parentId;
|
|
@@ -6876,6 +7009,25 @@ function applyAgentEvent(parts, event) {
|
|
|
6876
7009
|
const data = event.data;
|
|
6877
7010
|
if (!data) return parts;
|
|
6878
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
|
+
}
|
|
6879
7031
|
const last = next[next.length - 1];
|
|
6880
7032
|
if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
|
|
6881
7033
|
next[next.length - 1] = {
|
|
@@ -6899,14 +7051,18 @@ function applyAgentEvent(parts, event) {
|
|
|
6899
7051
|
if (existing >= 0) {
|
|
6900
7052
|
const prev = parts[existing];
|
|
6901
7053
|
const next = [...parts];
|
|
6902
|
-
const mergedInput =
|
|
7054
|
+
const mergedInput = {
|
|
7055
|
+
...prev.input ?? {},
|
|
7056
|
+
...input ?? {}
|
|
7057
|
+
};
|
|
7058
|
+
const mergedRecord = Object.keys(mergedInput).length > 0 ? mergedInput : void 0;
|
|
6903
7059
|
next[existing] = {
|
|
6904
7060
|
...prev,
|
|
6905
7061
|
name: event.name || prev.name,
|
|
6906
|
-
input:
|
|
6907
|
-
description: toolDescription(event.name || prev.name,
|
|
6908
|
-
detail: toolDetail(event.name || prev.name,
|
|
6909
|
-
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,
|
|
6910
7066
|
additions: diff.additions ?? prev.additions,
|
|
6911
7067
|
deletions: diff.deletions ?? prev.deletions,
|
|
6912
7068
|
parentId: event.parentId ?? prev.parentId
|
|
@@ -6932,6 +7088,30 @@ function applyAgentEvent(parts, event) {
|
|
|
6932
7088
|
if (event.type === "tool_result") {
|
|
6933
7089
|
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
6934
7090
|
const fromResult = parseDiffStat(event.content);
|
|
7091
|
+
if (event.partial) {
|
|
7092
|
+
if (existing < 0) {
|
|
7093
|
+
return [
|
|
7094
|
+
...parts,
|
|
7095
|
+
{
|
|
7096
|
+
type: "tool",
|
|
7097
|
+
id: event.id,
|
|
7098
|
+
name: "tool",
|
|
7099
|
+
description: "tool",
|
|
7100
|
+
status: event.isError ? "error" : "running",
|
|
7101
|
+
result: event.content,
|
|
7102
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
7103
|
+
}
|
|
7104
|
+
];
|
|
7105
|
+
}
|
|
7106
|
+
return parts.map((p, i) => {
|
|
7107
|
+
if (i !== existing || p.type !== "tool") return p;
|
|
7108
|
+
if (p.status === "done" || p.status === "error") return p;
|
|
7109
|
+
return {
|
|
7110
|
+
...p,
|
|
7111
|
+
result: event.content ?? p.result
|
|
7112
|
+
};
|
|
7113
|
+
});
|
|
7114
|
+
}
|
|
6935
7115
|
if (existing < 0) {
|
|
6936
7116
|
return [
|
|
6937
7117
|
...parts,
|
|
@@ -7017,47 +7197,68 @@ function electronResourcesPath() {
|
|
|
7017
7197
|
function packagedCursorRuntimeDir() {
|
|
7018
7198
|
const resources = electronResourcesPath();
|
|
7019
7199
|
if (!resources) return null;
|
|
7020
|
-
const dir = (0,
|
|
7021
|
-
if (!(0,
|
|
7200
|
+
const dir = (0, import_node_path20.join)(resources, "cursor-runtime");
|
|
7201
|
+
if (!(0, import_node_fs19.existsSync)((0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
|
|
7022
7202
|
return dir;
|
|
7023
7203
|
}
|
|
7024
7204
|
function packagedCursorRunnerPath() {
|
|
7025
7205
|
const dir = packagedCursorRuntimeDir();
|
|
7026
|
-
return dir ? (0,
|
|
7206
|
+
return dir ? (0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
|
|
7027
7207
|
}
|
|
7028
7208
|
function packagedMcpDir() {
|
|
7029
7209
|
const resources = electronResourcesPath();
|
|
7030
7210
|
if (!resources) return null;
|
|
7031
|
-
const dir = (0,
|
|
7032
|
-
if (!(0,
|
|
7211
|
+
const dir = (0, import_node_path20.join)(resources, "sideboard-mcp");
|
|
7212
|
+
if (!(0, import_node_fs19.existsSync)((0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
|
|
7033
7213
|
return dir;
|
|
7034
7214
|
}
|
|
7035
7215
|
function packagedMcpStdioPath() {
|
|
7036
7216
|
const dir = packagedMcpDir();
|
|
7037
|
-
return dir ? (0,
|
|
7217
|
+
return dir ? (0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
|
|
7038
7218
|
}
|
|
7039
7219
|
function packagedBundledNodePath() {
|
|
7040
7220
|
const resources = electronResourcesPath();
|
|
7041
7221
|
if (!resources) return null;
|
|
7042
|
-
const bin = (0,
|
|
7043
|
-
if (!(0,
|
|
7222
|
+
const bin = (0, import_node_path20.join)(resources, "node", "bin", "node");
|
|
7223
|
+
if (!(0, import_node_fs19.existsSync)(bin)) return null;
|
|
7044
7224
|
return bin;
|
|
7045
7225
|
}
|
|
7046
7226
|
function packagedCursorRipgrepCandidate(platformPkg, binName) {
|
|
7047
7227
|
const dir = packagedCursorRuntimeDir();
|
|
7048
7228
|
if (!dir) return null;
|
|
7049
|
-
return (0,
|
|
7229
|
+
return (0, import_node_path20.join)(dir, "node_modules", platformPkg, "bin", binName);
|
|
7050
7230
|
}
|
|
7051
|
-
var
|
|
7231
|
+
var import_node_fs19, import_node_path20;
|
|
7052
7232
|
var init_packaged_runtime = __esm({
|
|
7053
7233
|
"src/agents/packaged-runtime.ts"() {
|
|
7054
7234
|
"use strict";
|
|
7055
|
-
|
|
7056
|
-
|
|
7235
|
+
import_node_fs19 = require("fs");
|
|
7236
|
+
import_node_path20 = require("path");
|
|
7057
7237
|
}
|
|
7058
7238
|
});
|
|
7059
7239
|
|
|
7060
7240
|
// src/agents/node-launch.ts
|
|
7241
|
+
function withMaxOldSpaceSize(nodeOptions, heapMb) {
|
|
7242
|
+
const existing = (nodeOptions ?? "").trim();
|
|
7243
|
+
const match = MAX_OLD_SPACE_FLAG.exec(existing);
|
|
7244
|
+
if (match) {
|
|
7245
|
+
const current = match[2] ? Number(match[2]) : 0;
|
|
7246
|
+
if (Number.isFinite(current) && current >= heapMb) return existing;
|
|
7247
|
+
return existing.replace(MAX_OLD_SPACE_FLAG, ` --max-old-space-size=${heapMb}`).trim();
|
|
7248
|
+
}
|
|
7249
|
+
return existing ? `${existing} --max-old-space-size=${heapMb}` : `--max-old-space-size=${heapMb}`;
|
|
7250
|
+
}
|
|
7251
|
+
function applyAgentRunnerHeapEnv(env) {
|
|
7252
|
+
env.NODE_OPTIONS = withMaxOldSpaceSize(
|
|
7253
|
+
env.NODE_OPTIONS,
|
|
7254
|
+
AGENT_RUNNER_MAX_OLD_SPACE_MB
|
|
7255
|
+
);
|
|
7256
|
+
}
|
|
7257
|
+
function envWithAgentHeap(env) {
|
|
7258
|
+
const next = { ...env };
|
|
7259
|
+
applyAgentRunnerHeapEnv(next);
|
|
7260
|
+
return next;
|
|
7261
|
+
}
|
|
7061
7262
|
function isAsarPath(filePath) {
|
|
7062
7263
|
if (/\.asar\.unpacked([/\\]|$)/.test(filePath)) return false;
|
|
7063
7264
|
return /\.asar([/\\]|$)/.test(filePath);
|
|
@@ -7066,7 +7267,7 @@ function unpackedAsarPath(filePath) {
|
|
|
7066
7267
|
if (!isAsarPath(filePath)) return null;
|
|
7067
7268
|
const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
|
|
7068
7269
|
if (unpacked === filePath) return null;
|
|
7069
|
-
return (0,
|
|
7270
|
+
return (0, import_node_fs20.existsSync)(unpacked) ? unpacked : null;
|
|
7070
7271
|
}
|
|
7071
7272
|
function nodeReadableScriptPath(scriptPath) {
|
|
7072
7273
|
return unpackedAsarPath(scriptPath) ?? scriptPath;
|
|
@@ -7106,37 +7307,37 @@ function pickPreferredNode(candidates) {
|
|
|
7106
7307
|
return best;
|
|
7107
7308
|
}
|
|
7108
7309
|
function versionDirNodeBins(root, toBin) {
|
|
7109
|
-
if (!(0,
|
|
7310
|
+
if (!(0, import_node_fs20.existsSync)(root)) return [];
|
|
7110
7311
|
try {
|
|
7111
|
-
return (0,
|
|
7312
|
+
return (0, import_node_fs20.readdirSync)(root).map(toBin);
|
|
7112
7313
|
} catch {
|
|
7113
7314
|
return [];
|
|
7114
7315
|
}
|
|
7115
7316
|
}
|
|
7116
7317
|
function defaultNodeBinCandidates(home = (0, import_node_os7.homedir)()) {
|
|
7117
7318
|
const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
|
|
7118
|
-
(prefix) => PREFERRED_LTS_MAJORS.map((major) => (0,
|
|
7319
|
+
(prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path21.join)(prefix, "opt", `node@${major}`, "bin", "node"))
|
|
7119
7320
|
);
|
|
7120
7321
|
return [
|
|
7121
7322
|
...kegs,
|
|
7122
7323
|
"/opt/homebrew/bin/node",
|
|
7123
7324
|
"/usr/local/bin/node",
|
|
7124
|
-
(0,
|
|
7125
|
-
(0,
|
|
7126
|
-
(0,
|
|
7127
|
-
(0,
|
|
7128
|
-
(0,
|
|
7325
|
+
(0, import_node_path21.join)(home, ".local/share/fnm/aliases/default/bin/node"),
|
|
7326
|
+
(0, import_node_path21.join)(home, ".nvm/current/bin/node"),
|
|
7327
|
+
(0, import_node_path21.join)(home, ".volta/bin/node"),
|
|
7328
|
+
(0, import_node_path21.join)(home, ".asdf/shims/node"),
|
|
7329
|
+
(0, import_node_path21.join)(home, ".local/share/mise/shims/node"),
|
|
7129
7330
|
...versionDirNodeBins(
|
|
7130
|
-
(0,
|
|
7131
|
-
(name) => (0,
|
|
7331
|
+
(0, import_node_path21.join)(home, ".nvm", "versions", "node"),
|
|
7332
|
+
(name) => (0, import_node_path21.join)(home, ".nvm", "versions", "node", name, "bin", "node")
|
|
7132
7333
|
),
|
|
7133
7334
|
...versionDirNodeBins(
|
|
7134
|
-
(0,
|
|
7135
|
-
(name) => (0,
|
|
7335
|
+
(0, import_node_path21.join)(home, ".local/share/fnm", "node-versions"),
|
|
7336
|
+
(name) => (0, import_node_path21.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
|
|
7136
7337
|
),
|
|
7137
7338
|
...versionDirNodeBins(
|
|
7138
|
-
(0,
|
|
7139
|
-
(name) => (0,
|
|
7339
|
+
(0, import_node_path21.join)(home, ".volta", "tools", "image", "node"),
|
|
7340
|
+
(name) => (0, import_node_path21.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
|
|
7140
7341
|
)
|
|
7141
7342
|
];
|
|
7142
7343
|
}
|
|
@@ -7145,10 +7346,10 @@ function uniqueExistingNodeBins(paths) {
|
|
|
7145
7346
|
const out = [];
|
|
7146
7347
|
for (const raw of paths) {
|
|
7147
7348
|
const p = raw.trim();
|
|
7148
|
-
if (!p || !(0,
|
|
7349
|
+
if (!p || !(0, import_node_fs20.existsSync)(p) || isElectronLikeCommand(p)) continue;
|
|
7149
7350
|
let key = p;
|
|
7150
7351
|
try {
|
|
7151
|
-
key = (0,
|
|
7352
|
+
key = (0, import_node_fs20.realpathSync)(p);
|
|
7152
7353
|
} catch {
|
|
7153
7354
|
continue;
|
|
7154
7355
|
}
|
|
@@ -7193,13 +7394,21 @@ async function findSystemNode() {
|
|
|
7193
7394
|
function applyNodeLaunch(launch, args) {
|
|
7194
7395
|
const readableArgs = args.map(nodeReadableScriptPath);
|
|
7195
7396
|
if (!launch.env.ELECTRON_RUN_AS_NODE) {
|
|
7196
|
-
return {
|
|
7397
|
+
return {
|
|
7398
|
+
file: launch.file,
|
|
7399
|
+
args: readableArgs,
|
|
7400
|
+
env: envWithAgentHeap(launch.env)
|
|
7401
|
+
};
|
|
7197
7402
|
}
|
|
7198
7403
|
const wrapped = wrapElectronAsNodeLaunch(launch.file, readableArgs);
|
|
7199
7404
|
if (process.platform === "win32") {
|
|
7200
|
-
return {
|
|
7405
|
+
return {
|
|
7406
|
+
file: wrapped.file,
|
|
7407
|
+
args: wrapped.args,
|
|
7408
|
+
env: envWithAgentHeap(launch.env)
|
|
7409
|
+
};
|
|
7201
7410
|
}
|
|
7202
|
-
const env =
|
|
7411
|
+
const env = envWithAgentHeap(launch.env);
|
|
7203
7412
|
delete env.ELECTRON_RUN_AS_NODE;
|
|
7204
7413
|
return { file: wrapped.file, args: wrapped.args, env };
|
|
7205
7414
|
}
|
|
@@ -7220,16 +7429,18 @@ async function resolveNodeLaunch(scriptPath) {
|
|
|
7220
7429
|
env: { ELECTRON_RUN_AS_NODE: "1" }
|
|
7221
7430
|
};
|
|
7222
7431
|
}
|
|
7223
|
-
var
|
|
7432
|
+
var import_node_fs20, import_node_os7, import_node_path21, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
|
|
7224
7433
|
var init_node_launch = __esm({
|
|
7225
7434
|
"src/agents/node-launch.ts"() {
|
|
7226
7435
|
"use strict";
|
|
7227
|
-
|
|
7436
|
+
import_node_fs20 = require("fs");
|
|
7228
7437
|
import_node_os7 = require("os");
|
|
7229
|
-
|
|
7438
|
+
import_node_path21 = require("path");
|
|
7230
7439
|
init_nested_electron_env();
|
|
7231
7440
|
init_run();
|
|
7232
7441
|
init_packaged_runtime();
|
|
7442
|
+
AGENT_RUNNER_MAX_OLD_SPACE_MB = 8192;
|
|
7443
|
+
MAX_OLD_SPACE_FLAG = /(?:^|\s)(--max[-_]old[-_]space[-_]size)(?:[= ](\d+))?(?=\s|$)/;
|
|
7233
7444
|
PREFERRED_LTS_MAJORS = [24, 22, 20];
|
|
7234
7445
|
}
|
|
7235
7446
|
});
|
|
@@ -7317,37 +7528,37 @@ function corePackageDir() {
|
|
|
7317
7528
|
try {
|
|
7318
7529
|
const url = import_meta.url;
|
|
7319
7530
|
if (typeof url === "string" && url.length > 0) {
|
|
7320
|
-
return (0,
|
|
7531
|
+
return (0, import_node_path22.dirname)((0, import_node_url.fileURLToPath)(url));
|
|
7321
7532
|
}
|
|
7322
7533
|
} catch {
|
|
7323
7534
|
}
|
|
7324
7535
|
try {
|
|
7325
|
-
const req = (0, import_node_module.createRequire)((0,
|
|
7326
|
-
return (0,
|
|
7536
|
+
const req = (0, import_node_module.createRequire)((0, import_node_path22.join)(process.cwd(), "package.json"));
|
|
7537
|
+
return (0, import_node_path22.dirname)(req.resolve("@sideboard-ai/core"));
|
|
7327
7538
|
} catch {
|
|
7328
7539
|
return process.cwd();
|
|
7329
7540
|
}
|
|
7330
7541
|
}
|
|
7331
7542
|
function findSideboardMcpJsEntry() {
|
|
7332
7543
|
const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
|
|
7333
|
-
if (override && (0,
|
|
7544
|
+
if (override && (0, import_node_fs21.existsSync)(override)) return override;
|
|
7334
7545
|
const packaged = packagedMcpStdioPath();
|
|
7335
7546
|
if (packaged) return packaged;
|
|
7336
7547
|
let dir = corePackageDir();
|
|
7337
7548
|
for (let i = 0; i < 10; i++) {
|
|
7338
7549
|
const candidates = [
|
|
7339
|
-
(0,
|
|
7340
|
-
(0,
|
|
7341
|
-
(0,
|
|
7342
|
-
(0,
|
|
7343
|
-
(0,
|
|
7344
|
-
(0,
|
|
7345
|
-
(0,
|
|
7550
|
+
(0, import_node_path22.join)(dir, "mcp/run-stdio.js"),
|
|
7551
|
+
(0, import_node_path22.join)(dir, "mcp/run-stdio.cjs"),
|
|
7552
|
+
(0, import_node_path22.join)(dir, "dist/mcp/run-stdio.js"),
|
|
7553
|
+
(0, import_node_path22.join)(dir, "dist/mcp/run-stdio.cjs"),
|
|
7554
|
+
(0, import_node_path22.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
7555
|
+
(0, import_node_path22.join)(dir, "packages/cli/dist/index.js"),
|
|
7556
|
+
(0, import_node_path22.join)(dir, "cli/dist/index.js")
|
|
7346
7557
|
];
|
|
7347
7558
|
for (const p of candidates) {
|
|
7348
|
-
if ((0,
|
|
7559
|
+
if ((0, import_node_fs21.existsSync)(p) && !isAsarPath(p)) return p;
|
|
7349
7560
|
}
|
|
7350
|
-
const parent = (0,
|
|
7561
|
+
const parent = (0, import_node_path22.dirname)(dir);
|
|
7351
7562
|
if (parent === dir) break;
|
|
7352
7563
|
dir = parent;
|
|
7353
7564
|
}
|
|
@@ -7395,6 +7606,7 @@ async function buildInjectedMcpServers(opts) {
|
|
|
7395
7606
|
);
|
|
7396
7607
|
} catch {
|
|
7397
7608
|
}
|
|
7609
|
+
applyAgentRunnerHeapEnv(sideboard.env);
|
|
7398
7610
|
servers.push(sideboard);
|
|
7399
7611
|
}
|
|
7400
7612
|
if (opts.includeBrightsy && isBrightsyConnected()) {
|
|
@@ -7488,19 +7700,19 @@ function writeMcpServersConfig(servers) {
|
|
|
7488
7700
|
...env ? { env } : {}
|
|
7489
7701
|
};
|
|
7490
7702
|
}
|
|
7491
|
-
const dir = (0,
|
|
7492
|
-
const cfgPath = (0,
|
|
7493
|
-
(0,
|
|
7703
|
+
const dir = (0, import_node_fs21.mkdtempSync)((0, import_node_path22.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
|
|
7704
|
+
const cfgPath = (0, import_node_path22.join)(dir, "mcp.json");
|
|
7705
|
+
(0, import_node_fs21.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
|
|
7494
7706
|
return cfgPath;
|
|
7495
7707
|
}
|
|
7496
|
-
var
|
|
7708
|
+
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;
|
|
7497
7709
|
var init_injected_mcp = __esm({
|
|
7498
7710
|
"src/agents/injected-mcp.ts"() {
|
|
7499
7711
|
"use strict";
|
|
7500
|
-
|
|
7712
|
+
import_node_fs21 = require("fs");
|
|
7501
7713
|
import_node_module = require("module");
|
|
7502
7714
|
import_node_os8 = require("os");
|
|
7503
|
-
|
|
7715
|
+
import_node_path22 = require("path");
|
|
7504
7716
|
import_node_url = require("url");
|
|
7505
7717
|
init_run();
|
|
7506
7718
|
init_config();
|
|
@@ -7674,6 +7886,80 @@ function claudeParentToolUseId(obj) {
|
|
|
7674
7886
|
}
|
|
7675
7887
|
return void 0;
|
|
7676
7888
|
}
|
|
7889
|
+
function claudeString(obj, key) {
|
|
7890
|
+
const v = obj[key];
|
|
7891
|
+
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
7892
|
+
}
|
|
7893
|
+
function eventsFromClaudeSystem(obj) {
|
|
7894
|
+
const subtype = claudeString(obj, "subtype") ?? "";
|
|
7895
|
+
const parentId = claudeParentToolUseId(obj);
|
|
7896
|
+
if (subtype === "init") {
|
|
7897
|
+
if (parentId) return null;
|
|
7898
|
+
const sid = claudeString(obj, "session_id");
|
|
7899
|
+
return sid ? { type: "session_id", data: sid } : null;
|
|
7900
|
+
}
|
|
7901
|
+
if (subtype === "task_started") {
|
|
7902
|
+
const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id");
|
|
7903
|
+
if (!id) return null;
|
|
7904
|
+
const description = claudeString(obj, "description");
|
|
7905
|
+
const taskType = claudeString(obj, "task_type");
|
|
7906
|
+
const prompt = claudeString(obj, "prompt");
|
|
7907
|
+
return withEventParentId(
|
|
7908
|
+
{
|
|
7909
|
+
type: "tool_use",
|
|
7910
|
+
id,
|
|
7911
|
+
name: taskType || "Agent",
|
|
7912
|
+
input: {
|
|
7913
|
+
...description ? { description } : {},
|
|
7914
|
+
...prompt ? { prompt } : {},
|
|
7915
|
+
...claudeString(obj, "task_id") ? { task_id: claudeString(obj, "task_id") } : {}
|
|
7916
|
+
}
|
|
7917
|
+
},
|
|
7918
|
+
parentId
|
|
7919
|
+
);
|
|
7920
|
+
}
|
|
7921
|
+
if (subtype === "task_notification") {
|
|
7922
|
+
const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id") ?? parentId;
|
|
7923
|
+
if (!id) return null;
|
|
7924
|
+
const status = claudeString(obj, "status") ?? "working";
|
|
7925
|
+
const tools = typeof obj.tool_uses === "number" ? obj.tool_uses : void 0;
|
|
7926
|
+
const durationMs = typeof obj.duration_ms === "number" ? obj.duration_ms : void 0;
|
|
7927
|
+
const lastTool = claudeString(obj, "last_tool") ?? claudeString(obj, "current_tool") ?? claudeString(obj, "tool");
|
|
7928
|
+
const snapshot = [
|
|
7929
|
+
status,
|
|
7930
|
+
tools != null ? `${tools} tools` : null,
|
|
7931
|
+
durationMs != null ? `${Math.round(durationMs / 1e3)}s` : null,
|
|
7932
|
+
lastTool
|
|
7933
|
+
].filter((bit) => Boolean(bit)).join(" \xB7 ");
|
|
7934
|
+
return [
|
|
7935
|
+
{
|
|
7936
|
+
type: "tool_use",
|
|
7937
|
+
id,
|
|
7938
|
+
name: claudeString(obj, "task_type") || "Agent",
|
|
7939
|
+
input: {
|
|
7940
|
+
live_status: status,
|
|
7941
|
+
...tools != null ? { live_tool_uses: tools } : {},
|
|
7942
|
+
...durationMs != null ? { live_duration_ms: durationMs } : {},
|
|
7943
|
+
...lastTool ? { live_last_tool: lastTool } : {}
|
|
7944
|
+
}
|
|
7945
|
+
},
|
|
7946
|
+
withEventParentId(
|
|
7947
|
+
{ type: "thinking", data: snapshot, replace: true },
|
|
7948
|
+
id
|
|
7949
|
+
)
|
|
7950
|
+
];
|
|
7951
|
+
}
|
|
7952
|
+
if (subtype === "api_retry") {
|
|
7953
|
+
const attempt = obj.attempt;
|
|
7954
|
+
const max = obj.max_retries;
|
|
7955
|
+
const delay = obj.retry_delay_ms;
|
|
7956
|
+
return {
|
|
7957
|
+
type: "thinking",
|
|
7958
|
+
data: `API retry ${attempt ?? "?"}/${max ?? "?"}${typeof delay === "number" ? ` (wait ${delay}ms)` : ""}`
|
|
7959
|
+
};
|
|
7960
|
+
}
|
|
7961
|
+
return null;
|
|
7962
|
+
}
|
|
7677
7963
|
function parseIssuesJson(raw) {
|
|
7678
7964
|
const text4 = raw.trim();
|
|
7679
7965
|
const candidates = [text4];
|
|
@@ -7699,11 +7985,11 @@ function parseIssuesJson(raw) {
|
|
|
7699
7985
|
}
|
|
7700
7986
|
return [];
|
|
7701
7987
|
}
|
|
7702
|
-
var
|
|
7988
|
+
var import_node_fs22, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
|
|
7703
7989
|
var init_claude = __esm({
|
|
7704
7990
|
"src/agents/claude.ts"() {
|
|
7705
7991
|
"use strict";
|
|
7706
|
-
|
|
7992
|
+
import_node_fs22 = require("fs");
|
|
7707
7993
|
init_run();
|
|
7708
7994
|
init_app_settings();
|
|
7709
7995
|
init_claude_mcp();
|
|
@@ -7723,8 +8009,14 @@ var init_claude = __esm({
|
|
|
7723
8009
|
"WebSearch",
|
|
7724
8010
|
// Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
|
|
7725
8011
|
"Task",
|
|
7726
|
-
"Agent"
|
|
8012
|
+
"Agent",
|
|
8013
|
+
"TaskOutput",
|
|
8014
|
+
"TaskStop",
|
|
8015
|
+
"EnterWorktree",
|
|
8016
|
+
"ExitWorktree",
|
|
8017
|
+
"Skill"
|
|
7727
8018
|
];
|
|
8019
|
+
CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
|
|
7728
8020
|
CLAUDE_CHROME_ALLOWED_TOOLS = [
|
|
7729
8021
|
"mcp__claude-in-chrome",
|
|
7730
8022
|
"mcp__claude-in-chrome__*",
|
|
@@ -7736,7 +8028,7 @@ var init_claude = __esm({
|
|
|
7736
8028
|
async detect() {
|
|
7737
8029
|
const claude = resolveClaudeExecutable();
|
|
7738
8030
|
if (claude !== "claude") {
|
|
7739
|
-
if (!(0,
|
|
8031
|
+
if (!(0, import_node_fs22.existsSync)(claude)) {
|
|
7740
8032
|
return {
|
|
7741
8033
|
agent: "claude",
|
|
7742
8034
|
installed: false,
|
|
@@ -7853,7 +8145,12 @@ var init_claude = __esm({
|
|
|
7853
8145
|
stdin: useStdin ? `${promptText}
|
|
7854
8146
|
` : void 0,
|
|
7855
8147
|
// Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
|
|
7856
|
-
|
|
8148
|
+
// Raise the -p background-agent wait so long TaskOutput polls are not
|
|
8149
|
+
// abandoned at Claude Code’s 10-minute default.
|
|
8150
|
+
env: {
|
|
8151
|
+
CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
|
|
8152
|
+
CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS)
|
|
8153
|
+
}
|
|
7857
8154
|
};
|
|
7858
8155
|
},
|
|
7859
8156
|
parseEvent(line) {
|
|
@@ -7861,13 +8158,8 @@ var init_claude = __esm({
|
|
|
7861
8158
|
if (!trimmed) return null;
|
|
7862
8159
|
try {
|
|
7863
8160
|
const obj = JSON.parse(trimmed);
|
|
7864
|
-
if (obj.type === "system"
|
|
7865
|
-
|
|
7866
|
-
if (typeof sid === "string") return { type: "session_id", data: sid };
|
|
7867
|
-
return null;
|
|
7868
|
-
}
|
|
7869
|
-
if (obj.type === "system" && typeof obj.session_id === "string") {
|
|
7870
|
-
return { type: "session_id", data: obj.session_id };
|
|
8161
|
+
if (obj.type === "system") {
|
|
8162
|
+
return eventsFromClaudeSystem(obj);
|
|
7871
8163
|
}
|
|
7872
8164
|
if (obj.type === "assistant" || obj.type === "user") {
|
|
7873
8165
|
const parentId = claudeParentToolUseId(obj);
|
|
@@ -7987,7 +8279,7 @@ async function listCodexModels() {
|
|
|
7987
8279
|
if (codex === "codex") {
|
|
7988
8280
|
const which = await run("which", ["codex"], { reject: false });
|
|
7989
8281
|
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
7990
|
-
} else if (!(0,
|
|
8282
|
+
} else if (!(0, import_node_fs23.existsSync)(codex)) {
|
|
7991
8283
|
return FALLBACK_CODEX_MODELS;
|
|
7992
8284
|
}
|
|
7993
8285
|
const listed = await run(codex, ["debug", "models"], { reject: false });
|
|
@@ -8022,12 +8314,12 @@ function usageFromCodex(usage) {
|
|
|
8022
8314
|
}
|
|
8023
8315
|
function codexConfigHasNetworkAccess() {
|
|
8024
8316
|
const candidates = [
|
|
8025
|
-
(0,
|
|
8026
|
-
(0,
|
|
8317
|
+
(0, import_node_path23.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
|
|
8318
|
+
(0, import_node_path23.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
|
|
8027
8319
|
];
|
|
8028
8320
|
for (const path of candidates) {
|
|
8029
|
-
if (!(0,
|
|
8030
|
-
const text4 = (0,
|
|
8321
|
+
if (!(0, import_node_fs23.existsSync)(path)) continue;
|
|
8322
|
+
const text4 = (0, import_node_fs23.readFileSync)(path, "utf8");
|
|
8031
8323
|
if (/network_access\s*=\s*true/.test(text4)) return true;
|
|
8032
8324
|
}
|
|
8033
8325
|
return false;
|
|
@@ -8059,21 +8351,21 @@ function asRecord2(value) {
|
|
|
8059
8351
|
return void 0;
|
|
8060
8352
|
}
|
|
8061
8353
|
function codexLooksAuthenticated() {
|
|
8062
|
-
const authPath = (0,
|
|
8063
|
-
if (!(0,
|
|
8354
|
+
const authPath = (0, import_node_path23.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
|
|
8355
|
+
if (!(0, import_node_fs23.existsSync)(authPath)) return false;
|
|
8064
8356
|
try {
|
|
8065
|
-
return (0,
|
|
8357
|
+
return (0, import_node_fs23.statSync)(authPath).size > 2;
|
|
8066
8358
|
} catch {
|
|
8067
8359
|
return false;
|
|
8068
8360
|
}
|
|
8069
8361
|
}
|
|
8070
|
-
var
|
|
8362
|
+
var import_node_fs23, import_node_os9, import_node_path23, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
8071
8363
|
var init_codex = __esm({
|
|
8072
8364
|
"src/agents/codex.ts"() {
|
|
8073
8365
|
"use strict";
|
|
8074
|
-
|
|
8366
|
+
import_node_fs23 = require("fs");
|
|
8075
8367
|
import_node_os9 = require("os");
|
|
8076
|
-
|
|
8368
|
+
import_node_path23 = require("path");
|
|
8077
8369
|
init_run();
|
|
8078
8370
|
init_app_settings();
|
|
8079
8371
|
init_global_workspace();
|
|
@@ -8098,7 +8390,7 @@ var init_codex = __esm({
|
|
|
8098
8390
|
async detect() {
|
|
8099
8391
|
const codex = resolveAgentExecutable("codex");
|
|
8100
8392
|
if (codex !== "codex") {
|
|
8101
|
-
if (!(0,
|
|
8393
|
+
if (!(0, import_node_fs23.existsSync)(codex)) {
|
|
8102
8394
|
return {
|
|
8103
8395
|
agent: "codex",
|
|
8104
8396
|
installed: false,
|
|
@@ -8238,13 +8530,22 @@ var init_codex = __esm({
|
|
|
8238
8530
|
const events = [
|
|
8239
8531
|
{ type: "tool_use", id: item.id, name: "Bash", input }
|
|
8240
8532
|
];
|
|
8241
|
-
|
|
8533
|
+
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
8534
|
+
const output = typeof item.aggregated_output === "string" && item.aggregated_output ? item.aggregated_output : void 0;
|
|
8535
|
+
if (finished) {
|
|
8242
8536
|
events.push({
|
|
8243
8537
|
type: "tool_result",
|
|
8244
8538
|
id: item.id,
|
|
8245
|
-
content:
|
|
8539
|
+
content: output,
|
|
8246
8540
|
isError: item.status === "failed"
|
|
8247
8541
|
});
|
|
8542
|
+
} else if (output) {
|
|
8543
|
+
events.push({
|
|
8544
|
+
type: "tool_result",
|
|
8545
|
+
id: item.id,
|
|
8546
|
+
content: output,
|
|
8547
|
+
partial: true
|
|
8548
|
+
});
|
|
8248
8549
|
}
|
|
8249
8550
|
return events.length === 1 ? events[0] : events;
|
|
8250
8551
|
}
|
|
@@ -8287,9 +8588,6 @@ var init_codex = __esm({
|
|
|
8287
8588
|
if (sid && (type === "thread.started" || type === "session" || !type)) {
|
|
8288
8589
|
return { type: "session_id", data: sid };
|
|
8289
8590
|
}
|
|
8290
|
-
if (sid && type.endsWith(".started")) {
|
|
8291
|
-
return { type: "session_id", data: sid };
|
|
8292
|
-
}
|
|
8293
8591
|
if (type === "turn.completed" || type === "turn_completed") {
|
|
8294
8592
|
const usage = usageFromCodex(obj.usage);
|
|
8295
8593
|
return usage ? { type: "usage", data: usage, scope: "turn" } : null;
|
|
@@ -8463,7 +8761,7 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
8463
8761
|
if (msg.type === "tool_call" && msg.call_id && msg.name) {
|
|
8464
8762
|
const normalized = normalizeCursorToolCall(msg.name, msg.args);
|
|
8465
8763
|
if (msg.status === "running") {
|
|
8466
|
-
|
|
8764
|
+
const events = [
|
|
8467
8765
|
{
|
|
8468
8766
|
type: "tool_use",
|
|
8469
8767
|
id: msg.call_id,
|
|
@@ -8471,6 +8769,16 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
8471
8769
|
input: normalized.input
|
|
8472
8770
|
}
|
|
8473
8771
|
];
|
|
8772
|
+
const live = unwrapCursorToolResult(msg.result);
|
|
8773
|
+
if (live) {
|
|
8774
|
+
events.push({
|
|
8775
|
+
type: "tool_result",
|
|
8776
|
+
id: msg.call_id,
|
|
8777
|
+
content: live,
|
|
8778
|
+
partial: true
|
|
8779
|
+
});
|
|
8780
|
+
}
|
|
8781
|
+
return events;
|
|
8474
8782
|
}
|
|
8475
8783
|
if (msg.status === "completed" || msg.status === "error") {
|
|
8476
8784
|
return [
|
|
@@ -8537,21 +8845,21 @@ function platformRipgrepPackage() {
|
|
|
8537
8845
|
}
|
|
8538
8846
|
function usableRipgrepPath(candidate) {
|
|
8539
8847
|
const raw = candidate?.trim();
|
|
8540
|
-
if (!raw || !(0,
|
|
8848
|
+
if (!raw || !(0, import_node_path24.isAbsolute)(raw)) return null;
|
|
8541
8849
|
const readable = nodeReadableScriptPath(raw);
|
|
8542
|
-
if (!(0,
|
|
8850
|
+
if (!(0, import_node_fs24.existsSync)(readable) || isAsarPath(readable)) return null;
|
|
8543
8851
|
return readable;
|
|
8544
8852
|
}
|
|
8545
8853
|
function walkForBundledRipgrep(startFile) {
|
|
8546
8854
|
if (!startFile) return null;
|
|
8547
8855
|
const pkg = platformRipgrepPackage();
|
|
8548
8856
|
const name = rgBinaryName();
|
|
8549
|
-
let dir = (0,
|
|
8550
|
-
const root = (0,
|
|
8857
|
+
let dir = (0, import_node_path24.dirname)((0, import_node_path24.resolve)(startFile));
|
|
8858
|
+
const root = (0, import_node_path24.parse)(dir).root;
|
|
8551
8859
|
while (dir !== root) {
|
|
8552
|
-
const hit = usableRipgrepPath((0,
|
|
8860
|
+
const hit = usableRipgrepPath((0, import_node_path24.join)(dir, "node_modules", pkg, "bin", name));
|
|
8553
8861
|
if (hit) return hit;
|
|
8554
|
-
const next = (0,
|
|
8862
|
+
const next = (0, import_node_path24.dirname)(dir);
|
|
8555
8863
|
if (next === dir) break;
|
|
8556
8864
|
dir = next;
|
|
8557
8865
|
}
|
|
@@ -8561,7 +8869,7 @@ function requireResolveBundledRipgrep(fromFile) {
|
|
|
8561
8869
|
try {
|
|
8562
8870
|
const req = (0, import_node_module2.createRequire)(fromFile);
|
|
8563
8871
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
8564
|
-
return usableRipgrepPath((0,
|
|
8872
|
+
return usableRipgrepPath((0, import_node_path24.join)((0, import_node_path24.dirname)(pkgJson), "bin", rgBinaryName()));
|
|
8565
8873
|
} catch {
|
|
8566
8874
|
return null;
|
|
8567
8875
|
}
|
|
@@ -8583,13 +8891,13 @@ function cursorRipgrepEnv(opts) {
|
|
|
8583
8891
|
const path = resolveCursorRipgrepPath(opts);
|
|
8584
8892
|
return path ? { [RIPGREP_ENV]: path } : {};
|
|
8585
8893
|
}
|
|
8586
|
-
var
|
|
8894
|
+
var import_node_fs24, import_node_module2, import_node_path24, RIPGREP_ENV;
|
|
8587
8895
|
var init_cursor_ripgrep = __esm({
|
|
8588
8896
|
"src/agents/cursor-ripgrep.ts"() {
|
|
8589
8897
|
"use strict";
|
|
8590
|
-
|
|
8898
|
+
import_node_fs24 = require("fs");
|
|
8591
8899
|
import_node_module2 = require("module");
|
|
8592
|
-
|
|
8900
|
+
import_node_path24 = require("path");
|
|
8593
8901
|
init_node_launch();
|
|
8594
8902
|
init_packaged_runtime();
|
|
8595
8903
|
RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
@@ -8635,11 +8943,11 @@ function entryDir() {
|
|
|
8635
8943
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
8636
8944
|
if (cjsDir) return cjsDir;
|
|
8637
8945
|
try {
|
|
8638
|
-
return (0,
|
|
8946
|
+
return (0, import_node_path25.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
8639
8947
|
} catch {
|
|
8640
8948
|
try {
|
|
8641
8949
|
const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
|
|
8642
|
-
return (0,
|
|
8950
|
+
return (0, import_node_path25.dirname)(req.resolve("@sideboard-ai/core"));
|
|
8643
8951
|
} catch {
|
|
8644
8952
|
return process.cwd();
|
|
8645
8953
|
}
|
|
@@ -8650,27 +8958,27 @@ function cursorRunnerPath() {
|
|
|
8650
8958
|
if (packaged) return packaged;
|
|
8651
8959
|
const root = entryDir();
|
|
8652
8960
|
const candidates = [
|
|
8653
|
-
(0,
|
|
8654
|
-
(0,
|
|
8961
|
+
(0, import_node_path25.join)(root, "agents", "cursor-runner.js"),
|
|
8962
|
+
(0, import_node_path25.join)(root, "agents", "cursor-runner.cjs"),
|
|
8655
8963
|
// If somehow resolved from package root instead of dist/
|
|
8656
|
-
(0,
|
|
8657
|
-
(0,
|
|
8964
|
+
(0, import_node_path25.join)(root, "dist", "agents", "cursor-runner.js"),
|
|
8965
|
+
(0, import_node_path25.join)(root, "dist", "agents", "cursor-runner.cjs"),
|
|
8658
8966
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
8659
|
-
(0,
|
|
8660
|
-
(0,
|
|
8967
|
+
(0, import_node_path25.join)(root, "cursor-runner.ts"),
|
|
8968
|
+
(0, import_node_path25.join)(root, "src", "agents", "cursor-runner.ts")
|
|
8661
8969
|
];
|
|
8662
8970
|
for (const candidate of candidates) {
|
|
8663
|
-
if ((0,
|
|
8971
|
+
if ((0, import_node_fs25.existsSync)(candidate)) return candidate;
|
|
8664
8972
|
}
|
|
8665
8973
|
return candidates[0];
|
|
8666
8974
|
}
|
|
8667
|
-
var
|
|
8975
|
+
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;
|
|
8668
8976
|
var init_cursor = __esm({
|
|
8669
8977
|
"src/agents/cursor.ts"() {
|
|
8670
8978
|
"use strict";
|
|
8671
|
-
|
|
8979
|
+
import_node_fs25 = require("fs");
|
|
8672
8980
|
import_node_module3 = require("module");
|
|
8673
|
-
|
|
8981
|
+
import_node_path25 = require("path");
|
|
8674
8982
|
import_node_url2 = require("url");
|
|
8675
8983
|
import_sdk = require("@cursor/sdk");
|
|
8676
8984
|
init_run();
|
|
@@ -8820,7 +9128,7 @@ async function listOpencodeModels() {
|
|
|
8820
9128
|
if (opencode === "opencode") {
|
|
8821
9129
|
const which = await run("which", ["opencode"], { reject: false });
|
|
8822
9130
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
8823
|
-
} else if (!(0,
|
|
9131
|
+
} else if (!(0, import_node_fs26.existsSync)(opencode)) {
|
|
8824
9132
|
return FALLBACK_OPENCODE_MODELS;
|
|
8825
9133
|
}
|
|
8826
9134
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -8850,11 +9158,11 @@ function usageFromOpencode(tokens) {
|
|
|
8850
9158
|
cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
|
|
8851
9159
|
};
|
|
8852
9160
|
}
|
|
8853
|
-
var
|
|
9161
|
+
var import_node_fs26, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
|
|
8854
9162
|
var init_opencode = __esm({
|
|
8855
9163
|
"src/agents/opencode.ts"() {
|
|
8856
9164
|
"use strict";
|
|
8857
|
-
|
|
9165
|
+
import_node_fs26 = require("fs");
|
|
8858
9166
|
init_run();
|
|
8859
9167
|
init_app_settings();
|
|
8860
9168
|
init_global_workspace();
|
|
@@ -8881,7 +9189,7 @@ var init_opencode = __esm({
|
|
|
8881
9189
|
async detect() {
|
|
8882
9190
|
const opencode = resolveAgentExecutable("opencode");
|
|
8883
9191
|
if (opencode !== "opencode") {
|
|
8884
|
-
if (!(0,
|
|
9192
|
+
if (!(0, import_node_fs26.existsSync)(opencode)) {
|
|
8885
9193
|
return {
|
|
8886
9194
|
agent: "opencode",
|
|
8887
9195
|
installed: false,
|
|
@@ -8967,7 +9275,8 @@ var init_opencode = __esm({
|
|
|
8967
9275
|
return { type: "stderr", data: detail };
|
|
8968
9276
|
}
|
|
8969
9277
|
const sid = typeof obj.sessionID === "string" && obj.sessionID || typeof obj.sessionId === "string" && obj.sessionId || typeof obj.session_id === "string" && obj.session_id;
|
|
8970
|
-
|
|
9278
|
+
const childSid = str3(obj.childSessionID) ?? str3(obj.childSessionId) ?? str3(obj.parentID) ?? str3(obj.parentId);
|
|
9279
|
+
if (sid && !childSid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
|
|
8971
9280
|
return { type: "session_id", data: sid };
|
|
8972
9281
|
}
|
|
8973
9282
|
if (obj.type === "text") {
|
|
@@ -8987,13 +9296,16 @@ var init_opencode = __esm({
|
|
|
8987
9296
|
);
|
|
8988
9297
|
const events = [{ type: "tool_use", id, name, input }];
|
|
8989
9298
|
const output = state?.output;
|
|
8990
|
-
|
|
9299
|
+
const finished = state?.status === "completed" || state?.status === "error" || state?.status === "failed";
|
|
9300
|
+
const running = state?.status === "running" || state?.status === "in_progress" || state?.status === "pending";
|
|
9301
|
+
if (output != null || finished) {
|
|
8991
9302
|
const content = typeof output === "string" ? output : output != null ? JSON.stringify(output) : formatUnknownDetail(state?.error) || void 0;
|
|
8992
9303
|
events.push({
|
|
8993
9304
|
type: "tool_result",
|
|
8994
9305
|
id,
|
|
8995
9306
|
content,
|
|
8996
|
-
isError: state?.status === "error" || state?.status === "failed"
|
|
9307
|
+
isError: state?.status === "error" || state?.status === "failed",
|
|
9308
|
+
...running && !finished ? { partial: true } : {}
|
|
8997
9309
|
});
|
|
8998
9310
|
}
|
|
8999
9311
|
return events.length === 1 ? events[0] : events;
|
|
@@ -9028,14 +9340,17 @@ var init_opencode = __esm({
|
|
|
9028
9340
|
withEventParentId({ type: "tool_use", id, name, input }, parentId)
|
|
9029
9341
|
];
|
|
9030
9342
|
const output = state?.output ?? part.output;
|
|
9031
|
-
|
|
9343
|
+
const finished = state?.status === "completed" || state?.status === "error" || state?.status === "failed";
|
|
9344
|
+
const running = state?.status === "running" || state?.status === "in_progress" || state?.status === "pending";
|
|
9345
|
+
if (output != null || finished) {
|
|
9032
9346
|
nested.push(
|
|
9033
9347
|
withEventParentId(
|
|
9034
9348
|
{
|
|
9035
9349
|
type: "tool_result",
|
|
9036
9350
|
id,
|
|
9037
9351
|
content: typeof output === "string" ? output : output != null ? JSON.stringify(output) : void 0,
|
|
9038
|
-
isError: state?.status === "error" || state?.status === "failed"
|
|
9352
|
+
isError: state?.status === "error" || state?.status === "failed",
|
|
9353
|
+
...running && !finished ? { partial: true } : {}
|
|
9039
9354
|
},
|
|
9040
9355
|
parentId
|
|
9041
9356
|
)
|
|
@@ -9698,6 +10013,11 @@ function createAgentStreamCoalescer(emit, opts) {
|
|
|
9698
10013
|
return;
|
|
9699
10014
|
}
|
|
9700
10015
|
if (!event.data) return;
|
|
10016
|
+
if (event.type === "thinking" && event.replace) {
|
|
10017
|
+
flush2();
|
|
10018
|
+
emit(event);
|
|
10019
|
+
return;
|
|
10020
|
+
}
|
|
9701
10021
|
if (pending && pending.type === event.type && parentKey(pending) === parentKey(event)) {
|
|
9702
10022
|
pending.data += event.data;
|
|
9703
10023
|
} else {
|
|
@@ -9754,6 +10074,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
9754
10074
|
}
|
|
9755
10075
|
const env = childEnvWithAppSettings(cmd.env);
|
|
9756
10076
|
applyPromptCacheTtlEnv(thread.agent, env);
|
|
10077
|
+
applyAgentRunnerHeapEnv(env);
|
|
9757
10078
|
try {
|
|
9758
10079
|
if (isOrchestratorThread(thread)) {
|
|
9759
10080
|
mergeAgentGitAuthEnv(env, await resolveAgentGitAuthEnv(env));
|
|
@@ -9861,9 +10182,11 @@ var init_spawn = __esm({
|
|
|
9861
10182
|
init_agents();
|
|
9862
10183
|
init_orchestrator_capable();
|
|
9863
10184
|
init_message_parts();
|
|
10185
|
+
init_node_launch();
|
|
9864
10186
|
init_path();
|
|
9865
10187
|
init_usage();
|
|
9866
10188
|
init_cursor_stream_coalesce();
|
|
10189
|
+
init_node_launch();
|
|
9867
10190
|
}
|
|
9868
10191
|
});
|
|
9869
10192
|
|
|
@@ -10589,21 +10912,21 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
10589
10912
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
10590
10913
|
}
|
|
10591
10914
|
function readTextIfPresent(abs) {
|
|
10592
|
-
if (!(0,
|
|
10915
|
+
if (!(0, import_node_fs27.existsSync)(abs)) return null;
|
|
10593
10916
|
try {
|
|
10594
|
-
const content = (0,
|
|
10917
|
+
const content = (0, import_node_fs27.readFileSync)(abs, "utf8");
|
|
10595
10918
|
return content.trim() ? content : null;
|
|
10596
10919
|
} catch {
|
|
10597
10920
|
return null;
|
|
10598
10921
|
}
|
|
10599
10922
|
}
|
|
10600
10923
|
function readLocalGuidelines(worktreePath) {
|
|
10601
|
-
const localAbs = (0,
|
|
10924
|
+
const localAbs = (0, import_node_path26.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
10602
10925
|
const localContent = readTextIfPresent(localAbs);
|
|
10603
10926
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
10604
10927
|
return { path: REVIEW_REQUEST_PATH, content: localContent };
|
|
10605
10928
|
}
|
|
10606
|
-
const legacyAbs = (0,
|
|
10929
|
+
const legacyAbs = (0, import_node_path26.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
10607
10930
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
10608
10931
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
10609
10932
|
return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
|
|
@@ -10619,20 +10942,20 @@ function skillGuidelines(content, source) {
|
|
|
10619
10942
|
};
|
|
10620
10943
|
}
|
|
10621
10944
|
function ensureReviewSkillFile(worktreePath) {
|
|
10622
|
-
const abs = (0,
|
|
10945
|
+
const abs = (0, import_node_path26.join)(worktreePath, REVIEW_SKILL_PATH);
|
|
10623
10946
|
const existing = readTextIfPresent(abs);
|
|
10624
10947
|
if (existing) {
|
|
10625
10948
|
return { path: REVIEW_SKILL_PATH, content: existing, wrote: false };
|
|
10626
10949
|
}
|
|
10627
|
-
const fromRepo = readTextIfPresent((0,
|
|
10950
|
+
const fromRepo = readTextIfPresent((0, import_node_path26.join)(worktreePath, REPO_REVIEW_PATH));
|
|
10628
10951
|
const fromLocal = readLocalGuidelines(worktreePath)?.content ?? null;
|
|
10629
10952
|
const content = wrapReviewSkillMarkdown(fromRepo ?? fromLocal ?? REVIEW_REQUEST_TEMPLATE);
|
|
10630
|
-
(0,
|
|
10631
|
-
(0,
|
|
10953
|
+
(0, import_node_fs27.mkdirSync)((0, import_node_path26.dirname)(abs), { recursive: true });
|
|
10954
|
+
(0, import_node_fs27.writeFileSync)(abs, content, "utf8");
|
|
10632
10955
|
return { path: REVIEW_SKILL_PATH, content, wrote: true };
|
|
10633
10956
|
}
|
|
10634
10957
|
function resolveReviewGuidelines(worktreePath) {
|
|
10635
|
-
const skillContent = readTextIfPresent((0,
|
|
10958
|
+
const skillContent = readTextIfPresent((0, import_node_path26.join)(worktreePath, REVIEW_SKILL_PATH));
|
|
10636
10959
|
if (skillContent) return skillGuidelines(skillContent, "skill");
|
|
10637
10960
|
const local = readLocalGuidelines(worktreePath);
|
|
10638
10961
|
if (local) {
|
|
@@ -10682,13 +11005,13 @@ async function requestReview(threadRef, send) {
|
|
|
10682
11005
|
const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
|
|
10683
11006
|
return { tab: started, from };
|
|
10684
11007
|
}
|
|
10685
|
-
var import_node_crypto5,
|
|
11008
|
+
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;
|
|
10686
11009
|
var init_request_review = __esm({
|
|
10687
11010
|
"src/review/request-review.ts"() {
|
|
10688
11011
|
"use strict";
|
|
10689
11012
|
import_node_crypto5 = require("crypto");
|
|
10690
|
-
|
|
10691
|
-
|
|
11013
|
+
import_node_fs27 = require("fs");
|
|
11014
|
+
import_node_path26 = require("path");
|
|
10692
11015
|
init_global_workspace();
|
|
10693
11016
|
init_chat_tabs();
|
|
10694
11017
|
init_thread_store();
|
|
@@ -10713,9 +11036,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
10713
11036
|
return new RegExp(`^${escaped}$`).test(name);
|
|
10714
11037
|
}
|
|
10715
11038
|
function readWorktreeInclude(repoPath) {
|
|
10716
|
-
const path = (0,
|
|
10717
|
-
if (!(0,
|
|
10718
|
-
return (0,
|
|
11039
|
+
const path = (0, import_node_path27.join)(repoPath, ".worktreeinclude");
|
|
11040
|
+
if (!(0, import_node_fs28.existsSync)(path)) return [];
|
|
11041
|
+
return (0, import_node_fs28.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
10719
11042
|
}
|
|
10720
11043
|
function resolveFilesToCopy(repoPath) {
|
|
10721
11044
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -10725,10 +11048,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
10725
11048
|
if (settings?.fileIncludeGlobs?.length) {
|
|
10726
11049
|
const matched = [];
|
|
10727
11050
|
try {
|
|
10728
|
-
for (const entry of (0,
|
|
11051
|
+
for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
10729
11052
|
if (!entry.isFile()) continue;
|
|
10730
11053
|
for (const glob of settings.fileIncludeGlobs) {
|
|
10731
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
11054
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path27.basename)(glob), entry.name)) {
|
|
10732
11055
|
matched.push(entry.name);
|
|
10733
11056
|
break;
|
|
10734
11057
|
}
|
|
@@ -10740,7 +11063,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
10740
11063
|
}
|
|
10741
11064
|
const defaults = [];
|
|
10742
11065
|
try {
|
|
10743
|
-
for (const entry of (0,
|
|
11066
|
+
for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
10744
11067
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
10745
11068
|
defaults.push(entry.name);
|
|
10746
11069
|
}
|
|
@@ -10754,11 +11077,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
10754
11077
|
const patterns = resolveFilesToCopy(repoPath);
|
|
10755
11078
|
const copied = [];
|
|
10756
11079
|
for (const rel of patterns) {
|
|
10757
|
-
const src = (0,
|
|
10758
|
-
if (!(0,
|
|
10759
|
-
const dest = (0,
|
|
10760
|
-
(0,
|
|
10761
|
-
(0,
|
|
11080
|
+
const src = (0, import_node_path27.join)(repoPath, rel);
|
|
11081
|
+
if (!(0, import_node_fs28.existsSync)(src)) continue;
|
|
11082
|
+
const dest = (0, import_node_path27.join)(worktreePath, rel);
|
|
11083
|
+
(0, import_node_fs28.mkdirSync)((0, import_node_path27.dirname)(dest), { recursive: true });
|
|
11084
|
+
(0, import_node_fs28.copyFileSync)(src, dest);
|
|
10762
11085
|
copied.push(rel);
|
|
10763
11086
|
}
|
|
10764
11087
|
return copied;
|
|
@@ -10793,7 +11116,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
10793
11116
|
const env = stripNestedElectronEnv({
|
|
10794
11117
|
...baseEnv ?? process.env
|
|
10795
11118
|
});
|
|
10796
|
-
const name = opts.workspaceName ?? (0,
|
|
11119
|
+
const name = opts.workspaceName ?? (0, import_node_path27.basename)(opts.worktreePath);
|
|
10797
11120
|
const ports = opts.ports ?? [];
|
|
10798
11121
|
const primary = ports[0];
|
|
10799
11122
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -11054,13 +11377,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
11054
11377
|
done: handle.done
|
|
11055
11378
|
};
|
|
11056
11379
|
}
|
|
11057
|
-
var
|
|
11380
|
+
var import_node_fs28, import_node_net, import_node_path27, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
11058
11381
|
var init_conductor = __esm({
|
|
11059
11382
|
"src/hook/conductor.ts"() {
|
|
11060
11383
|
"use strict";
|
|
11061
|
-
|
|
11384
|
+
import_node_fs28 = require("fs");
|
|
11062
11385
|
import_node_net = require("net");
|
|
11063
|
-
|
|
11386
|
+
import_node_path27 = require("path");
|
|
11064
11387
|
import_execa4 = require("execa");
|
|
11065
11388
|
import_node_readline3 = require("readline");
|
|
11066
11389
|
init_settings();
|
|
@@ -11086,9 +11409,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11086
11409
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
11087
11410
|
);
|
|
11088
11411
|
const homeRoot = sideboardWorkspacesDir();
|
|
11089
|
-
if ((0,
|
|
11412
|
+
if ((0, import_node_fs29.existsSync)(homeRoot)) {
|
|
11090
11413
|
try {
|
|
11091
|
-
for (const entry of (0,
|
|
11414
|
+
for (const entry of (0, import_node_fs29.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
11092
11415
|
if (!entry.isDirectory()) continue;
|
|
11093
11416
|
void entry;
|
|
11094
11417
|
}
|
|
@@ -11098,7 +11421,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11098
11421
|
const orphans = [];
|
|
11099
11422
|
const seen = /* @__PURE__ */ new Set();
|
|
11100
11423
|
for (const repoPath of repos) {
|
|
11101
|
-
if (!repoPath || !(0,
|
|
11424
|
+
if (!repoPath || !(0, import_node_fs29.existsSync)(repoPath)) continue;
|
|
11102
11425
|
try {
|
|
11103
11426
|
const wts = await listWorktrees(repoPath);
|
|
11104
11427
|
for (const wt of wts) {
|
|
@@ -11109,7 +11432,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11109
11432
|
seen.add(path);
|
|
11110
11433
|
let mtimeMs = 0;
|
|
11111
11434
|
try {
|
|
11112
|
-
mtimeMs = (0,
|
|
11435
|
+
mtimeMs = (0, import_node_fs29.statSync)(path).mtimeMs;
|
|
11113
11436
|
} catch {
|
|
11114
11437
|
mtimeMs = 0;
|
|
11115
11438
|
}
|
|
@@ -11119,16 +11442,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11119
11442
|
}
|
|
11120
11443
|
try {
|
|
11121
11444
|
const root = worktreesRoot(repoPath);
|
|
11122
|
-
if ((0,
|
|
11123
|
-
for (const entry of (0,
|
|
11445
|
+
if ((0, import_node_fs29.existsSync)(root)) {
|
|
11446
|
+
for (const entry of (0, import_node_fs29.readdirSync)(root, { withFileTypes: true })) {
|
|
11124
11447
|
if (!entry.isDirectory()) continue;
|
|
11125
|
-
const path = (0,
|
|
11448
|
+
const path = (0, import_node_path28.join)(root, entry.name).replace(/\/$/, "");
|
|
11126
11449
|
if (known.has(path) || seen.has(path)) continue;
|
|
11127
|
-
if (!(0,
|
|
11450
|
+
if (!(0, import_node_fs29.existsSync)((0, import_node_path28.join)(path, ".git"))) continue;
|
|
11128
11451
|
seen.add(path);
|
|
11129
11452
|
let mtimeMs = 0;
|
|
11130
11453
|
try {
|
|
11131
|
-
mtimeMs = (0,
|
|
11454
|
+
mtimeMs = (0, import_node_fs29.statSync)(path).mtimeMs;
|
|
11132
11455
|
} catch {
|
|
11133
11456
|
mtimeMs = Date.now();
|
|
11134
11457
|
}
|
|
@@ -11180,12 +11503,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
|
|
|
11180
11503
|
const elapsed = Date.now() - Date.parse(last);
|
|
11181
11504
|
return elapsed >= intervalHours * 36e5;
|
|
11182
11505
|
}
|
|
11183
|
-
var
|
|
11506
|
+
var import_node_fs29, import_node_path28;
|
|
11184
11507
|
var init_orphan_cleanup = __esm({
|
|
11185
11508
|
"src/git/orphan-cleanup.ts"() {
|
|
11186
11509
|
"use strict";
|
|
11187
|
-
|
|
11188
|
-
|
|
11510
|
+
import_node_fs29 = require("fs");
|
|
11511
|
+
import_node_path28 = require("path");
|
|
11189
11512
|
init_worktree();
|
|
11190
11513
|
init_thread_store();
|
|
11191
11514
|
init_paths();
|
|
@@ -11292,38 +11615,38 @@ __export(workspaces_exports, {
|
|
|
11292
11615
|
syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
|
|
11293
11616
|
});
|
|
11294
11617
|
function workspacesFile() {
|
|
11295
|
-
return (0,
|
|
11618
|
+
return (0, import_node_path29.join)(appDataDir(), "workspaces.json");
|
|
11296
11619
|
}
|
|
11297
11620
|
function removedWorkspacesFile() {
|
|
11298
|
-
return (0,
|
|
11621
|
+
return (0, import_node_path29.join)(appDataDir(), "removed-workspaces.json");
|
|
11299
11622
|
}
|
|
11300
11623
|
function readAll() {
|
|
11301
11624
|
const path = workspacesFile();
|
|
11302
|
-
if (!(0,
|
|
11625
|
+
if (!(0, import_node_fs30.existsSync)(path)) return [];
|
|
11303
11626
|
try {
|
|
11304
|
-
const raw = JSON.parse((0,
|
|
11627
|
+
const raw = JSON.parse((0, import_node_fs30.readFileSync)(path, "utf8"));
|
|
11305
11628
|
return Array.isArray(raw) ? raw : [];
|
|
11306
11629
|
} catch {
|
|
11307
11630
|
return [];
|
|
11308
11631
|
}
|
|
11309
11632
|
}
|
|
11310
11633
|
function writeAll(list) {
|
|
11311
|
-
(0,
|
|
11312
|
-
(0,
|
|
11634
|
+
(0, import_node_fs30.mkdirSync)(appDataDir(), { recursive: true });
|
|
11635
|
+
(0, import_node_fs30.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
|
|
11313
11636
|
}
|
|
11314
11637
|
function readRemoved() {
|
|
11315
11638
|
const path = removedWorkspacesFile();
|
|
11316
|
-
if (!(0,
|
|
11639
|
+
if (!(0, import_node_fs30.existsSync)(path)) return /* @__PURE__ */ new Set();
|
|
11317
11640
|
try {
|
|
11318
|
-
const raw = JSON.parse((0,
|
|
11641
|
+
const raw = JSON.parse((0, import_node_fs30.readFileSync)(path, "utf8"));
|
|
11319
11642
|
return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
|
|
11320
11643
|
} catch {
|
|
11321
11644
|
return /* @__PURE__ */ new Set();
|
|
11322
11645
|
}
|
|
11323
11646
|
}
|
|
11324
11647
|
function writeRemoved(paths) {
|
|
11325
|
-
(0,
|
|
11326
|
-
(0,
|
|
11648
|
+
(0, import_node_fs30.mkdirSync)(appDataDir(), { recursive: true });
|
|
11649
|
+
(0, import_node_fs30.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
|
|
11327
11650
|
}
|
|
11328
11651
|
function rememberRemoved(repoPath) {
|
|
11329
11652
|
const next = readRemoved();
|
|
@@ -11346,7 +11669,7 @@ function listWorkspaces() {
|
|
|
11346
11669
|
async function addWorkspace(repoPath) {
|
|
11347
11670
|
const root = await resolveRepoRoot(repoPath);
|
|
11348
11671
|
if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
|
|
11349
|
-
if (!(0,
|
|
11672
|
+
if (!(0, import_node_fs30.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
|
|
11350
11673
|
forgetRemoved(root);
|
|
11351
11674
|
await ensureGhPreferOrigin(root);
|
|
11352
11675
|
const current = readAll();
|
|
@@ -11354,7 +11677,7 @@ async function addWorkspace(repoPath) {
|
|
|
11354
11677
|
if (existing) return existing;
|
|
11355
11678
|
const next = {
|
|
11356
11679
|
path: root,
|
|
11357
|
-
name: (0,
|
|
11680
|
+
name: (0, import_node_path29.basename)(root),
|
|
11358
11681
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
11359
11682
|
};
|
|
11360
11683
|
writeAll([...current, next]);
|
|
@@ -11376,10 +11699,10 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
11376
11699
|
if (!path || path === "/" || isGlobalRepoPath(path) || byPath.has(path) || removed.has(path)) {
|
|
11377
11700
|
continue;
|
|
11378
11701
|
}
|
|
11379
|
-
if (!(0,
|
|
11702
|
+
if (!(0, import_node_fs30.existsSync)(path)) continue;
|
|
11380
11703
|
const ws = {
|
|
11381
11704
|
path,
|
|
11382
|
-
name: (0,
|
|
11705
|
+
name: (0, import_node_path29.basename)(path),
|
|
11383
11706
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
11384
11707
|
};
|
|
11385
11708
|
byPath.set(path, ws);
|
|
@@ -11389,12 +11712,12 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
11389
11712
|
if (dirty) writeAll(next);
|
|
11390
11713
|
return next.sort((a, b) => a.name.localeCompare(b.name));
|
|
11391
11714
|
}
|
|
11392
|
-
var
|
|
11715
|
+
var import_node_fs30, import_node_path29;
|
|
11393
11716
|
var init_workspaces2 = __esm({
|
|
11394
11717
|
"src/store/workspaces.ts"() {
|
|
11395
11718
|
"use strict";
|
|
11396
|
-
|
|
11397
|
-
|
|
11719
|
+
import_node_fs30 = require("fs");
|
|
11720
|
+
import_node_path29 = require("path");
|
|
11398
11721
|
init_paths();
|
|
11399
11722
|
init_global_workspace();
|
|
11400
11723
|
init_worktree();
|
|
@@ -11407,12 +11730,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
11407
11730
|
if (!url) throw new Error("Clone URL is required");
|
|
11408
11731
|
let name = opts.name?.trim();
|
|
11409
11732
|
if (!name) {
|
|
11410
|
-
const leaf = (0,
|
|
11733
|
+
const leaf = (0, import_node_path30.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
11411
11734
|
name = leaf || "repo";
|
|
11412
11735
|
}
|
|
11413
11736
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
11414
|
-
const dest = (0,
|
|
11415
|
-
if ((0,
|
|
11737
|
+
const dest = (0, import_node_path30.join)(sideboardReposDir(), name);
|
|
11738
|
+
if ((0, import_node_fs31.existsSync)(dest)) {
|
|
11416
11739
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
11417
11740
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
11418
11741
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -11427,12 +11750,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
11427
11750
|
const workspace = await ensureWorkspace(repoPath);
|
|
11428
11751
|
return { repoPath, workspace };
|
|
11429
11752
|
}
|
|
11430
|
-
var
|
|
11753
|
+
var import_node_fs31, import_node_path30, import_execa6;
|
|
11431
11754
|
var init_clone_repo = __esm({
|
|
11432
11755
|
"src/git/clone-repo.ts"() {
|
|
11433
11756
|
"use strict";
|
|
11434
|
-
|
|
11435
|
-
|
|
11757
|
+
import_node_fs31 = require("fs");
|
|
11758
|
+
import_node_path30 = require("path");
|
|
11436
11759
|
import_execa6 = require("execa");
|
|
11437
11760
|
init_paths();
|
|
11438
11761
|
init_workspaces2();
|
|
@@ -11442,11 +11765,11 @@ var init_clone_repo = __esm({
|
|
|
11442
11765
|
|
|
11443
11766
|
// src/store/desktop-host.ts
|
|
11444
11767
|
function desktopHostPidPath() {
|
|
11445
|
-
return (0,
|
|
11768
|
+
return (0, import_node_path31.join)(appDataDir(), "desktop-host.pid");
|
|
11446
11769
|
}
|
|
11447
11770
|
function readDesktopHostPid() {
|
|
11448
11771
|
try {
|
|
11449
|
-
const pid = Number.parseInt((0,
|
|
11772
|
+
const pid = Number.parseInt((0, import_node_fs32.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
|
|
11450
11773
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
11451
11774
|
return pid;
|
|
11452
11775
|
} catch {
|
|
@@ -11472,12 +11795,12 @@ function thisProcessShouldDrainAgentQueues() {
|
|
|
11472
11795
|
if (isThisProcessDesktopHost()) return true;
|
|
11473
11796
|
return !isDesktopHostAlive();
|
|
11474
11797
|
}
|
|
11475
|
-
var
|
|
11798
|
+
var import_node_fs32, import_node_path31;
|
|
11476
11799
|
var init_desktop_host = __esm({
|
|
11477
11800
|
"src/store/desktop-host.ts"() {
|
|
11478
11801
|
"use strict";
|
|
11479
|
-
|
|
11480
|
-
|
|
11802
|
+
import_node_fs32 = require("fs");
|
|
11803
|
+
import_node_path31 = require("path");
|
|
11481
11804
|
init_paths();
|
|
11482
11805
|
}
|
|
11483
11806
|
});
|
|
@@ -11527,7 +11850,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
11527
11850
|
});
|
|
11528
11851
|
await requireAgent(resolved.agent);
|
|
11529
11852
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
11530
|
-
if (!(0,
|
|
11853
|
+
if (!(0, import_node_fs33.existsSync)(repoPath)) {
|
|
11531
11854
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
11532
11855
|
}
|
|
11533
11856
|
if (input.cowboy) {
|
|
@@ -11650,11 +11973,11 @@ async function listLinearIssues(agent, repoPath) {
|
|
|
11650
11973
|
}
|
|
11651
11974
|
return adapter.listLinearIssues(repoPath);
|
|
11652
11975
|
}
|
|
11653
|
-
var
|
|
11976
|
+
var import_node_fs33;
|
|
11654
11977
|
var init_create = __esm({
|
|
11655
11978
|
"src/threads/create.ts"() {
|
|
11656
11979
|
"use strict";
|
|
11657
|
-
|
|
11980
|
+
import_node_fs33 = require("fs");
|
|
11658
11981
|
init_detect();
|
|
11659
11982
|
init_worktree();
|
|
11660
11983
|
init_conductor();
|
|
@@ -11699,21 +12022,13 @@ function summarizeTurnLive(parts) {
|
|
|
11699
12022
|
(p) => p.type === "tool"
|
|
11700
12023
|
);
|
|
11701
12024
|
const lastTool = tools[tools.length - 1];
|
|
11702
|
-
const
|
|
11703
|
-
const
|
|
12025
|
+
const interesting = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? lastTool;
|
|
12026
|
+
const lastToolLabel = interesting ? interesting.description || toolDescription(interesting.name, interesting.input) || interesting.name : void 0;
|
|
11704
12027
|
const thinking = lastText(parts, "thinking");
|
|
11705
12028
|
const text4 = lastText(parts, "text");
|
|
11706
12029
|
const excerptRaw = thinking || text4;
|
|
11707
12030
|
const excerpt = excerptRaw.length > 280 ? `${excerptRaw.slice(-280)}` : excerptRaw || void 0;
|
|
11708
|
-
|
|
11709
|
-
if (lastToolLabel) {
|
|
11710
|
-
const verb = running ? lastToolLabel : `Finished ${lastToolLabel}`;
|
|
11711
|
-
summary = tools.length > 1 ? `${verb} (${tools.length} tools)` : verb;
|
|
11712
|
-
} else if (thinking) {
|
|
11713
|
-
summary = "Thinking\u2026";
|
|
11714
|
-
} else if (text4) {
|
|
11715
|
-
summary = "Writing reply\u2026";
|
|
11716
|
-
}
|
|
12031
|
+
const summary = liveActivitySummary(parts);
|
|
11717
12032
|
return {
|
|
11718
12033
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11719
12034
|
summary,
|
|
@@ -11763,20 +12078,20 @@ function writeTurnLive(threadId, progress) {
|
|
|
11763
12078
|
const path = threadLivePath(threadId);
|
|
11764
12079
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
11765
12080
|
try {
|
|
11766
|
-
(0,
|
|
11767
|
-
(0,
|
|
12081
|
+
(0, import_node_fs34.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
|
|
12082
|
+
(0, import_node_fs34.renameSync)(tmp, path);
|
|
11768
12083
|
} catch {
|
|
11769
12084
|
try {
|
|
11770
|
-
(0,
|
|
12085
|
+
(0, import_node_fs34.unlinkSync)(tmp);
|
|
11771
12086
|
} catch {
|
|
11772
12087
|
}
|
|
11773
12088
|
}
|
|
11774
12089
|
}
|
|
11775
12090
|
function readTurnLive(threadId) {
|
|
11776
12091
|
const path = threadLivePath(threadId);
|
|
11777
|
-
if (!(0,
|
|
12092
|
+
if (!(0, import_node_fs34.existsSync)(path)) return null;
|
|
11778
12093
|
try {
|
|
11779
|
-
const raw = JSON.parse((0,
|
|
12094
|
+
const raw = JSON.parse((0, import_node_fs34.readFileSync)(path, "utf8"));
|
|
11780
12095
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
11781
12096
|
return raw;
|
|
11782
12097
|
} catch {
|
|
@@ -11788,17 +12103,17 @@ function clearTurnLive(threadId) {
|
|
|
11788
12103
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
11789
12104
|
buffers.delete(threadId);
|
|
11790
12105
|
const path = threadLivePath(threadId);
|
|
11791
|
-
if (!(0,
|
|
12106
|
+
if (!(0, import_node_fs34.existsSync)(path)) return;
|
|
11792
12107
|
try {
|
|
11793
|
-
(0,
|
|
12108
|
+
(0, import_node_fs34.unlinkSync)(path);
|
|
11794
12109
|
} catch {
|
|
11795
12110
|
}
|
|
11796
12111
|
}
|
|
11797
|
-
var
|
|
12112
|
+
var import_node_fs34, buffers, FLUSH_MS, MAX_PARTS;
|
|
11798
12113
|
var init_turn_live = __esm({
|
|
11799
12114
|
"src/store/turn-live.ts"() {
|
|
11800
12115
|
"use strict";
|
|
11801
|
-
|
|
12116
|
+
import_node_fs34 = require("fs");
|
|
11802
12117
|
init_message_parts();
|
|
11803
12118
|
init_paths();
|
|
11804
12119
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -11977,7 +12292,7 @@ var init_quota_failover = __esm({
|
|
|
11977
12292
|
// src/threads/adopt.ts
|
|
11978
12293
|
function thisModuleFile() {
|
|
11979
12294
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
11980
|
-
return cjsFile || process.argv[1] || (0,
|
|
12295
|
+
return cjsFile || process.argv[1] || (0, import_node_path32.join)(process.cwd(), "package.json");
|
|
11981
12296
|
}
|
|
11982
12297
|
function openReadonlySqlite(file) {
|
|
11983
12298
|
const req = (0, import_node_module4.createRequire)(thisModuleFile());
|
|
@@ -11995,21 +12310,21 @@ function mapAgentType(raw) {
|
|
|
11995
12310
|
return null;
|
|
11996
12311
|
}
|
|
11997
12312
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
11998
|
-
if (!workspacePath || !(0,
|
|
12313
|
+
if (!workspacePath || !(0, import_node_fs35.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
11999
12314
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
12000
12315
|
let best = null;
|
|
12001
12316
|
let hashes;
|
|
12002
12317
|
try {
|
|
12003
|
-
hashes = (0,
|
|
12318
|
+
hashes = (0, import_node_fs35.readdirSync)(CURSOR_SDK_STORE);
|
|
12004
12319
|
} catch {
|
|
12005
12320
|
return null;
|
|
12006
12321
|
}
|
|
12007
12322
|
for (const hash of hashes) {
|
|
12008
|
-
const agentsFile = (0,
|
|
12009
|
-
if (!(0,
|
|
12323
|
+
const agentsFile = (0, import_node_path32.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
12324
|
+
if (!(0, import_node_fs35.existsSync)(agentsFile)) continue;
|
|
12010
12325
|
let text4;
|
|
12011
12326
|
try {
|
|
12012
|
-
text4 = (0,
|
|
12327
|
+
text4 = (0, import_node_fs35.readFileSync)(agentsFile, "utf8");
|
|
12013
12328
|
} catch {
|
|
12014
12329
|
continue;
|
|
12015
12330
|
}
|
|
@@ -12033,7 +12348,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
12033
12348
|
return best?.agentId ?? null;
|
|
12034
12349
|
}
|
|
12035
12350
|
async function adoptThread(input) {
|
|
12036
|
-
if (!(0,
|
|
12351
|
+
if (!(0, import_node_fs35.existsSync)(input.worktreePath)) {
|
|
12037
12352
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
12038
12353
|
}
|
|
12039
12354
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -12057,18 +12372,18 @@ async function adoptThread(input) {
|
|
|
12057
12372
|
return thread;
|
|
12058
12373
|
}
|
|
12059
12374
|
function listConductorWorkspaces() {
|
|
12060
|
-
if (!(0,
|
|
12375
|
+
if (!(0, import_node_fs35.existsSync)(CONDUCTOR_DB)) {
|
|
12061
12376
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
12062
12377
|
}
|
|
12063
|
-
const tmp = (0,
|
|
12064
|
-
const snapshot = (0,
|
|
12378
|
+
const tmp = (0, import_node_fs35.mkdtempSync)((0, import_node_path32.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
|
|
12379
|
+
const snapshot = (0, import_node_path32.join)(tmp, "conductor.db");
|
|
12065
12380
|
try {
|
|
12066
|
-
(0,
|
|
12381
|
+
(0, import_node_fs35.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
12067
12382
|
for (const suffix of ["-wal", "-shm"]) {
|
|
12068
12383
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
12069
|
-
if ((0,
|
|
12384
|
+
if ((0, import_node_fs35.existsSync)(src)) {
|
|
12070
12385
|
try {
|
|
12071
|
-
(0,
|
|
12386
|
+
(0, import_node_fs35.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
12072
12387
|
} catch {
|
|
12073
12388
|
}
|
|
12074
12389
|
}
|
|
@@ -12144,22 +12459,22 @@ function listConductorWorkspaces() {
|
|
|
12144
12459
|
db.close();
|
|
12145
12460
|
}
|
|
12146
12461
|
} finally {
|
|
12147
|
-
(0,
|
|
12462
|
+
(0, import_node_fs35.rmSync)(tmp, { recursive: true, force: true });
|
|
12148
12463
|
}
|
|
12149
12464
|
}
|
|
12150
12465
|
function importConductorWorkspace(workspaceId) {
|
|
12151
|
-
if (!(0,
|
|
12466
|
+
if (!(0, import_node_fs35.existsSync)(CONDUCTOR_DB)) {
|
|
12152
12467
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
12153
12468
|
}
|
|
12154
|
-
const tmp = (0,
|
|
12155
|
-
const snapshot = (0,
|
|
12469
|
+
const tmp = (0, import_node_fs35.mkdtempSync)((0, import_node_path32.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
|
|
12470
|
+
const snapshot = (0, import_node_path32.join)(tmp, "conductor.db");
|
|
12156
12471
|
try {
|
|
12157
|
-
(0,
|
|
12472
|
+
(0, import_node_fs35.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
12158
12473
|
for (const suffix of ["-wal", "-shm"]) {
|
|
12159
12474
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
12160
|
-
if ((0,
|
|
12475
|
+
if ((0, import_node_fs35.existsSync)(src)) {
|
|
12161
12476
|
try {
|
|
12162
|
-
(0,
|
|
12477
|
+
(0, import_node_fs35.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
12163
12478
|
} catch {
|
|
12164
12479
|
}
|
|
12165
12480
|
}
|
|
@@ -12177,7 +12492,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
12177
12492
|
).get(workspaceId);
|
|
12178
12493
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
12179
12494
|
const worktreePath = String(row.workspacePath);
|
|
12180
|
-
if (!(0,
|
|
12495
|
+
if (!(0, import_node_fs35.existsSync)(worktreePath)) {
|
|
12181
12496
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
12182
12497
|
}
|
|
12183
12498
|
let sessionId = null;
|
|
@@ -12240,31 +12555,31 @@ function importConductorWorkspace(workspaceId) {
|
|
|
12240
12555
|
db.close();
|
|
12241
12556
|
}
|
|
12242
12557
|
} finally {
|
|
12243
|
-
(0,
|
|
12558
|
+
(0, import_node_fs35.rmSync)(tmp, { recursive: true, force: true });
|
|
12244
12559
|
}
|
|
12245
12560
|
}
|
|
12246
12561
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
12247
12562
|
return importConductorWorkspace(workspaceId);
|
|
12248
12563
|
}
|
|
12249
|
-
var import_node_child_process3,
|
|
12564
|
+
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;
|
|
12250
12565
|
var init_adopt = __esm({
|
|
12251
12566
|
"src/threads/adopt.ts"() {
|
|
12252
12567
|
"use strict";
|
|
12253
12568
|
import_node_child_process3 = require("child_process");
|
|
12254
|
-
|
|
12569
|
+
import_node_fs35 = require("fs");
|
|
12255
12570
|
import_node_os10 = require("os");
|
|
12256
|
-
|
|
12571
|
+
import_node_path32 = require("path");
|
|
12257
12572
|
import_node_module4 = require("module");
|
|
12258
12573
|
init_worktree();
|
|
12259
12574
|
init_thread_store();
|
|
12260
|
-
CONDUCTOR_APP_SUPPORT = (0,
|
|
12575
|
+
CONDUCTOR_APP_SUPPORT = (0, import_node_path32.join)(
|
|
12261
12576
|
process.env.HOME ?? "",
|
|
12262
12577
|
"Library",
|
|
12263
12578
|
"Application Support",
|
|
12264
12579
|
"com.conductor.app"
|
|
12265
12580
|
);
|
|
12266
|
-
CONDUCTOR_DB = (0,
|
|
12267
|
-
CURSOR_SDK_STORE = (0,
|
|
12581
|
+
CONDUCTOR_DB = (0, import_node_path32.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
12582
|
+
CURSOR_SDK_STORE = (0, import_node_path32.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
12268
12583
|
}
|
|
12269
12584
|
});
|
|
12270
12585
|
|
|
@@ -12331,7 +12646,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
12331
12646
|
let createdWorktree = false;
|
|
12332
12647
|
const trees = await listWorktrees(repoPath);
|
|
12333
12648
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
12334
|
-
if (checkedOut?.path && (0,
|
|
12649
|
+
if (checkedOut?.path && (0, import_node_fs36.existsSync)(checkedOut.path)) {
|
|
12335
12650
|
if (input.reuseExistingWorktree !== false) {
|
|
12336
12651
|
worktreePath = checkedOut.path;
|
|
12337
12652
|
} else {
|
|
@@ -12473,7 +12788,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
12473
12788
|
async function createPrStack(input, onSetupLine) {
|
|
12474
12789
|
await requireAgent(input.agent);
|
|
12475
12790
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
12476
|
-
if (!(0,
|
|
12791
|
+
if (!(0, import_node_fs36.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
12477
12792
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
12478
12793
|
const status = await detectGhStack(repoPath);
|
|
12479
12794
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -12540,7 +12855,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
12540
12855
|
}
|
|
12541
12856
|
}
|
|
12542
12857
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
12543
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
12858
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs36.existsSync)(bootstrap.worktreePath)) {
|
|
12544
12859
|
try {
|
|
12545
12860
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
12546
12861
|
deleteBranch: bootstrap.branchName
|
|
@@ -12550,11 +12865,11 @@ async function createPrStack(input, onSetupLine) {
|
|
|
12550
12865
|
}
|
|
12551
12866
|
return { stack, threads, createdThreadIds };
|
|
12552
12867
|
}
|
|
12553
|
-
var
|
|
12868
|
+
var import_node_fs36;
|
|
12554
12869
|
var init_stack_layers = __esm({
|
|
12555
12870
|
"src/threads/stack-layers.ts"() {
|
|
12556
12871
|
"use strict";
|
|
12557
|
-
|
|
12872
|
+
import_node_fs36 = require("fs");
|
|
12558
12873
|
init_detect();
|
|
12559
12874
|
init_run();
|
|
12560
12875
|
init_stack();
|
|
@@ -12567,7 +12882,7 @@ var init_stack_layers = __esm({
|
|
|
12567
12882
|
|
|
12568
12883
|
// src/diff/diff.ts
|
|
12569
12884
|
async function inspectGitWorktree(worktreePath) {
|
|
12570
|
-
if (!worktreePath || !(0,
|
|
12885
|
+
if (!worktreePath || !(0, import_node_fs37.existsSync)(worktreePath)) return "missing_worktree";
|
|
12571
12886
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
12572
12887
|
reject: false
|
|
12573
12888
|
});
|
|
@@ -12575,7 +12890,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
12575
12890
|
return "ok";
|
|
12576
12891
|
}
|
|
12577
12892
|
async function initializeGitRepository(worktreePath) {
|
|
12578
|
-
if (!worktreePath || !(0,
|
|
12893
|
+
if (!worktreePath || !(0, import_node_fs37.existsSync)(worktreePath)) {
|
|
12579
12894
|
throw new Error("Worktree not found");
|
|
12580
12895
|
}
|
|
12581
12896
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -12709,11 +13024,11 @@ new file mode 100644
|
|
|
12709
13024
|
};
|
|
12710
13025
|
}
|
|
12711
13026
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
12712
|
-
const abs = (0,
|
|
13027
|
+
const abs = (0, import_node_path33.join)(worktreePath, path);
|
|
12713
13028
|
try {
|
|
12714
|
-
const st = (0,
|
|
13029
|
+
const st = (0, import_node_fs37.statSync)(abs);
|
|
12715
13030
|
if (st.isFile() && st.size > maxHunk) {
|
|
12716
|
-
const buf = (0,
|
|
13031
|
+
const buf = (0, import_node_fs37.readFileSync)(abs).subarray(0, maxHunk);
|
|
12717
13032
|
return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
|
|
12718
13033
|
}
|
|
12719
13034
|
} catch {
|
|
@@ -13202,8 +13517,8 @@ function isImageRelativePath(relativePath) {
|
|
|
13202
13517
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
13203
13518
|
assertSafeRelativePath(relativePath);
|
|
13204
13519
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
13205
|
-
const abs = (0,
|
|
13206
|
-
const st = (0,
|
|
13520
|
+
const abs = (0, import_node_path33.join)(worktreePath, relativePath);
|
|
13521
|
+
const st = (0, import_node_fs37.statSync)(abs);
|
|
13207
13522
|
if (!st.isFile()) {
|
|
13208
13523
|
throw new Error(`Not a file: ${relativePath}`);
|
|
13209
13524
|
}
|
|
@@ -13212,7 +13527,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
13212
13527
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
13213
13528
|
);
|
|
13214
13529
|
}
|
|
13215
|
-
const buf = (0,
|
|
13530
|
+
const buf = (0, import_node_fs37.readFileSync)(abs);
|
|
13216
13531
|
return {
|
|
13217
13532
|
path: relativePath,
|
|
13218
13533
|
contentBase64: buf.toString("base64"),
|
|
@@ -13222,12 +13537,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
13222
13537
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
13223
13538
|
assertSafeRelativePath(relativePath);
|
|
13224
13539
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
13225
|
-
const abs = (0,
|
|
13226
|
-
const st = (0,
|
|
13540
|
+
const abs = (0, import_node_path33.join)(worktreePath, relativePath);
|
|
13541
|
+
const st = (0, import_node_fs37.statSync)(abs);
|
|
13227
13542
|
if (!st.isFile()) {
|
|
13228
13543
|
throw new Error(`Not a file: ${relativePath}`);
|
|
13229
13544
|
}
|
|
13230
|
-
const buf = (0,
|
|
13545
|
+
const buf = (0, import_node_fs37.readFileSync)(abs);
|
|
13231
13546
|
if (isImageRelativePath(relativePath)) {
|
|
13232
13547
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
13233
13548
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -13270,9 +13585,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
13270
13585
|
}
|
|
13271
13586
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
13272
13587
|
assertSafeRelativePath(relativePath);
|
|
13273
|
-
const abs = (0,
|
|
13274
|
-
(0,
|
|
13275
|
-
(0,
|
|
13588
|
+
const abs = (0, import_node_path33.join)(worktreePath, relativePath);
|
|
13589
|
+
(0, import_node_fs37.mkdirSync)((0, import_node_path33.dirname)(abs), { recursive: true });
|
|
13590
|
+
(0, import_node_fs37.writeFileSync)(abs, content, "utf8");
|
|
13276
13591
|
return { path: relativePath };
|
|
13277
13592
|
}
|
|
13278
13593
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -13289,12 +13604,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
13289
13604
|
truncated: full.files.length > maxFiles
|
|
13290
13605
|
};
|
|
13291
13606
|
}
|
|
13292
|
-
var
|
|
13607
|
+
var import_node_fs37, import_node_path33, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS, DEFAULT_UPLOAD_MAX_BYTES;
|
|
13293
13608
|
var init_diff = __esm({
|
|
13294
13609
|
"src/diff/diff.ts"() {
|
|
13295
13610
|
"use strict";
|
|
13296
|
-
|
|
13297
|
-
|
|
13611
|
+
import_node_fs37 = require("fs");
|
|
13612
|
+
import_node_path33 = require("path");
|
|
13298
13613
|
init_run();
|
|
13299
13614
|
init_worktree();
|
|
13300
13615
|
mergeBaseCache = /* @__PURE__ */ new Map();
|
|
@@ -13462,7 +13777,7 @@ function parseFrontmatter(content) {
|
|
|
13462
13777
|
}
|
|
13463
13778
|
function readSkill(skillMd, source) {
|
|
13464
13779
|
try {
|
|
13465
|
-
const content = (0,
|
|
13780
|
+
const content = (0, import_node_fs38.readFileSync)(skillMd, "utf8");
|
|
13466
13781
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
13467
13782
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
13468
13783
|
const name = fmName || dirName;
|
|
@@ -13481,19 +13796,19 @@ function readSkill(skillMd, source) {
|
|
|
13481
13796
|
}
|
|
13482
13797
|
}
|
|
13483
13798
|
function scanSkillsDir(dir, source, out) {
|
|
13484
|
-
if (!(0,
|
|
13799
|
+
if (!(0, import_node_fs38.existsSync)(dir)) return;
|
|
13485
13800
|
let entries;
|
|
13486
13801
|
try {
|
|
13487
|
-
entries = (0,
|
|
13802
|
+
entries = (0, import_node_fs38.readdirSync)(dir);
|
|
13488
13803
|
} catch {
|
|
13489
13804
|
return;
|
|
13490
13805
|
}
|
|
13491
13806
|
for (const entry of entries) {
|
|
13492
13807
|
if (entry.startsWith(".")) continue;
|
|
13493
|
-
const skillMd = (0,
|
|
13494
|
-
if (!(0,
|
|
13808
|
+
const skillMd = (0, import_node_path34.join)(dir, entry, "SKILL.md");
|
|
13809
|
+
if (!(0, import_node_fs38.existsSync)(skillMd)) continue;
|
|
13495
13810
|
try {
|
|
13496
|
-
if (!(0,
|
|
13811
|
+
if (!(0, import_node_fs38.statSync)(skillMd).isFile()) continue;
|
|
13497
13812
|
} catch {
|
|
13498
13813
|
continue;
|
|
13499
13814
|
}
|
|
@@ -13502,24 +13817,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
13502
13817
|
}
|
|
13503
13818
|
}
|
|
13504
13819
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
13505
|
-
if (!(0,
|
|
13820
|
+
if (!(0, import_node_fs38.existsSync)(pluginsRoot)) return;
|
|
13506
13821
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
13507
13822
|
if (depth > 7) return;
|
|
13508
13823
|
let entries;
|
|
13509
13824
|
try {
|
|
13510
|
-
entries = (0,
|
|
13825
|
+
entries = (0, import_node_fs38.readdirSync)(dir);
|
|
13511
13826
|
} catch {
|
|
13512
13827
|
return;
|
|
13513
13828
|
}
|
|
13514
13829
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
13515
|
-
const skill = readSkill((0,
|
|
13830
|
+
const skill = readSkill((0, import_node_path34.join)(dir, "SKILL.md"), "cli");
|
|
13516
13831
|
if (skill) out.push(skill);
|
|
13517
13832
|
}
|
|
13518
13833
|
for (const entry of entries) {
|
|
13519
13834
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
13520
|
-
const full = (0,
|
|
13835
|
+
const full = (0, import_node_path34.join)(dir, entry);
|
|
13521
13836
|
try {
|
|
13522
|
-
if (!(0,
|
|
13837
|
+
if (!(0, import_node_fs38.statSync)(full).isDirectory()) continue;
|
|
13523
13838
|
} catch {
|
|
13524
13839
|
continue;
|
|
13525
13840
|
}
|
|
@@ -13537,17 +13852,17 @@ function discoverSkills(worktreePath) {
|
|
|
13537
13852
|
const home = (0, import_node_os11.homedir)();
|
|
13538
13853
|
const collected = [];
|
|
13539
13854
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
13540
|
-
scanSkillsDir((0,
|
|
13855
|
+
scanSkillsDir((0, import_node_path34.join)(worktreePath, rel), "workspace", collected);
|
|
13541
13856
|
}
|
|
13542
13857
|
for (const abs of [
|
|
13543
|
-
(0,
|
|
13544
|
-
(0,
|
|
13545
|
-
(0,
|
|
13546
|
-
(0,
|
|
13858
|
+
(0, import_node_path34.join)(home, ".claude/skills"),
|
|
13859
|
+
(0, import_node_path34.join)(home, ".cursor/skills"),
|
|
13860
|
+
(0, import_node_path34.join)(home, ".sideboard/skills"),
|
|
13861
|
+
(0, import_node_path34.join)(home, ".brightsy/skills")
|
|
13547
13862
|
]) {
|
|
13548
13863
|
scanSkillsDir(abs, "user", collected);
|
|
13549
13864
|
}
|
|
13550
|
-
scanClaudePluginSkills((0,
|
|
13865
|
+
scanClaudePluginSkills((0, import_node_path34.join)(home, ".claude/plugins"), collected);
|
|
13551
13866
|
const rank = { workspace: 0, user: 1, cli: 2 };
|
|
13552
13867
|
const byCommand = /* @__PURE__ */ new Map();
|
|
13553
13868
|
for (const skill of collected) {
|
|
@@ -13559,7 +13874,7 @@ function discoverSkills(worktreePath) {
|
|
|
13559
13874
|
return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
|
|
13560
13875
|
}
|
|
13561
13876
|
function readSkillBody(skillPath, maxChars = 12e3) {
|
|
13562
|
-
const raw = (0,
|
|
13877
|
+
const raw = (0, import_node_fs38.readFileSync)(skillPath, "utf8");
|
|
13563
13878
|
if (raw.startsWith("---")) {
|
|
13564
13879
|
const end = raw.indexOf("\n---", 3);
|
|
13565
13880
|
if (end >= 0) {
|
|
@@ -13573,13 +13888,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
13573
13888
|
|
|
13574
13889
|
\u2026(truncated)` : raw;
|
|
13575
13890
|
}
|
|
13576
|
-
var
|
|
13891
|
+
var import_node_fs38, import_node_os11, import_node_path34;
|
|
13577
13892
|
var init_discover = __esm({
|
|
13578
13893
|
"src/skills/discover.ts"() {
|
|
13579
13894
|
"use strict";
|
|
13580
|
-
|
|
13895
|
+
import_node_fs38 = require("fs");
|
|
13581
13896
|
import_node_os11 = require("os");
|
|
13582
|
-
|
|
13897
|
+
import_node_path34 = require("path");
|
|
13583
13898
|
}
|
|
13584
13899
|
});
|
|
13585
13900
|
|
|
@@ -13670,7 +13985,7 @@ var init_expand = __esm({
|
|
|
13670
13985
|
|
|
13671
13986
|
// src/composer/stage-files.ts
|
|
13672
13987
|
function fileExtension(filePath) {
|
|
13673
|
-
const base = (0,
|
|
13988
|
+
const base = (0, import_node_path35.basename)(filePath).toLowerCase();
|
|
13674
13989
|
return base.includes(".") ? base.split(".").pop() || "" : "";
|
|
13675
13990
|
}
|
|
13676
13991
|
function isImageFilePath(filePath) {
|
|
@@ -13680,22 +13995,22 @@ function imageMimeType(filePath) {
|
|
|
13680
13995
|
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
13681
13996
|
}
|
|
13682
13997
|
function ensureAttachmentsDir(worktreePath) {
|
|
13683
|
-
const dir = (0,
|
|
13684
|
-
(0,
|
|
13685
|
-
const gi = (0,
|
|
13686
|
-
if (!(0,
|
|
13687
|
-
(0,
|
|
13998
|
+
const dir = (0, import_node_path35.join)(worktreePath, ATTACHMENTS_DIR);
|
|
13999
|
+
(0, import_node_fs39.mkdirSync)(dir, { recursive: true });
|
|
14000
|
+
const gi = (0, import_node_path35.join)(dir, ".gitignore");
|
|
14001
|
+
if (!(0, import_node_fs39.existsSync)(gi)) {
|
|
14002
|
+
(0, import_node_fs39.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
|
|
13688
14003
|
}
|
|
13689
14004
|
return dir;
|
|
13690
14005
|
}
|
|
13691
14006
|
function uniqueAttachmentName(dir, originalName) {
|
|
13692
14007
|
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
13693
|
-
if (!(0,
|
|
13694
|
-
const ext = (0,
|
|
14008
|
+
if (!(0, import_node_fs39.existsSync)((0, import_node_path35.join)(dir, safe))) return safe;
|
|
14009
|
+
const ext = (0, import_node_path35.extname)(safe);
|
|
13695
14010
|
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
13696
14011
|
for (let i = 1; i < 1e4; i++) {
|
|
13697
14012
|
const candidate = `${stem}-${i}${ext}`;
|
|
13698
|
-
if (!(0,
|
|
14013
|
+
if (!(0, import_node_fs39.existsSync)((0, import_node_path35.join)(dir, candidate))) return candidate;
|
|
13699
14014
|
}
|
|
13700
14015
|
return `${stem}-${(0, import_node_crypto7.randomUUID)()}${ext}`;
|
|
13701
14016
|
}
|
|
@@ -13751,15 +14066,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
|
13751
14066
|
const dir = ensureAttachmentsDir(worktreePath);
|
|
13752
14067
|
const out = [];
|
|
13753
14068
|
for (const abs of absolutePaths) {
|
|
13754
|
-
const originalName = (0,
|
|
14069
|
+
const originalName = (0, import_node_path35.basename)(abs);
|
|
13755
14070
|
try {
|
|
13756
|
-
const st = (0,
|
|
14071
|
+
const st = (0, import_node_fs39.statSync)(abs);
|
|
13757
14072
|
if (!st.isFile()) continue;
|
|
13758
14073
|
const name = uniqueAttachmentName(dir, originalName);
|
|
13759
|
-
const destAbs = (0,
|
|
13760
|
-
(0,
|
|
14074
|
+
const destAbs = (0, import_node_path35.join)(dir, name);
|
|
14075
|
+
(0, import_node_fs39.copyFileSync)(abs, destAbs);
|
|
13761
14076
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
13762
|
-
const buf = (0,
|
|
14077
|
+
const buf = (0, import_node_fs39.readFileSync)(destAbs);
|
|
13763
14078
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
13764
14079
|
} catch (err) {
|
|
13765
14080
|
out.push({
|
|
@@ -13781,8 +14096,8 @@ function stageBuffersAsAttachments(worktreePath, buffers2) {
|
|
|
13781
14096
|
try {
|
|
13782
14097
|
const buf = Buffer.from(item.dataBase64, "base64");
|
|
13783
14098
|
const name = uniqueAttachmentName(dir, originalName);
|
|
13784
|
-
const destAbs = (0,
|
|
13785
|
-
(0,
|
|
14099
|
+
const destAbs = (0, import_node_path35.join)(dir, name);
|
|
14100
|
+
(0, import_node_fs39.writeFileSync)(destAbs, buf);
|
|
13786
14101
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
13787
14102
|
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
13788
14103
|
} catch (err) {
|
|
@@ -13802,18 +14117,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
13802
14117
|
if (!rel || rel.includes("..") || rel.startsWith("/")) {
|
|
13803
14118
|
out.push({
|
|
13804
14119
|
id: (0, import_node_crypto7.randomUUID)(),
|
|
13805
|
-
name: (0,
|
|
14120
|
+
name: (0, import_node_path35.basename)(rel) || "file",
|
|
13806
14121
|
kind: "file",
|
|
13807
14122
|
content: `(invalid path: ${rel})`
|
|
13808
14123
|
});
|
|
13809
14124
|
continue;
|
|
13810
14125
|
}
|
|
13811
|
-
const name = (0,
|
|
14126
|
+
const name = (0, import_node_path35.basename)(rel);
|
|
13812
14127
|
try {
|
|
13813
|
-
const abs = (0,
|
|
13814
|
-
const st = (0,
|
|
14128
|
+
const abs = (0, import_node_path35.join)(worktreePath, rel);
|
|
14129
|
+
const st = (0, import_node_fs39.statSync)(abs);
|
|
13815
14130
|
if (!st.isFile()) continue;
|
|
13816
|
-
const buf = (0,
|
|
14131
|
+
const buf = (0, import_node_fs39.readFileSync)(abs);
|
|
13817
14132
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
13818
14133
|
} catch (err) {
|
|
13819
14134
|
out.push({
|
|
@@ -13826,12 +14141,12 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
13826
14141
|
}
|
|
13827
14142
|
return out;
|
|
13828
14143
|
}
|
|
13829
|
-
var
|
|
14144
|
+
var import_node_fs39, import_node_path35, import_node_crypto7, IMAGE_EXTENSIONS2, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES;
|
|
13830
14145
|
var init_stage_files = __esm({
|
|
13831
14146
|
"src/composer/stage-files.ts"() {
|
|
13832
14147
|
"use strict";
|
|
13833
|
-
|
|
13834
|
-
|
|
14148
|
+
import_node_fs39 = require("fs");
|
|
14149
|
+
import_node_path35 = require("path");
|
|
13835
14150
|
import_node_crypto7 = require("crypto");
|
|
13836
14151
|
init_workspace_scratch();
|
|
13837
14152
|
IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
@@ -13978,14 +14293,15 @@ function formatArtifactDirective() {
|
|
|
13978
14293
|
return [
|
|
13979
14294
|
"Sideboard side column (desktop UI):",
|
|
13980
14295
|
"claude.ai\u2019s \u201CArtifact\u201D tool does NOT exist in Claude Code. That is expected.",
|
|
14296
|
+
"Do not unprompted-duplicate a payload. Chat markdown (including tables) already renders in the transcript \u2014 do not also call present_schema with those same rows just to display them. If the user asks for an editable / interactive table, call present_schema even if markdown already showed the data. Do not also call present_artifact for a document you already fenced in chat.",
|
|
13981
14297
|
"Documents (HTML/SVG/markdown):",
|
|
13982
14298
|
"1) Emit a fenced code block tagged `html` (preferred), `svg`, or `markdown` with the FULL document \u2014 Sideboard opens a side column. Example:",
|
|
13983
14299
|
"```html",
|
|
13984
14300
|
"<!DOCTYPE html><html><head><title>Demo</title></head><body><h1>Hi</h1></body></html>",
|
|
13985
14301
|
"```",
|
|
13986
|
-
"2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content.",
|
|
14302
|
+
"2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content \u2014 not both a fence and this tool for the same body.",
|
|
13987
14303
|
"CMS / JSON Schema forms & tables (Brightsy or any schema+schemaUi source):",
|
|
13988
|
-
"3) Call Sideboard MCP `present_schema`
|
|
14304
|
+
"3) Call Sideboard MCP `present_schema` when the user needs to filter, edit, publish, or persist rows \u2014 including after you already showed a markdown table, if they then ask for an editable table. If they only need to read the data, a markdown table is enough. When you do call it, pass title, mode (table|form), and either:",
|
|
13989
14305
|
" - datasource=brightsy + resource_id (record type UUID) after fetching types via Brightsy MCP, or",
|
|
13990
14306
|
" - datasource=inline + resource: { id, title, schema, schemaUi } and optional records/record.",
|
|
13991
14307
|
"Files / media browser (CMS file manager column):",
|
|
@@ -13994,18 +14310,18 @@ function formatArtifactDirective() {
|
|
|
13994
14310
|
"Multiple-choice questions:",
|
|
13995
14311
|
"5) Call Sideboard MCP `ask_user` only when work is blocked on choosing among a few concrete options (approach forks, which API, auth vs cookies). First write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it). Include a description on every option. After calling, stop and wait for their next message with answers. If you are asking a real multiple-choice, use ask_user rather than chat bullets so Sideboard shows the composer picker.",
|
|
13996
14312
|
"Do not call ask_user for greetings, check-ins, \u201Chello\u201D, open-ended how-can-I-help, or to invent a menu of possible next tasks \u2014 reply in chat. If one option is the obvious default, proceed without asking.",
|
|
13997
|
-
"Never say artifacts, CMS UI, or the Files column are unavailable.
|
|
14313
|
+
"Never say artifacts, CMS UI, or the Files column are unavailable. present_schema is for interactive list/edit/publish (use it when they ask to edit, even if chat already had a markdown table); present_files for storage UI; html fences for standalone pages; ask_user only for those blocked predefined-option questions."
|
|
13998
14314
|
].join("\n");
|
|
13999
14315
|
}
|
|
14000
14316
|
function formatUiReminder() {
|
|
14001
|
-
return "Sideboard UI: html fence or present_artifact
|
|
14317
|
+
return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. 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.";
|
|
14002
14318
|
}
|
|
14003
|
-
var
|
|
14319
|
+
var import_node_fs40, import_node_path36;
|
|
14004
14320
|
var init_instructions = __esm({
|
|
14005
14321
|
"src/agents/instructions.ts"() {
|
|
14006
14322
|
"use strict";
|
|
14007
|
-
|
|
14008
|
-
|
|
14323
|
+
import_node_fs40 = require("fs");
|
|
14324
|
+
import_node_path36 = require("path");
|
|
14009
14325
|
init_git_auth_mode();
|
|
14010
14326
|
init_worktree_labels();
|
|
14011
14327
|
}
|
|
@@ -14081,40 +14397,40 @@ __export(plan_file_exports, {
|
|
|
14081
14397
|
writePlanFile: () => writePlanFile
|
|
14082
14398
|
});
|
|
14083
14399
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
14084
|
-
const gitignoreAbs = (0,
|
|
14085
|
-
if ((0,
|
|
14086
|
-
(0,
|
|
14087
|
-
(0,
|
|
14400
|
+
const gitignoreAbs = (0, import_node_path37.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
14401
|
+
if ((0, import_node_fs41.existsSync)(gitignoreAbs)) return;
|
|
14402
|
+
(0, import_node_fs41.mkdirSync)((0, import_node_path37.dirname)(gitignoreAbs), { recursive: true });
|
|
14403
|
+
(0, import_node_fs41.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
14088
14404
|
}
|
|
14089
14405
|
function planFileAbs(worktreePath) {
|
|
14090
|
-
return (0,
|
|
14406
|
+
return (0, import_node_path37.join)(worktreePath, PLAN_FILE_REL);
|
|
14091
14407
|
}
|
|
14092
14408
|
function readTextIfPresent2(abs) {
|
|
14093
|
-
if (!(0,
|
|
14409
|
+
if (!(0, import_node_fs41.existsSync)(abs)) return null;
|
|
14094
14410
|
try {
|
|
14095
|
-
const content = (0,
|
|
14411
|
+
const content = (0, import_node_fs41.readFileSync)(abs, "utf8");
|
|
14096
14412
|
return content.trim() ? content : null;
|
|
14097
14413
|
} catch {
|
|
14098
14414
|
return null;
|
|
14099
14415
|
}
|
|
14100
14416
|
}
|
|
14101
14417
|
function readPlanFile(worktreePath) {
|
|
14102
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
14418
|
+
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));
|
|
14103
14419
|
}
|
|
14104
14420
|
function writePlanFile(worktreePath, content) {
|
|
14105
14421
|
ensureAttachmentsGitignore(worktreePath);
|
|
14106
14422
|
const abs = planFileAbs(worktreePath);
|
|
14107
|
-
(0,
|
|
14423
|
+
(0, import_node_fs41.mkdirSync)((0, import_node_path37.dirname)(abs), { recursive: true });
|
|
14108
14424
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
14109
|
-
(0,
|
|
14425
|
+
(0, import_node_fs41.writeFileSync)(abs, body, "utf8");
|
|
14110
14426
|
return PLAN_FILE_REL;
|
|
14111
14427
|
}
|
|
14112
|
-
var
|
|
14428
|
+
var import_node_fs41, import_node_path37;
|
|
14113
14429
|
var init_plan_file = __esm({
|
|
14114
14430
|
"src/plan/plan-file.ts"() {
|
|
14115
14431
|
"use strict";
|
|
14116
|
-
|
|
14117
|
-
|
|
14432
|
+
import_node_fs41 = require("fs");
|
|
14433
|
+
import_node_path37 = require("path");
|
|
14118
14434
|
init_workspace_scratch();
|
|
14119
14435
|
init_plan_present();
|
|
14120
14436
|
init_plan_present();
|
|
@@ -14174,7 +14490,7 @@ function setCaffeinateHoldHooks(next) {
|
|
|
14174
14490
|
hooks = next;
|
|
14175
14491
|
}
|
|
14176
14492
|
function caffeinateHoldPath() {
|
|
14177
|
-
return (0,
|
|
14493
|
+
return (0, import_node_path38.join)(appDataDir(), "caffeinate-hold.json");
|
|
14178
14494
|
}
|
|
14179
14495
|
function processAlive(pid) {
|
|
14180
14496
|
if (hooks.processAlive) return hooks.processAlive(pid);
|
|
@@ -14208,9 +14524,9 @@ function uniqueIds(ids) {
|
|
|
14208
14524
|
}
|
|
14209
14525
|
function readHold() {
|
|
14210
14526
|
const path = caffeinateHoldPath();
|
|
14211
|
-
if (!(0,
|
|
14527
|
+
if (!(0, import_node_fs42.existsSync)(path)) return null;
|
|
14212
14528
|
try {
|
|
14213
|
-
const parsed = JSON.parse((0,
|
|
14529
|
+
const parsed = JSON.parse((0, import_node_fs42.readFileSync)(path, "utf8"));
|
|
14214
14530
|
if (typeof parsed?.pid === "number" && parsed.pid > 0) {
|
|
14215
14531
|
return {
|
|
14216
14532
|
pid: parsed.pid,
|
|
@@ -14232,7 +14548,7 @@ function writeHold(pid, threadIds) {
|
|
|
14232
14548
|
}
|
|
14233
14549
|
function clearHold() {
|
|
14234
14550
|
try {
|
|
14235
|
-
(0,
|
|
14551
|
+
(0, import_node_fs42.unlinkSync)(caffeinateHoldPath());
|
|
14236
14552
|
} catch {
|
|
14237
14553
|
}
|
|
14238
14554
|
}
|
|
@@ -14317,13 +14633,13 @@ function releaseCaffeinateHoldForThread(threadId) {
|
|
|
14317
14633
|
}
|
|
14318
14634
|
return setCaffeinateHold(false, { threadId: id });
|
|
14319
14635
|
}
|
|
14320
|
-
var import_node_child_process4,
|
|
14636
|
+
var import_node_child_process4, import_node_fs42, import_node_path38, hooks;
|
|
14321
14637
|
var init_caffeinate_hold = __esm({
|
|
14322
14638
|
"src/store/caffeinate-hold.ts"() {
|
|
14323
14639
|
"use strict";
|
|
14324
14640
|
import_node_child_process4 = require("child_process");
|
|
14325
|
-
|
|
14326
|
-
|
|
14641
|
+
import_node_fs42 = require("fs");
|
|
14642
|
+
import_node_path38 = require("path");
|
|
14327
14643
|
init_paths();
|
|
14328
14644
|
init_private_file();
|
|
14329
14645
|
hooks = {};
|
|
@@ -14332,7 +14648,7 @@ var init_caffeinate_hold = __esm({
|
|
|
14332
14648
|
|
|
14333
14649
|
// src/store/schedules.ts
|
|
14334
14650
|
function schedulesPath() {
|
|
14335
|
-
return (0,
|
|
14651
|
+
return (0, import_node_path39.join)(appDataDir(), "schedules.json");
|
|
14336
14652
|
}
|
|
14337
14653
|
function parseDurationMs(every) {
|
|
14338
14654
|
const m = every.trim().match(DURATION_RE);
|
|
@@ -14432,9 +14748,9 @@ function normalizeTask(raw) {
|
|
|
14432
14748
|
}
|
|
14433
14749
|
function readAll2() {
|
|
14434
14750
|
const path = schedulesPath();
|
|
14435
|
-
if (!(0,
|
|
14751
|
+
if (!(0, import_node_fs43.existsSync)(path)) return [];
|
|
14436
14752
|
try {
|
|
14437
|
-
const parsed = JSON.parse((0,
|
|
14753
|
+
const parsed = JSON.parse((0, import_node_fs43.readFileSync)(path, "utf8"));
|
|
14438
14754
|
if (!Array.isArray(parsed)) return [];
|
|
14439
14755
|
return parsed.map((row) => {
|
|
14440
14756
|
try {
|
|
@@ -14546,13 +14862,13 @@ function recordScheduleRun(id, result) {
|
|
|
14546
14862
|
writeAll2(rows);
|
|
14547
14863
|
return next;
|
|
14548
14864
|
}
|
|
14549
|
-
var import_node_crypto8,
|
|
14865
|
+
var import_node_crypto8, import_node_fs43, import_node_path39, import_croner, DURATION_RE, UNIT_MS;
|
|
14550
14866
|
var init_schedules = __esm({
|
|
14551
14867
|
"src/store/schedules.ts"() {
|
|
14552
14868
|
"use strict";
|
|
14553
14869
|
import_node_crypto8 = require("crypto");
|
|
14554
|
-
|
|
14555
|
-
|
|
14870
|
+
import_node_fs43 = require("fs");
|
|
14871
|
+
import_node_path39 = require("path");
|
|
14556
14872
|
import_croner = require("croner");
|
|
14557
14873
|
init_orchestrator_capable();
|
|
14558
14874
|
init_paths();
|
|
@@ -14700,10 +15016,10 @@ __export(cursor_recover_exports, {
|
|
|
14700
15016
|
function recoverFinishedCursorRun(opts) {
|
|
14701
15017
|
const agentId = opts.agentId.trim();
|
|
14702
15018
|
if (!agentId) return null;
|
|
14703
|
-
const runsPath = (0,
|
|
14704
|
-
if (!(0,
|
|
15019
|
+
const runsPath = (0, import_node_path40.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
|
|
15020
|
+
if (!(0, import_node_fs44.existsSync)(runsPath)) return null;
|
|
14705
15021
|
try {
|
|
14706
|
-
const lines = (0,
|
|
15022
|
+
const lines = (0, import_node_fs44.readFileSync)(runsPath, "utf8").split("\n");
|
|
14707
15023
|
let best = null;
|
|
14708
15024
|
for (const line of lines) {
|
|
14709
15025
|
const trimmed = line.trim();
|
|
@@ -14729,12 +15045,12 @@ function recoverFinishedCursorRun(opts) {
|
|
|
14729
15045
|
return null;
|
|
14730
15046
|
}
|
|
14731
15047
|
}
|
|
14732
|
-
var
|
|
15048
|
+
var import_node_fs44, import_node_path40;
|
|
14733
15049
|
var init_cursor_recover = __esm({
|
|
14734
15050
|
"src/agents/cursor-recover.ts"() {
|
|
14735
15051
|
"use strict";
|
|
14736
|
-
|
|
14737
|
-
|
|
15052
|
+
import_node_fs44 = require("fs");
|
|
15053
|
+
import_node_path40 = require("path");
|
|
14738
15054
|
init_paths();
|
|
14739
15055
|
}
|
|
14740
15056
|
});
|
|
@@ -14865,14 +15181,16 @@ async function startOrchestration(opts) {
|
|
|
14865
15181
|
}
|
|
14866
15182
|
return updated;
|
|
14867
15183
|
}
|
|
14868
|
-
var import_node_events,
|
|
15184
|
+
var import_node_events, import_node_fs45, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
|
|
14869
15185
|
var init_orchestrator = __esm({
|
|
14870
15186
|
"src/orchestrator/orchestrator.ts"() {
|
|
14871
15187
|
"use strict";
|
|
14872
15188
|
import_node_events = require("events");
|
|
14873
15189
|
init_outbound_watch();
|
|
14874
|
-
|
|
15190
|
+
import_node_fs45 = require("fs");
|
|
14875
15191
|
init_error_detail();
|
|
15192
|
+
init_run();
|
|
15193
|
+
init_stale_lock();
|
|
14876
15194
|
init_spawn();
|
|
14877
15195
|
init_agents();
|
|
14878
15196
|
init_worktree();
|
|
@@ -14988,7 +15306,7 @@ var init_orchestrator = __esm({
|
|
|
14988
15306
|
}
|
|
14989
15307
|
continue;
|
|
14990
15308
|
}
|
|
14991
|
-
if (!(0,
|
|
15309
|
+
if (!(0, import_node_fs45.existsSync)(thread.worktreePath)) {
|
|
14992
15310
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
14993
15311
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
14994
15312
|
continue;
|
|
@@ -15581,7 +15899,15 @@ var init_orchestrator = __esm({
|
|
|
15581
15899
|
hasSession: Boolean(this.requireThread(threadId).sessionId)
|
|
15582
15900
|
})) {
|
|
15583
15901
|
updateThread(threadId, { sessionId: null });
|
|
15584
|
-
|
|
15902
|
+
try {
|
|
15903
|
+
const gitDirs = await resolveGitDirsForLockRecovery(thread.worktreePath);
|
|
15904
|
+
const clearedLocks = clearStaleIndexLocks(gitDirs, 2e3);
|
|
15905
|
+
if (clearedLocks.length > 0) {
|
|
15906
|
+
pushTurnStderr(stderrTail, "Cleared a stale git lock left by the crashed agent process");
|
|
15907
|
+
}
|
|
15908
|
+
} catch {
|
|
15909
|
+
}
|
|
15910
|
+
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";
|
|
15585
15911
|
pushTurnStderr(stderrTail, retryNote);
|
|
15586
15912
|
this.emit({
|
|
15587
15913
|
type: "turn_output",
|
|
@@ -16053,13 +16379,14 @@ var init_orchestrator = __esm({
|
|
|
16053
16379
|
const text4 = (lastAgent?.text ?? "").trim() || (thread.status === "error" ? lastError ?? "" : "");
|
|
16054
16380
|
const stillRunning = thread.status === "running" || thread.status === "queued";
|
|
16055
16381
|
const live = stillRunning ? readTurnLive(thread.id) : null;
|
|
16382
|
+
const queuedHint = thread.status === "queued" && !live?.summary ? "Queued \u2014 waiting for a concurrency slot" : null;
|
|
16056
16383
|
return {
|
|
16057
16384
|
text: text4,
|
|
16058
16385
|
status: thread.status,
|
|
16059
16386
|
sessionId: thread.sessionId,
|
|
16060
16387
|
lastError,
|
|
16061
16388
|
stillRunning,
|
|
16062
|
-
progress: live?.summary ??
|
|
16389
|
+
progress: live?.summary ?? queuedHint,
|
|
16063
16390
|
lastActivityAt: live?.updatedAt ?? null
|
|
16064
16391
|
};
|
|
16065
16392
|
}
|
|
@@ -16576,7 +16903,7 @@ var init_orchestrator = __esm({
|
|
|
16576
16903
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
16577
16904
|
return restored2;
|
|
16578
16905
|
}
|
|
16579
|
-
if (!(0,
|
|
16906
|
+
if (!(0, import_node_fs45.existsSync)(thread.worktreePath)) {
|
|
16580
16907
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
16581
16908
|
throw new Error(
|
|
16582
16909
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -16656,7 +16983,7 @@ init_nested_electron_env();
|
|
|
16656
16983
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
16657
16984
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
16658
16985
|
var import_zod4 = require("zod");
|
|
16659
|
-
var
|
|
16986
|
+
var import_node_path41 = require("path");
|
|
16660
16987
|
init_orchestrator();
|
|
16661
16988
|
init_worktree();
|
|
16662
16989
|
|
|
@@ -17163,6 +17490,10 @@ function mcpWaitForTurnTimeoutMs(requested) {
|
|
|
17163
17490
|
return Math.min(Math.max(1e3, Math.floor(n)), MCP_WAIT_FOR_TURN_MAX_MS);
|
|
17164
17491
|
}
|
|
17165
17492
|
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.";
|
|
17493
|
+
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.";
|
|
17494
|
+
function mcpWaitStillRunningHint(status) {
|
|
17495
|
+
return status === "queued" ? MCP_WAIT_QUEUED_HINT : MCP_WAIT_STILL_RUNNING_HINT;
|
|
17496
|
+
}
|
|
17166
17497
|
|
|
17167
17498
|
// src/mcp/server.ts
|
|
17168
17499
|
init_turn_live();
|
|
@@ -18009,7 +18340,7 @@ async function startMcpServer() {
|
|
|
18009
18340
|
async () => {
|
|
18010
18341
|
const threads = orch.getThreads(true);
|
|
18011
18342
|
const lines = threads.map((t) => {
|
|
18012
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
18343
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path41.basename)(t.repoPath) || t.repoPath;
|
|
18013
18344
|
const live = t.status === "running" || t.status === "queued" ? readTurnLive(t.id) : null;
|
|
18014
18345
|
const progress = live?.summary ? ` ${live.summary}` : "";
|
|
18015
18346
|
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}`;
|
|
@@ -18045,7 +18376,7 @@ async function startMcpServer() {
|
|
|
18045
18376
|
prUrl: t.prUrl,
|
|
18046
18377
|
lastError: t.lastError ?? null,
|
|
18047
18378
|
stillRunning: t.status === "running" || t.status === "queued",
|
|
18048
|
-
progress: live?.summary ?? null,
|
|
18379
|
+
progress: live?.summary ?? (t.status === "queued" ? "Queued \u2014 waiting for a concurrency slot" : null),
|
|
18049
18380
|
lastActivityAt: live?.updatedAt ?? null
|
|
18050
18381
|
};
|
|
18051
18382
|
return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
|
|
@@ -18054,7 +18385,7 @@ async function startMcpServer() {
|
|
|
18054
18385
|
}
|
|
18055
18386
|
server.tool(
|
|
18056
18387
|
"present_artifact",
|
|
18057
|
-
"Show an HTML, SVG, markdown, or React document in Sideboard\u2019s Claude-style side column (desktop). Use instead of claude.ai\u2019s artifact tool \u2014 pass the full document content. Prefer type=html for interactive pages. For type=react, pass a single component module that `export default`s a component (JSX/TSX ok) \u2014 Sideboard bootstraps React/ReactDOM/Babel and renders it; only `react`/`react-dom` imports are available, no other npm packages.",
|
|
18388
|
+
"Show an HTML, SVG, markdown, or React document in Sideboard\u2019s Claude-style side column (desktop). Use instead of claude.ai\u2019s artifact tool \u2014 pass the full document content. Do not also emit the same document as a chat html/markdown fence. Prefer type=html for interactive pages. For type=react, pass a single component module that `export default`s a component (JSX/TSX ok) \u2014 Sideboard bootstraps React/ReactDOM/Babel and renders it; only `react`/`react-dom` imports are available, no other npm packages.",
|
|
18058
18389
|
{
|
|
18059
18390
|
title: import_zod4.z.string().describe("Short title shown in the artifact pane header"),
|
|
18060
18391
|
type: import_zod4.z.enum(["html", "svg", "markdown", "react"]).describe(
|
|
@@ -18131,7 +18462,7 @@ async function startMcpServer() {
|
|
|
18131
18462
|
);
|
|
18132
18463
|
server.tool(
|
|
18133
18464
|
"present_schema",
|
|
18134
|
-
"Open Sideboard\u2019s schema-driven side column (filterable table and/or form). Pass JSON Schema + optional schemaUi. Prefer datasource=inline with embedded resource/records. Use datasource=brightsy with resource_id only when the user is logged into Brightsy.",
|
|
18465
|
+
"Open Sideboard\u2019s schema-driven side column (filterable table and/or form) when the user needs to filter, edit, publish, or persist records. Do not call this just to re-display rows you already wrote as a markdown table. If the user asks for an editable / interactive table, call this even if chat already showed those rows. Pass JSON Schema + optional schemaUi. Prefer datasource=inline with embedded resource/records. Use datasource=brightsy with resource_id only when the user is logged into Brightsy.",
|
|
18135
18466
|
{
|
|
18136
18467
|
title: import_zod4.z.string().describe("Pane title"),
|
|
18137
18468
|
mode: import_zod4.z.enum(["table", "form"]).optional().describe("table = list/filter records; form = edit one record"),
|
|
@@ -18379,7 +18710,7 @@ async function startMcpServer() {
|
|
|
18379
18710
|
);
|
|
18380
18711
|
server.tool(
|
|
18381
18712
|
"wait_for_turn",
|
|
18382
|
-
"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 \
|
|
18713
|
+
"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.",
|
|
18383
18714
|
{
|
|
18384
18715
|
ref: import_zod4.z.string(),
|
|
18385
18716
|
timeoutMs: import_zod4.z.number().optional()
|
|
@@ -18401,7 +18732,7 @@ async function startMcpServer() {
|
|
|
18401
18732
|
stillRunning: result.stillRunning,
|
|
18402
18733
|
progress: result.progress,
|
|
18403
18734
|
lastActivityAt: result.lastActivityAt,
|
|
18404
|
-
hint: result.stillRunning ?
|
|
18735
|
+
hint: result.stillRunning ? mcpWaitStillRunningHint(result.status) : void 0
|
|
18405
18736
|
})
|
|
18406
18737
|
}
|
|
18407
18738
|
]
|
|
@@ -18420,7 +18751,7 @@ async function startMcpServer() {
|
|
|
18420
18751
|
type: "text",
|
|
18421
18752
|
text: JSON.stringify({
|
|
18422
18753
|
...result,
|
|
18423
|
-
hint: result.stillRunning ?
|
|
18754
|
+
hint: result.stillRunning ? mcpWaitStillRunningHint(result.status) : void 0
|
|
18424
18755
|
})
|
|
18425
18756
|
}
|
|
18426
18757
|
]
|