@sideboard-ai/core 0.1.111 → 0.1.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/cursor-runner.cjs +29 -20
- package/dist/agents/cursor-runner.js +3 -3
- package/dist/{agents-NN22A4G5.js → agents-3X3EFCQY.js} +7 -7
- package/dist/{agents-GH3FWDW2.js → agents-AHAFC6FR.js} +10 -10
- package/dist/{chunk-4EWPKYOU.js → chunk-4OJMZ6P2.js} +2 -2
- package/dist/{chunk-KVFNTWFG.js → chunk-66XTXHR3.js} +244 -36
- package/dist/{chunk-KQBI5HNT.js → chunk-7WC5UWEB.js} +2 -2
- package/dist/{chunk-WIHKHR5R.js → chunk-AXQ4ZWHK.js} +5 -0
- package/dist/{chunk-NC3U42ZP.js → chunk-C6OBY6IC.js} +268 -27
- package/dist/{chunk-DMJKOFTO.js → chunk-DCNR7NAL.js} +39 -31
- package/dist/{chunk-LGXBYZZA.js → chunk-DVM4ID64.js} +69 -13
- package/dist/{chunk-2GO3YKBA.js → chunk-EKIDHL2T.js} +4 -4
- package/dist/{chunk-C4KHDW3U.js → chunk-FZCIQYNQ.js} +1 -1
- package/dist/{chunk-7KWYXGIU.js → chunk-K3TIQXOH.js} +2 -2
- package/dist/{chunk-3KETJKYA.js → chunk-KPIYENTF.js} +69 -13
- package/dist/{chunk-JTQQPJAU.js → chunk-MZ6HJ7VL.js} +47 -34
- package/dist/{chunk-363Z34PY.js → chunk-SLU5JVKD.js} +251 -217
- 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 +787 -427
- package/dist/index.d.cts +53 -1
- package/dist/index.d.ts +53 -1
- package/dist/index.js +33 -15
- package/dist/mcp/run-stdio.cjs +906 -625
- package/dist/mcp/run-stdio.js +18 -14
- package/dist/{orchestrator-4T2SXDZ7.js → orchestrator-GKLYKLRC.js} +8 -8
- package/dist/{orchestrator-EP57AB5W.js → orchestrator-TXASYNHT.js} +10 -10
- package/dist/{run-XKTAJRWF.js → run-USF6FRKV.js} +3 -1
- package/dist/{run-CFKZPY7F.js → run-XQKGHQZ2.js} +3 -1
- package/dist/{workspaces-XAQVKTLO.js → workspaces-HJ3EVATC.js} +5 -5
- package/dist/{workspaces-HV3J4TTW.js → workspaces-QG6PGFQR.js} +5 -5
- package/dist/{worktree-XFJED3VU.js → worktree-IW3BX26B.js} +2 -2
- package/dist/{worktree-N2EV24EE.js → worktree-OTFQO2W7.js} +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3583,12 +3583,47 @@ var init_path = __esm({
|
|
|
3583
3583
|
}
|
|
3584
3584
|
});
|
|
3585
3585
|
|
|
3586
|
+
// src/git/stale-lock.ts
|
|
3587
|
+
function isIndexLockError(text4) {
|
|
3588
|
+
return /Unable to create ['"][^'"]*index\.lock['"]: File exists/i.test(text4);
|
|
3589
|
+
}
|
|
3590
|
+
function clearStaleIndexLock(gitDir, maxAgeMs = STALE_INDEX_LOCK_MS, now = Date.now()) {
|
|
3591
|
+
const lockPath = (0, import_node_path14.join)(gitDir, "index.lock");
|
|
3592
|
+
try {
|
|
3593
|
+
if (!(0, import_node_fs14.existsSync)(lockPath)) return null;
|
|
3594
|
+
if (now - (0, import_node_fs14.statSync)(lockPath).mtimeMs < maxAgeMs) return null;
|
|
3595
|
+
(0, import_node_fs14.unlinkSync)(lockPath);
|
|
3596
|
+
return lockPath;
|
|
3597
|
+
} catch {
|
|
3598
|
+
return null;
|
|
3599
|
+
}
|
|
3600
|
+
}
|
|
3601
|
+
function clearStaleIndexLocks(gitDirs, maxAgeMs = STALE_INDEX_LOCK_MS) {
|
|
3602
|
+
const now = Date.now();
|
|
3603
|
+
const removed = [];
|
|
3604
|
+
for (const dir of new Set(gitDirs)) {
|
|
3605
|
+
const cleared = clearStaleIndexLock(dir, maxAgeMs, now);
|
|
3606
|
+
if (cleared) removed.push(cleared);
|
|
3607
|
+
}
|
|
3608
|
+
return removed;
|
|
3609
|
+
}
|
|
3610
|
+
var import_node_fs14, import_node_path14, STALE_INDEX_LOCK_MS;
|
|
3611
|
+
var init_stale_lock = __esm({
|
|
3612
|
+
"src/git/stale-lock.ts"() {
|
|
3613
|
+
"use strict";
|
|
3614
|
+
import_node_fs14 = require("fs");
|
|
3615
|
+
import_node_path14 = require("path");
|
|
3616
|
+
STALE_INDEX_LOCK_MS = 2e4;
|
|
3617
|
+
}
|
|
3618
|
+
});
|
|
3619
|
+
|
|
3586
3620
|
// src/git/run.ts
|
|
3587
3621
|
var run_exports = {};
|
|
3588
3622
|
__export(run_exports, {
|
|
3589
3623
|
gh: () => gh,
|
|
3590
3624
|
git: () => git,
|
|
3591
3625
|
resolveGhAuthToken: () => resolveGhAuthToken,
|
|
3626
|
+
resolveGitDirsForLockRecovery: () => resolveGitDirsForLockRecovery,
|
|
3592
3627
|
run: () => run
|
|
3593
3628
|
});
|
|
3594
3629
|
async function run(file, args, opts) {
|
|
@@ -3617,6 +3652,21 @@ async function run(file, args, opts) {
|
|
|
3617
3652
|
throw err;
|
|
3618
3653
|
}
|
|
3619
3654
|
}
|
|
3655
|
+
async function resolveGitDirsForLockRecovery(cwd, env = {}) {
|
|
3656
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
3657
|
+
const [gitDir, commonDir] = await Promise.all([
|
|
3658
|
+
run("git", ["rev-parse", "--absolute-git-dir"], { cwd, reject: false, env, timeoutMs: 5e3 }),
|
|
3659
|
+
run("git", ["rev-parse", "--path-format=absolute", "--git-common-dir"], {
|
|
3660
|
+
cwd,
|
|
3661
|
+
reject: false,
|
|
3662
|
+
env,
|
|
3663
|
+
timeoutMs: 5e3
|
|
3664
|
+
})
|
|
3665
|
+
]);
|
|
3666
|
+
if (gitDir.exitCode === 0 && gitDir.stdout.trim()) dirs.add(gitDir.stdout.trim());
|
|
3667
|
+
if (commonDir.exitCode === 0 && commonDir.stdout.trim()) dirs.add(commonDir.stdout.trim());
|
|
3668
|
+
return [...dirs];
|
|
3669
|
+
}
|
|
3620
3670
|
async function git(args, cwd, opts) {
|
|
3621
3671
|
const prefix = [];
|
|
3622
3672
|
if (opts?.config) {
|
|
@@ -3625,21 +3675,32 @@ async function git(args, cwd, opts) {
|
|
|
3625
3675
|
prefix.push("-c", `${key}=${value}`);
|
|
3626
3676
|
}
|
|
3627
3677
|
}
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
reject: opts?.reject,
|
|
3631
|
-
timeoutMs: opts?.timeoutMs,
|
|
3678
|
+
const gitArgs = ["--no-pager", ...prefix, ...args];
|
|
3679
|
+
const env = {
|
|
3632
3680
|
// Never block forever on a credential/SSH prompt inside MCP / Electron.
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3681
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
3682
|
+
GIT_ASKPASS: process.env.GIT_ASKPASS || "echo",
|
|
3683
|
+
SSH_ASKPASS: process.env.SSH_ASKPASS || "echo",
|
|
3684
|
+
GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND || "ssh -o BatchMode=yes -o ConnectTimeout=15",
|
|
3685
|
+
GCM_INTERACTIVE: "never",
|
|
3686
|
+
GH_PROMPT_DISABLED: "1",
|
|
3687
|
+
...opts?.env
|
|
3688
|
+
};
|
|
3689
|
+
let result = await run("git", gitArgs, { cwd, reject: false, timeoutMs: opts?.timeoutMs, env });
|
|
3690
|
+
if (result.exitCode !== 0 && isIndexLockError(result.stderr)) {
|
|
3691
|
+
const gitDirs = await resolveGitDirsForLockRecovery(cwd, env);
|
|
3692
|
+
const cleared = clearStaleIndexLocks(gitDirs);
|
|
3693
|
+
if (cleared.length > 0) {
|
|
3694
|
+
result = await run("git", gitArgs, { cwd, reject: false, timeoutMs: opts?.timeoutMs, env });
|
|
3641
3695
|
}
|
|
3642
|
-
}
|
|
3696
|
+
}
|
|
3697
|
+
if ((opts?.reject ?? true) && result.exitCode !== 0) {
|
|
3698
|
+
throw new Error(
|
|
3699
|
+
`Command failed with exit code ${result.exitCode}: git ${gitArgs.join(" ")}
|
|
3700
|
+
${result.stderr}`
|
|
3701
|
+
);
|
|
3702
|
+
}
|
|
3703
|
+
return result;
|
|
3643
3704
|
}
|
|
3644
3705
|
async function gh(args, cwd, opts) {
|
|
3645
3706
|
return run("gh", args, {
|
|
@@ -3664,6 +3725,7 @@ var init_run = __esm({
|
|
|
3664
3725
|
"use strict";
|
|
3665
3726
|
import_execa2 = require("execa");
|
|
3666
3727
|
init_path();
|
|
3728
|
+
init_stale_lock();
|
|
3667
3729
|
}
|
|
3668
3730
|
});
|
|
3669
3731
|
|
|
@@ -3758,7 +3820,7 @@ async function warmGithubAgentAuth(opts) {
|
|
|
3758
3820
|
}
|
|
3759
3821
|
function normalizeWritableRoot(raw) {
|
|
3760
3822
|
const trimmed = raw.trim().replace(/\/+$/, "");
|
|
3761
|
-
return trimmed && (0,
|
|
3823
|
+
return trimmed && (0, import_node_path15.isAbsolute)(trimmed) ? trimmed : null;
|
|
3762
3824
|
}
|
|
3763
3825
|
async function resolveCodexGitWritableRoots(cwd) {
|
|
3764
3826
|
const roots = /* @__PURE__ */ new Set();
|
|
@@ -3835,11 +3897,11 @@ function formatGitAuthModeDirective(mode) {
|
|
|
3835
3897
|
].join("\n");
|
|
3836
3898
|
}
|
|
3837
3899
|
}
|
|
3838
|
-
var
|
|
3900
|
+
var import_node_path15, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
|
|
3839
3901
|
var init_git_auth_mode = __esm({
|
|
3840
3902
|
"src/git/git-auth-mode.ts"() {
|
|
3841
3903
|
"use strict";
|
|
3842
|
-
|
|
3904
|
+
import_node_path15 = require("path");
|
|
3843
3905
|
init_app_settings();
|
|
3844
3906
|
init_github_agent_auth();
|
|
3845
3907
|
init_run();
|
|
@@ -5037,8 +5099,8 @@ function isLocalPrFetchBranch(ref) {
|
|
|
5037
5099
|
}
|
|
5038
5100
|
async function createThreadWorktree(opts) {
|
|
5039
5101
|
let branchName = `thread/${opts.slug}`;
|
|
5040
|
-
const worktreePath = (0,
|
|
5041
|
-
if ((0,
|
|
5102
|
+
const worktreePath = (0, import_node_path16.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
5103
|
+
if ((0, import_node_fs15.existsSync)(worktreePath)) {
|
|
5042
5104
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
5043
5105
|
}
|
|
5044
5106
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -5105,8 +5167,8 @@ ${add.stdout}`;
|
|
|
5105
5167
|
async function createExistingBranchWorktree(opts) {
|
|
5106
5168
|
const branchName = opts.branchName.trim();
|
|
5107
5169
|
if (!branchName) throw new Error("branch name required");
|
|
5108
|
-
const worktreePath = (0,
|
|
5109
|
-
if ((0,
|
|
5170
|
+
const worktreePath = (0, import_node_path16.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
5171
|
+
if ((0, import_node_fs15.existsSync)(worktreePath)) {
|
|
5110
5172
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
5111
5173
|
}
|
|
5112
5174
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -5397,10 +5459,10 @@ function sameRepoPath(a, b) {
|
|
|
5397
5459
|
return normalizeWorktreePath(a) === normalizeWorktreePath(b);
|
|
5398
5460
|
}
|
|
5399
5461
|
function listLocalThreadBranchSlugs(repoPath) {
|
|
5400
|
-
const refsDir = (0,
|
|
5401
|
-
if (!(0,
|
|
5462
|
+
const refsDir = (0, import_node_path16.join)(repoPath, ".git", "refs", "heads", "thread");
|
|
5463
|
+
if (!(0, import_node_fs15.existsSync)(refsDir)) return [];
|
|
5402
5464
|
try {
|
|
5403
|
-
return (0,
|
|
5465
|
+
return (0, import_node_fs15.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
|
|
5404
5466
|
} catch {
|
|
5405
5467
|
return [];
|
|
5406
5468
|
}
|
|
@@ -5408,8 +5470,8 @@ function listLocalThreadBranchSlugs(repoPath) {
|
|
|
5408
5470
|
function collectTakenTeamSlugs(repoPath) {
|
|
5409
5471
|
const taken = /* @__PURE__ */ new Set();
|
|
5410
5472
|
const root = worktreesRoot(repoPath);
|
|
5411
|
-
if ((0,
|
|
5412
|
-
for (const entry of (0,
|
|
5473
|
+
if ((0, import_node_fs15.existsSync)(root)) {
|
|
5474
|
+
for (const entry of (0, import_node_fs15.readdirSync)(root, { withFileTypes: true })) {
|
|
5413
5475
|
if (entry.isDirectory() && entry.name !== ".DS_Store") {
|
|
5414
5476
|
taken.add(normalizeTakenSlug(entry.name));
|
|
5415
5477
|
}
|
|
@@ -5430,18 +5492,18 @@ function allocateTeamSlug(repoPath) {
|
|
|
5430
5492
|
const taken = collectTakenTeamSlugs(repoPath);
|
|
5431
5493
|
for (let attempt = 0; attempt < 32; attempt++) {
|
|
5432
5494
|
const team = allocateTeamName(taken);
|
|
5433
|
-
const path2 = (0,
|
|
5434
|
-
if (!(0,
|
|
5495
|
+
const path2 = (0, import_node_path16.join)(worktreesRoot(repoPath), team.slug);
|
|
5496
|
+
if (!(0, import_node_fs15.existsSync)(path2)) return team;
|
|
5435
5497
|
taken.add(team.slug);
|
|
5436
5498
|
}
|
|
5437
5499
|
throw new Error("No available soccer team worktree directories left");
|
|
5438
5500
|
}
|
|
5439
|
-
var
|
|
5501
|
+
var import_node_fs15, import_node_path16;
|
|
5440
5502
|
var init_worktree = __esm({
|
|
5441
5503
|
"src/git/worktree.ts"() {
|
|
5442
5504
|
"use strict";
|
|
5443
|
-
|
|
5444
|
-
|
|
5505
|
+
import_node_fs15 = require("fs");
|
|
5506
|
+
import_node_path16 = require("path");
|
|
5445
5507
|
init_paths();
|
|
5446
5508
|
init_thread_store();
|
|
5447
5509
|
init_teams();
|
|
@@ -5518,7 +5580,7 @@ function coordinatorTurnReminder(opts) {
|
|
|
5518
5580
|
function ensureGlobalCoordinatorCwd(opts) {
|
|
5519
5581
|
const dir = globalAgentCwd();
|
|
5520
5582
|
try {
|
|
5521
|
-
(0,
|
|
5583
|
+
(0, import_node_fs16.mkdirSync)(dir, { recursive: true });
|
|
5522
5584
|
} catch {
|
|
5523
5585
|
return dir;
|
|
5524
5586
|
}
|
|
@@ -5526,7 +5588,7 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
5526
5588
|
let orchId = opts?.orchestratorThreadId?.trim() || "";
|
|
5527
5589
|
if (!orchId) {
|
|
5528
5590
|
try {
|
|
5529
|
-
const existing = (0,
|
|
5591
|
+
const existing = (0, import_node_fs16.readFileSync)((0, import_node_path17.join)(dir, "AGENTS.md"), "utf8");
|
|
5530
5592
|
const m = existing.match(
|
|
5531
5593
|
/YOUR orchestration thread id is `([0-9a-f-]{36})`/i
|
|
5532
5594
|
);
|
|
@@ -5568,9 +5630,9 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
5568
5630
|
"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."
|
|
5569
5631
|
].join("\n");
|
|
5570
5632
|
try {
|
|
5571
|
-
(0,
|
|
5633
|
+
(0, import_node_fs16.writeFileSync)((0, import_node_path17.join)(dir, "CLAUDE.md"), `${body}
|
|
5572
5634
|
`, "utf8");
|
|
5573
|
-
(0,
|
|
5635
|
+
(0, import_node_fs16.writeFileSync)((0, import_node_path17.join)(dir, "AGENTS.md"), `${body}
|
|
5574
5636
|
`, "utf8");
|
|
5575
5637
|
} catch {
|
|
5576
5638
|
}
|
|
@@ -5602,12 +5664,12 @@ function coordinatorSystemPrompt(opts) {
|
|
|
5602
5664
|
formatWorkspaceInventory(opts.workspaces)
|
|
5603
5665
|
].join("\n");
|
|
5604
5666
|
}
|
|
5605
|
-
var
|
|
5667
|
+
var import_node_fs16, import_node_path17, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
|
|
5606
5668
|
var init_coordinator_prompt = __esm({
|
|
5607
5669
|
"src/orchestrator/coordinator-prompt.ts"() {
|
|
5608
5670
|
"use strict";
|
|
5609
|
-
|
|
5610
|
-
|
|
5671
|
+
import_node_fs16 = require("fs");
|
|
5672
|
+
import_node_path17 = require("path");
|
|
5611
5673
|
init_worktree();
|
|
5612
5674
|
init_app_settings();
|
|
5613
5675
|
init_paths();
|
|
@@ -5633,7 +5695,7 @@ var init_coordinator_prompt = __esm({
|
|
|
5633
5695
|
"- 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.",
|
|
5634
5696
|
"- 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.",
|
|
5635
5697
|
"- 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",
|
|
5636
|
-
"- 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.",
|
|
5698
|
+
"- 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.",
|
|
5637
5699
|
"- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
|
|
5638
5700
|
"- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
|
|
5639
5701
|
"Setup / run:",
|
|
@@ -5950,13 +6012,13 @@ var init_api = __esm({
|
|
|
5950
6012
|
|
|
5951
6013
|
// src/slack/reply-target.ts
|
|
5952
6014
|
function storePath() {
|
|
5953
|
-
return (0,
|
|
6015
|
+
return (0, import_node_path18.join)(appDataDir(), "slack-reply-to.json");
|
|
5954
6016
|
}
|
|
5955
6017
|
function readStore() {
|
|
5956
6018
|
const path2 = storePath();
|
|
5957
|
-
if (!(0,
|
|
6019
|
+
if (!(0, import_node_fs17.existsSync)(path2)) return {};
|
|
5958
6020
|
try {
|
|
5959
|
-
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0,
|
|
6021
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs17.readFileSync)(path2, "utf8"));
|
|
5960
6022
|
return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
|
|
5961
6023
|
} catch {
|
|
5962
6024
|
return {};
|
|
@@ -5971,12 +6033,12 @@ function setSlackReplyTarget(target) {
|
|
|
5971
6033
|
function getSlackReplyTarget(threadId) {
|
|
5972
6034
|
return readStore()[threadId] ?? null;
|
|
5973
6035
|
}
|
|
5974
|
-
var
|
|
6036
|
+
var import_node_fs17, import_node_path18;
|
|
5975
6037
|
var init_reply_target = __esm({
|
|
5976
6038
|
"src/slack/reply-target.ts"() {
|
|
5977
6039
|
"use strict";
|
|
5978
|
-
|
|
5979
|
-
|
|
6040
|
+
import_node_fs17 = require("fs");
|
|
6041
|
+
import_node_path18 = require("path");
|
|
5980
6042
|
init_paths();
|
|
5981
6043
|
init_private_file();
|
|
5982
6044
|
init_secure_file();
|
|
@@ -5985,7 +6047,7 @@ var init_reply_target = __esm({
|
|
|
5985
6047
|
|
|
5986
6048
|
// src/slack/workspaces.ts
|
|
5987
6049
|
function storePath2() {
|
|
5988
|
-
return (0,
|
|
6050
|
+
return (0, import_node_path19.join)(appDataDir(), "slack-workspaces.json");
|
|
5989
6051
|
}
|
|
5990
6052
|
function readStore2() {
|
|
5991
6053
|
try {
|
|
@@ -6092,11 +6154,11 @@ function requireSlackWorkspace(teamId) {
|
|
|
6092
6154
|
}
|
|
6093
6155
|
return ws;
|
|
6094
6156
|
}
|
|
6095
|
-
var
|
|
6157
|
+
var import_node_path19;
|
|
6096
6158
|
var init_workspaces = __esm({
|
|
6097
6159
|
"src/slack/workspaces.ts"() {
|
|
6098
6160
|
"use strict";
|
|
6099
|
-
|
|
6161
|
+
import_node_path19 = require("path");
|
|
6100
6162
|
init_paths();
|
|
6101
6163
|
init_secure_file();
|
|
6102
6164
|
init_api();
|
|
@@ -6105,7 +6167,7 @@ var init_workspaces = __esm({
|
|
|
6105
6167
|
|
|
6106
6168
|
// src/slack/outbound-watch.ts
|
|
6107
6169
|
function storePath3() {
|
|
6108
|
-
return (0,
|
|
6170
|
+
return (0, import_node_path20.join)(appDataDir(), "slack-outbound-watch.json");
|
|
6109
6171
|
}
|
|
6110
6172
|
function watchId(teamId, channelId, ts) {
|
|
6111
6173
|
return `${teamId}:${channelId}:${ts}`;
|
|
@@ -6135,9 +6197,9 @@ function tsNewer(a, b) {
|
|
|
6135
6197
|
}
|
|
6136
6198
|
function readStore3() {
|
|
6137
6199
|
const path2 = storePath3();
|
|
6138
|
-
if (!(0,
|
|
6200
|
+
if (!(0, import_node_fs18.existsSync)(path2)) return [];
|
|
6139
6201
|
try {
|
|
6140
|
-
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0,
|
|
6202
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs18.readFileSync)(path2, "utf8"));
|
|
6141
6203
|
return Array.isArray(parsed?.watches) ? parsed.watches : [];
|
|
6142
6204
|
} catch {
|
|
6143
6205
|
return [];
|
|
@@ -6480,12 +6542,12 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
6480
6542
|
if (changed) writeStore2(watches);
|
|
6481
6543
|
return listSlackReplyBadges();
|
|
6482
6544
|
}
|
|
6483
|
-
var
|
|
6545
|
+
var import_node_fs18, import_node_path20, MAX_WATCHES, MAX_REPLIES_PER_WATCH, WATCH_TTL_MS, POLL_INTERVAL_MS, lastPollMs, nameCache;
|
|
6484
6546
|
var init_outbound_watch = __esm({
|
|
6485
6547
|
"src/slack/outbound-watch.ts"() {
|
|
6486
6548
|
"use strict";
|
|
6487
|
-
|
|
6488
|
-
|
|
6549
|
+
import_node_fs18 = require("fs");
|
|
6550
|
+
import_node_path20 = require("path");
|
|
6489
6551
|
init_paths();
|
|
6490
6552
|
init_private_file();
|
|
6491
6553
|
init_secure_file();
|
|
@@ -6635,6 +6697,7 @@ function looksLikeRetryableRunnerCrash(text4) {
|
|
|
6635
6697
|
}
|
|
6636
6698
|
function shouldRetryFailedAgentTurn(detail, opts) {
|
|
6637
6699
|
if (looksLikeInvalidAgentSession(detail) && opts.hasSession) return true;
|
|
6700
|
+
if (looksLikeV8Oom(detail) && opts.hasSession) return true;
|
|
6638
6701
|
return looksLikeRetryableRunnerCrash(detail);
|
|
6639
6702
|
}
|
|
6640
6703
|
function looksLikeAgentFailureMessage(text4) {
|
|
@@ -6727,39 +6790,39 @@ var init_error_detail = __esm({
|
|
|
6727
6790
|
NESTED_ELECTRON_SUMMARY = "Cursor local agent crashed at Electron startup (nested Chromium / HasCustomHostObject)";
|
|
6728
6791
|
HOMEBREW_LIBUV_SUMMARY = "Cursor runner crashed in Node (Homebrew Node + shared libuv). Install Node 22 LTS (`brew install node@22`) and retry.";
|
|
6729
6792
|
BUNDLED_NODE_CRASH_SUMMARY = "Cursor runner crashed in Node. Retry the turn.";
|
|
6730
|
-
V8_OOM_SUMMARY = "
|
|
6793
|
+
V8_OOM_SUMMARY = "Agent ran out of memory (JavaScript heap). If it keeps happening, exclude large files from the project folder.";
|
|
6731
6794
|
MINIFIED_DUMP_SUMMARY = "Cursor local agent crashed during startup (truncated crash dump)";
|
|
6732
6795
|
}
|
|
6733
6796
|
});
|
|
6734
6797
|
|
|
6735
6798
|
// src/brightsy/config.ts
|
|
6736
6799
|
function brightsyConfigPath() {
|
|
6737
|
-
return (0,
|
|
6800
|
+
return (0, import_node_path21.join)((0, import_node_os6.homedir)(), ".brightsy", "config.json");
|
|
6738
6801
|
}
|
|
6739
6802
|
function loadBrightsyConfig() {
|
|
6740
6803
|
const path2 = brightsyConfigPath();
|
|
6741
|
-
if (!(0,
|
|
6804
|
+
if (!(0, import_node_fs19.existsSync)(path2)) {
|
|
6742
6805
|
throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
|
|
6743
6806
|
}
|
|
6744
|
-
const raw = JSON.parse((0,
|
|
6807
|
+
const raw = JSON.parse((0, import_node_fs19.readFileSync)(path2, "utf8"));
|
|
6745
6808
|
if (!raw.access_token || !raw.account_id) {
|
|
6746
6809
|
throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
|
|
6747
6810
|
}
|
|
6748
6811
|
return raw;
|
|
6749
6812
|
}
|
|
6750
6813
|
function saveBrightsyConfig(cfg) {
|
|
6751
|
-
(0,
|
|
6814
|
+
(0, import_node_fs19.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
|
|
6752
6815
|
`, {
|
|
6753
6816
|
mode: 384
|
|
6754
6817
|
});
|
|
6755
6818
|
}
|
|
6756
|
-
var
|
|
6819
|
+
var import_node_fs19, import_node_os6, import_node_path21;
|
|
6757
6820
|
var init_config = __esm({
|
|
6758
6821
|
"src/brightsy/config.ts"() {
|
|
6759
6822
|
"use strict";
|
|
6760
|
-
|
|
6823
|
+
import_node_fs19 = require("fs");
|
|
6761
6824
|
import_node_os6 = require("os");
|
|
6762
|
-
|
|
6825
|
+
import_node_path21 = require("path");
|
|
6763
6826
|
}
|
|
6764
6827
|
});
|
|
6765
6828
|
|
|
@@ -6862,22 +6925,22 @@ __export(connected_teams_exports, {
|
|
|
6862
6925
|
listConnectedBrightsyTeams: () => listConnectedBrightsyTeams
|
|
6863
6926
|
});
|
|
6864
6927
|
function storePath4() {
|
|
6865
|
-
return (0,
|
|
6928
|
+
return (0, import_node_path22.join)(appDataDir(), "brightsy-teams.json");
|
|
6866
6929
|
}
|
|
6867
6930
|
function readStore4() {
|
|
6868
6931
|
const path2 = storePath4();
|
|
6869
|
-
if (!(0,
|
|
6932
|
+
if (!(0, import_node_fs20.existsSync)(path2)) return [];
|
|
6870
6933
|
try {
|
|
6871
|
-
const parsed = JSON.parse((0,
|
|
6934
|
+
const parsed = JSON.parse((0, import_node_fs20.readFileSync)(path2, "utf8"));
|
|
6872
6935
|
return Array.isArray(parsed.teams) ? parsed.teams : [];
|
|
6873
6936
|
} catch {
|
|
6874
6937
|
return [];
|
|
6875
6938
|
}
|
|
6876
6939
|
}
|
|
6877
6940
|
function writeStore3(teams) {
|
|
6878
|
-
(0,
|
|
6941
|
+
(0, import_node_fs20.mkdirSync)(appDataDir(), { recursive: true });
|
|
6879
6942
|
const path2 = storePath4();
|
|
6880
|
-
(0,
|
|
6943
|
+
(0, import_node_fs20.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
|
|
6881
6944
|
`, {
|
|
6882
6945
|
mode: 384
|
|
6883
6946
|
});
|
|
@@ -7039,12 +7102,12 @@ function brightsyMcpServerName(slug) {
|
|
|
7039
7102
|
const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
|
|
7040
7103
|
return `brightsy_${cleaned || "team"}`;
|
|
7041
7104
|
}
|
|
7042
|
-
var
|
|
7105
|
+
var import_node_fs20, import_node_path22;
|
|
7043
7106
|
var init_connected_teams = __esm({
|
|
7044
7107
|
"src/brightsy/connected-teams.ts"() {
|
|
7045
7108
|
"use strict";
|
|
7046
|
-
|
|
7047
|
-
|
|
7109
|
+
import_node_fs20 = require("fs");
|
|
7110
|
+
import_node_path22 = require("path");
|
|
7048
7111
|
init_paths();
|
|
7049
7112
|
init_accounts();
|
|
7050
7113
|
init_config();
|
|
@@ -7422,11 +7485,11 @@ async function syncCliForTarget(accountId) {
|
|
|
7422
7485
|
}
|
|
7423
7486
|
applyConnectedTeamToCli(team);
|
|
7424
7487
|
}
|
|
7425
|
-
var
|
|
7488
|
+
var import_node_fs21, brightsyAdapter;
|
|
7426
7489
|
var init_brightsy = __esm({
|
|
7427
7490
|
"src/agents/brightsy.ts"() {
|
|
7428
7491
|
"use strict";
|
|
7429
|
-
|
|
7492
|
+
import_node_fs21 = require("fs");
|
|
7430
7493
|
init_run();
|
|
7431
7494
|
init_connected_teams();
|
|
7432
7495
|
init_config();
|
|
@@ -7441,7 +7504,7 @@ var init_brightsy = __esm({
|
|
|
7441
7504
|
async detect() {
|
|
7442
7505
|
const brightsy = resolveAgentExecutable("brightsy");
|
|
7443
7506
|
if (brightsy !== "brightsy") {
|
|
7444
|
-
if (!(0,
|
|
7507
|
+
if (!(0, import_node_fs21.existsSync)(brightsy)) {
|
|
7445
7508
|
return {
|
|
7446
7509
|
agent: "brightsy",
|
|
7447
7510
|
installed: false,
|
|
@@ -7617,9 +7680,9 @@ function toolDescription(name, input) {
|
|
|
7617
7680
|
if (/connectedAgentRequest/i.test(name)) {
|
|
7618
7681
|
return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
|
|
7619
7682
|
}
|
|
7620
|
-
if (desc && kind) return `${kind}: ${desc}`;
|
|
7621
|
-
if (desc) return desc
|
|
7622
|
-
return
|
|
7683
|
+
if (desc && kind) return `${kind}: ${desc}${subagentLiveSuffix(input)}`;
|
|
7684
|
+
if (desc) return `${desc}${subagentLiveSuffix(input)}`;
|
|
7685
|
+
return `Subagent${subagentLiveSuffix(input)}`;
|
|
7623
7686
|
}
|
|
7624
7687
|
if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
|
|
7625
7688
|
return str2(input?.title) ? `Artifact ${str2(input?.title)}` : "Artifact";
|
|
@@ -7644,13 +7707,148 @@ function toolDescription(name, input) {
|
|
|
7644
7707
|
}
|
|
7645
7708
|
if (/grep/i.test(name)) return "Search files";
|
|
7646
7709
|
if (/glob/i.test(name)) return "Find files";
|
|
7710
|
+
const compact = n.replace(/[_-]/g, "");
|
|
7711
|
+
if (/^taskoutput$/i.test(compact)) {
|
|
7712
|
+
return str2(input.task_id) ? `Wait for ${str2(input.task_id)}` : "Wait for background task";
|
|
7713
|
+
}
|
|
7714
|
+
if (/^taskstop$/i.test(compact)) {
|
|
7715
|
+
return str2(input.task_id) ? `Stop ${str2(input.task_id)}` : "Stop background task";
|
|
7716
|
+
}
|
|
7717
|
+
if (/^monitor$/i.test(compact)) {
|
|
7718
|
+
const command = str2(input.command);
|
|
7719
|
+
return command ? `Watch ${command.length > 48 ? `${command.slice(0, 45)}\u2026` : command}` : "Watch command";
|
|
7720
|
+
}
|
|
7647
7721
|
return n;
|
|
7648
7722
|
}
|
|
7723
|
+
function subagentLiveSuffix(input) {
|
|
7724
|
+
if (!input) return "";
|
|
7725
|
+
const bits = [];
|
|
7726
|
+
const status = str2(input.live_status);
|
|
7727
|
+
if (status && !/^runn(ing)?$|^working$/i.test(status)) bits.push(status);
|
|
7728
|
+
if (typeof input.live_tool_uses === "number") bits.push(`${input.live_tool_uses} tools`);
|
|
7729
|
+
if (typeof input.live_duration_ms === "number") {
|
|
7730
|
+
bits.push(`${Math.max(0, Math.round(Number(input.live_duration_ms) / 1e3))}s`);
|
|
7731
|
+
}
|
|
7732
|
+
const last = str2(input.live_last_tool);
|
|
7733
|
+
if (last) bits.push(last);
|
|
7734
|
+
return bits.length ? ` \xB7 ${bits.join(" \xB7 ")}` : "";
|
|
7735
|
+
}
|
|
7649
7736
|
function isSubagentToolName(name) {
|
|
7650
7737
|
const n = (name ?? "").trim();
|
|
7651
7738
|
if (/^(task|agent|spawn_agent)$/i.test(n)) return true;
|
|
7652
7739
|
return /connectedAgentRequest/i.test(n);
|
|
7653
7740
|
}
|
|
7741
|
+
function isPollWrapperToolName(name) {
|
|
7742
|
+
const n = (name ?? "").replace(/[_-]/g, "");
|
|
7743
|
+
return /^(taskoutput|taskstop|sleep)$/i.test(n);
|
|
7744
|
+
}
|
|
7745
|
+
function lastTextPart(parts, type) {
|
|
7746
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
7747
|
+
const p = parts[i];
|
|
7748
|
+
if (p.type === type && p.text.trim()) return p.text.trim();
|
|
7749
|
+
}
|
|
7750
|
+
return "";
|
|
7751
|
+
}
|
|
7752
|
+
function toolLabel(tool) {
|
|
7753
|
+
return tool.description || toolDescription(tool.name, tool.input) || tool.name;
|
|
7754
|
+
}
|
|
7755
|
+
function fileBasename(path2) {
|
|
7756
|
+
const parts = path2.replace(/\/$/, "").split(/[/\\]/);
|
|
7757
|
+
return parts[parts.length - 1] || path2;
|
|
7758
|
+
}
|
|
7759
|
+
function classifyTool(name) {
|
|
7760
|
+
const compact = name.replace(/^mcp__[^_]+__/, "").replace(/[_-]/g, "");
|
|
7761
|
+
if (/bash|shell|terminal|^zsh$|^sh$/i.test(compact)) return "shell";
|
|
7762
|
+
if (/grep|glob|search|ripgrep|findfiles|semsearch/i.test(compact)) return "search";
|
|
7763
|
+
if (/^(read|cat)$/i.test(compact) || /^read/i.test(compact)) return "read";
|
|
7764
|
+
if (/edit|write|apply|strreplace|multiedit|updatefile|createfile/i.test(compact)) {
|
|
7765
|
+
return "edit";
|
|
7766
|
+
}
|
|
7767
|
+
return "other";
|
|
7768
|
+
}
|
|
7769
|
+
function toolActivityLine(parts) {
|
|
7770
|
+
const tools = parts.filter((p) => {
|
|
7771
|
+
if (p.type !== "tool" || p.parentId) return false;
|
|
7772
|
+
if (isPollWrapperToolName(p.name)) return false;
|
|
7773
|
+
if (/present_plan$/i.test(p.name ?? "")) return false;
|
|
7774
|
+
if (/ask_user|AskUserQuestion/i.test(p.name ?? "")) return false;
|
|
7775
|
+
return true;
|
|
7776
|
+
});
|
|
7777
|
+
if (tools.length === 0) return null;
|
|
7778
|
+
const edited = [];
|
|
7779
|
+
let reads = 0;
|
|
7780
|
+
let searches = 0;
|
|
7781
|
+
let shells = 0;
|
|
7782
|
+
let others = 0;
|
|
7783
|
+
let additions = 0;
|
|
7784
|
+
let deletions = 0;
|
|
7785
|
+
for (const tool of tools) {
|
|
7786
|
+
const kind = classifyTool(tool.name);
|
|
7787
|
+
if (kind === "edit") {
|
|
7788
|
+
const path2 = tool.filePath ?? toolFilePath(tool.input);
|
|
7789
|
+
edited.push({
|
|
7790
|
+
name: path2 ? fileBasename(path2) : tool.name,
|
|
7791
|
+
running: tool.status === "running"
|
|
7792
|
+
});
|
|
7793
|
+
} else if (kind === "read") reads += 1;
|
|
7794
|
+
else if (kind === "search") searches += 1;
|
|
7795
|
+
else if (kind === "shell") shells += 1;
|
|
7796
|
+
else others += 1;
|
|
7797
|
+
if (typeof tool.additions === "number") additions += tool.additions;
|
|
7798
|
+
if (typeof tool.deletions === "number") deletions += tool.deletions;
|
|
7799
|
+
}
|
|
7800
|
+
const bits = [];
|
|
7801
|
+
const editing = edited.filter((e) => e.running);
|
|
7802
|
+
const editedDone = edited.filter((e) => !e.running);
|
|
7803
|
+
if (editing.length === 1) bits.push(`Editing ${editing[0].name}`);
|
|
7804
|
+
else if (editing.length > 1) bits.push(`Editing ${editing.length} files`);
|
|
7805
|
+
if (editedDone.length === 1) bits.push(`${editing.length ? "edited" : "Edited"} ${editedDone[0].name}`);
|
|
7806
|
+
else if (editedDone.length > 1) {
|
|
7807
|
+
bits.push(`${editing.length ? "edited" : "Edited"} ${editedDone.length} files`);
|
|
7808
|
+
}
|
|
7809
|
+
if (reads === 1) bits.push("explored 1 file");
|
|
7810
|
+
else if (reads > 1) bits.push(`explored ${reads} files`);
|
|
7811
|
+
if (searches === 1) bits.push("1 search");
|
|
7812
|
+
else if (searches > 1) bits.push(`${searches} searches`);
|
|
7813
|
+
if (shells === 1) bits.push("ran 1 command");
|
|
7814
|
+
else if (shells > 1) bits.push(`ran ${shells} commands`);
|
|
7815
|
+
if (others === 1) bits.push("1 tool");
|
|
7816
|
+
else if (others > 1) bits.push(`${others} tools`);
|
|
7817
|
+
if (bits.length === 0) return null;
|
|
7818
|
+
return { text: bits.join(", "), additions, deletions };
|
|
7819
|
+
}
|
|
7820
|
+
function liveActivitySummary(parts, opts) {
|
|
7821
|
+
if (opts?.queued && parts.length === 0) {
|
|
7822
|
+
return "Queued \u2014 waiting for a slot";
|
|
7823
|
+
}
|
|
7824
|
+
const tools = parts.filter((p) => p.type === "tool");
|
|
7825
|
+
const runningSubs = tools.filter(
|
|
7826
|
+
(t) => t.status === "running" && !t.parentId && isSubagentToolName(t.name)
|
|
7827
|
+
);
|
|
7828
|
+
const runningNested = [...tools].reverse().find((t) => t.status === "running" && t.parentId && !isPollWrapperToolName(t.name));
|
|
7829
|
+
const runningTop = [...tools].reverse().find(
|
|
7830
|
+
(t) => t.status === "running" && !t.parentId && !isPollWrapperToolName(t.name) && !isSubagentToolName(t.name)
|
|
7831
|
+
);
|
|
7832
|
+
const runningPoll = [...tools].reverse().find((t) => t.status === "running" && isPollWrapperToolName(t.name));
|
|
7833
|
+
const thinking = lastTextPart(parts, "thinking");
|
|
7834
|
+
const text4 = lastTextPart(parts, "text");
|
|
7835
|
+
if (runningSubs.length > 0) {
|
|
7836
|
+
const heads = runningSubs.map(toolLabel);
|
|
7837
|
+
const head = runningSubs.length === 1 ? heads[0] : `${runningSubs.length} subagents \xB7 ${heads.slice(0, 2).join(" \xB7 ")}`;
|
|
7838
|
+
if (runningNested) return `${head} \xB7 ${toolLabel(runningNested)}`;
|
|
7839
|
+
return head;
|
|
7840
|
+
}
|
|
7841
|
+
if (runningTop) return toolLabel(runningTop);
|
|
7842
|
+
if (runningPoll) return toolLabel(runningPoll);
|
|
7843
|
+
if (thinking) return thinking.length > 96 ? `\u2026${thinking.slice(-96)}` : thinking;
|
|
7844
|
+
if (text4) return "Writing reply\u2026";
|
|
7845
|
+
const last = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? tools.at(-1);
|
|
7846
|
+
if (last) {
|
|
7847
|
+
const label = toolLabel(last);
|
|
7848
|
+
return last.status === "running" ? label : `Finished ${label}`;
|
|
7849
|
+
}
|
|
7850
|
+
return "Working\u2026";
|
|
7851
|
+
}
|
|
7654
7852
|
function messagePartParentId(part) {
|
|
7655
7853
|
if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
|
|
7656
7854
|
return part.parentId;
|
|
@@ -7736,6 +7934,25 @@ function applyAgentEvent(parts, event) {
|
|
|
7736
7934
|
const data = event.data;
|
|
7737
7935
|
if (!data) return parts;
|
|
7738
7936
|
const next = [...parts];
|
|
7937
|
+
if (event.replace) {
|
|
7938
|
+
for (let i = next.length - 1; i >= 0; i--) {
|
|
7939
|
+
const prev = next[i];
|
|
7940
|
+
if (prev?.type === "thinking" && sameParentId(prev.parentId, event.parentId)) {
|
|
7941
|
+
next[i] = {
|
|
7942
|
+
type: "thinking",
|
|
7943
|
+
text: data,
|
|
7944
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
7945
|
+
};
|
|
7946
|
+
return next;
|
|
7947
|
+
}
|
|
7948
|
+
}
|
|
7949
|
+
next.push({
|
|
7950
|
+
type: "thinking",
|
|
7951
|
+
text: data,
|
|
7952
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
7953
|
+
});
|
|
7954
|
+
return next;
|
|
7955
|
+
}
|
|
7739
7956
|
const last = next[next.length - 1];
|
|
7740
7957
|
if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
|
|
7741
7958
|
next[next.length - 1] = {
|
|
@@ -7759,14 +7976,18 @@ function applyAgentEvent(parts, event) {
|
|
|
7759
7976
|
if (existing >= 0) {
|
|
7760
7977
|
const prev = parts[existing];
|
|
7761
7978
|
const next = [...parts];
|
|
7762
|
-
const mergedInput =
|
|
7979
|
+
const mergedInput = {
|
|
7980
|
+
...prev.input ?? {},
|
|
7981
|
+
...input ?? {}
|
|
7982
|
+
};
|
|
7983
|
+
const mergedRecord = Object.keys(mergedInput).length > 0 ? mergedInput : void 0;
|
|
7763
7984
|
next[existing] = {
|
|
7764
7985
|
...prev,
|
|
7765
7986
|
name: event.name || prev.name,
|
|
7766
|
-
input:
|
|
7767
|
-
description: toolDescription(event.name || prev.name,
|
|
7768
|
-
detail: toolDetail(event.name || prev.name,
|
|
7769
|
-
filePath: toolFilePath(
|
|
7987
|
+
input: mergedRecord,
|
|
7988
|
+
description: toolDescription(event.name || prev.name, mergedRecord),
|
|
7989
|
+
detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
|
|
7990
|
+
filePath: toolFilePath(mergedRecord) ?? prev.filePath,
|
|
7770
7991
|
additions: diff.additions ?? prev.additions,
|
|
7771
7992
|
deletions: diff.deletions ?? prev.deletions,
|
|
7772
7993
|
parentId: event.parentId ?? prev.parentId
|
|
@@ -7884,47 +8105,68 @@ function electronResourcesPath() {
|
|
|
7884
8105
|
function packagedCursorRuntimeDir() {
|
|
7885
8106
|
const resources = electronResourcesPath();
|
|
7886
8107
|
if (!resources) return null;
|
|
7887
|
-
const dir = (0,
|
|
7888
|
-
if (!(0,
|
|
8108
|
+
const dir = (0, import_node_path23.join)(resources, "cursor-runtime");
|
|
8109
|
+
if (!(0, import_node_fs22.existsSync)((0, import_node_path23.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
|
|
7889
8110
|
return dir;
|
|
7890
8111
|
}
|
|
7891
8112
|
function packagedCursorRunnerPath() {
|
|
7892
8113
|
const dir = packagedCursorRuntimeDir();
|
|
7893
|
-
return dir ? (0,
|
|
8114
|
+
return dir ? (0, import_node_path23.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
|
|
7894
8115
|
}
|
|
7895
8116
|
function packagedMcpDir() {
|
|
7896
8117
|
const resources = electronResourcesPath();
|
|
7897
8118
|
if (!resources) return null;
|
|
7898
|
-
const dir = (0,
|
|
7899
|
-
if (!(0,
|
|
8119
|
+
const dir = (0, import_node_path23.join)(resources, "sideboard-mcp");
|
|
8120
|
+
if (!(0, import_node_fs22.existsSync)((0, import_node_path23.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
|
|
7900
8121
|
return dir;
|
|
7901
8122
|
}
|
|
7902
8123
|
function packagedMcpStdioPath() {
|
|
7903
8124
|
const dir = packagedMcpDir();
|
|
7904
|
-
return dir ? (0,
|
|
8125
|
+
return dir ? (0, import_node_path23.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
|
|
7905
8126
|
}
|
|
7906
8127
|
function packagedBundledNodePath() {
|
|
7907
8128
|
const resources = electronResourcesPath();
|
|
7908
8129
|
if (!resources) return null;
|
|
7909
|
-
const bin = (0,
|
|
7910
|
-
if (!(0,
|
|
8130
|
+
const bin = (0, import_node_path23.join)(resources, "node", "bin", "node");
|
|
8131
|
+
if (!(0, import_node_fs22.existsSync)(bin)) return null;
|
|
7911
8132
|
return bin;
|
|
7912
8133
|
}
|
|
7913
8134
|
function packagedCursorRipgrepCandidate(platformPkg, binName) {
|
|
7914
8135
|
const dir = packagedCursorRuntimeDir();
|
|
7915
8136
|
if (!dir) return null;
|
|
7916
|
-
return (0,
|
|
8137
|
+
return (0, import_node_path23.join)(dir, "node_modules", platformPkg, "bin", binName);
|
|
7917
8138
|
}
|
|
7918
|
-
var
|
|
8139
|
+
var import_node_fs22, import_node_path23;
|
|
7919
8140
|
var init_packaged_runtime = __esm({
|
|
7920
8141
|
"src/agents/packaged-runtime.ts"() {
|
|
7921
8142
|
"use strict";
|
|
7922
|
-
|
|
7923
|
-
|
|
8143
|
+
import_node_fs22 = require("fs");
|
|
8144
|
+
import_node_path23 = require("path");
|
|
7924
8145
|
}
|
|
7925
8146
|
});
|
|
7926
8147
|
|
|
7927
8148
|
// src/agents/node-launch.ts
|
|
8149
|
+
function withMaxOldSpaceSize(nodeOptions, heapMb) {
|
|
8150
|
+
const existing = (nodeOptions ?? "").trim();
|
|
8151
|
+
const match = MAX_OLD_SPACE_FLAG.exec(existing);
|
|
8152
|
+
if (match) {
|
|
8153
|
+
const current = match[2] ? Number(match[2]) : 0;
|
|
8154
|
+
if (Number.isFinite(current) && current >= heapMb) return existing;
|
|
8155
|
+
return existing.replace(MAX_OLD_SPACE_FLAG, ` --max-old-space-size=${heapMb}`).trim();
|
|
8156
|
+
}
|
|
8157
|
+
return existing ? `${existing} --max-old-space-size=${heapMb}` : `--max-old-space-size=${heapMb}`;
|
|
8158
|
+
}
|
|
8159
|
+
function applyAgentRunnerHeapEnv(env) {
|
|
8160
|
+
env.NODE_OPTIONS = withMaxOldSpaceSize(
|
|
8161
|
+
env.NODE_OPTIONS,
|
|
8162
|
+
AGENT_RUNNER_MAX_OLD_SPACE_MB
|
|
8163
|
+
);
|
|
8164
|
+
}
|
|
8165
|
+
function envWithAgentHeap(env) {
|
|
8166
|
+
const next = { ...env };
|
|
8167
|
+
applyAgentRunnerHeapEnv(next);
|
|
8168
|
+
return next;
|
|
8169
|
+
}
|
|
7928
8170
|
function isAsarPath(filePath) {
|
|
7929
8171
|
if (/\.asar\.unpacked([/\\]|$)/.test(filePath)) return false;
|
|
7930
8172
|
return /\.asar([/\\]|$)/.test(filePath);
|
|
@@ -7933,7 +8175,7 @@ function unpackedAsarPath(filePath) {
|
|
|
7933
8175
|
if (!isAsarPath(filePath)) return null;
|
|
7934
8176
|
const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
|
|
7935
8177
|
if (unpacked === filePath) return null;
|
|
7936
|
-
return (0,
|
|
8178
|
+
return (0, import_node_fs23.existsSync)(unpacked) ? unpacked : null;
|
|
7937
8179
|
}
|
|
7938
8180
|
function nodeReadableScriptPath(scriptPath) {
|
|
7939
8181
|
return unpackedAsarPath(scriptPath) ?? scriptPath;
|
|
@@ -7973,37 +8215,37 @@ function pickPreferredNode(candidates) {
|
|
|
7973
8215
|
return best;
|
|
7974
8216
|
}
|
|
7975
8217
|
function versionDirNodeBins(root, toBin) {
|
|
7976
|
-
if (!(0,
|
|
8218
|
+
if (!(0, import_node_fs23.existsSync)(root)) return [];
|
|
7977
8219
|
try {
|
|
7978
|
-
return (0,
|
|
8220
|
+
return (0, import_node_fs23.readdirSync)(root).map(toBin);
|
|
7979
8221
|
} catch {
|
|
7980
8222
|
return [];
|
|
7981
8223
|
}
|
|
7982
8224
|
}
|
|
7983
8225
|
function defaultNodeBinCandidates(home = (0, import_node_os7.homedir)()) {
|
|
7984
8226
|
const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
|
|
7985
|
-
(prefix) => PREFERRED_LTS_MAJORS.map((major) => (0,
|
|
8227
|
+
(prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path24.join)(prefix, "opt", `node@${major}`, "bin", "node"))
|
|
7986
8228
|
);
|
|
7987
8229
|
return [
|
|
7988
8230
|
...kegs,
|
|
7989
8231
|
"/opt/homebrew/bin/node",
|
|
7990
8232
|
"/usr/local/bin/node",
|
|
7991
|
-
(0,
|
|
7992
|
-
(0,
|
|
7993
|
-
(0,
|
|
7994
|
-
(0,
|
|
7995
|
-
(0,
|
|
8233
|
+
(0, import_node_path24.join)(home, ".local/share/fnm/aliases/default/bin/node"),
|
|
8234
|
+
(0, import_node_path24.join)(home, ".nvm/current/bin/node"),
|
|
8235
|
+
(0, import_node_path24.join)(home, ".volta/bin/node"),
|
|
8236
|
+
(0, import_node_path24.join)(home, ".asdf/shims/node"),
|
|
8237
|
+
(0, import_node_path24.join)(home, ".local/share/mise/shims/node"),
|
|
7996
8238
|
...versionDirNodeBins(
|
|
7997
|
-
(0,
|
|
7998
|
-
(name) => (0,
|
|
8239
|
+
(0, import_node_path24.join)(home, ".nvm", "versions", "node"),
|
|
8240
|
+
(name) => (0, import_node_path24.join)(home, ".nvm", "versions", "node", name, "bin", "node")
|
|
7999
8241
|
),
|
|
8000
8242
|
...versionDirNodeBins(
|
|
8001
|
-
(0,
|
|
8002
|
-
(name) => (0,
|
|
8243
|
+
(0, import_node_path24.join)(home, ".local/share/fnm", "node-versions"),
|
|
8244
|
+
(name) => (0, import_node_path24.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
|
|
8003
8245
|
),
|
|
8004
8246
|
...versionDirNodeBins(
|
|
8005
|
-
(0,
|
|
8006
|
-
(name) => (0,
|
|
8247
|
+
(0, import_node_path24.join)(home, ".volta", "tools", "image", "node"),
|
|
8248
|
+
(name) => (0, import_node_path24.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
|
|
8007
8249
|
)
|
|
8008
8250
|
];
|
|
8009
8251
|
}
|
|
@@ -8012,10 +8254,10 @@ function uniqueExistingNodeBins(paths) {
|
|
|
8012
8254
|
const out = [];
|
|
8013
8255
|
for (const raw of paths) {
|
|
8014
8256
|
const p = raw.trim();
|
|
8015
|
-
if (!p || !(0,
|
|
8257
|
+
if (!p || !(0, import_node_fs23.existsSync)(p) || isElectronLikeCommand(p)) continue;
|
|
8016
8258
|
let key = p;
|
|
8017
8259
|
try {
|
|
8018
|
-
key = (0,
|
|
8260
|
+
key = (0, import_node_fs23.realpathSync)(p);
|
|
8019
8261
|
} catch {
|
|
8020
8262
|
continue;
|
|
8021
8263
|
}
|
|
@@ -8060,13 +8302,21 @@ async function findSystemNode() {
|
|
|
8060
8302
|
function applyNodeLaunch(launch, args) {
|
|
8061
8303
|
const readableArgs = args.map(nodeReadableScriptPath);
|
|
8062
8304
|
if (!launch.env.ELECTRON_RUN_AS_NODE) {
|
|
8063
|
-
return {
|
|
8305
|
+
return {
|
|
8306
|
+
file: launch.file,
|
|
8307
|
+
args: readableArgs,
|
|
8308
|
+
env: envWithAgentHeap(launch.env)
|
|
8309
|
+
};
|
|
8064
8310
|
}
|
|
8065
8311
|
const wrapped = wrapElectronAsNodeLaunch(launch.file, readableArgs);
|
|
8066
8312
|
if (process.platform === "win32") {
|
|
8067
|
-
return {
|
|
8313
|
+
return {
|
|
8314
|
+
file: wrapped.file,
|
|
8315
|
+
args: wrapped.args,
|
|
8316
|
+
env: envWithAgentHeap(launch.env)
|
|
8317
|
+
};
|
|
8068
8318
|
}
|
|
8069
|
-
const env =
|
|
8319
|
+
const env = envWithAgentHeap(launch.env);
|
|
8070
8320
|
delete env.ELECTRON_RUN_AS_NODE;
|
|
8071
8321
|
return { file: wrapped.file, args: wrapped.args, env };
|
|
8072
8322
|
}
|
|
@@ -8087,16 +8337,18 @@ async function resolveNodeLaunch(scriptPath) {
|
|
|
8087
8337
|
env: { ELECTRON_RUN_AS_NODE: "1" }
|
|
8088
8338
|
};
|
|
8089
8339
|
}
|
|
8090
|
-
var
|
|
8340
|
+
var import_node_fs23, import_node_os7, import_node_path24, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
|
|
8091
8341
|
var init_node_launch = __esm({
|
|
8092
8342
|
"src/agents/node-launch.ts"() {
|
|
8093
8343
|
"use strict";
|
|
8094
|
-
|
|
8344
|
+
import_node_fs23 = require("fs");
|
|
8095
8345
|
import_node_os7 = require("os");
|
|
8096
|
-
|
|
8346
|
+
import_node_path24 = require("path");
|
|
8097
8347
|
init_nested_electron_env();
|
|
8098
8348
|
init_run();
|
|
8099
8349
|
init_packaged_runtime();
|
|
8350
|
+
AGENT_RUNNER_MAX_OLD_SPACE_MB = 8192;
|
|
8351
|
+
MAX_OLD_SPACE_FLAG = /(?:^|\s)(--max[-_]old[-_]space[-_]size)(?:[= ](\d+))?(?=\s|$)/;
|
|
8100
8352
|
PREFERRED_LTS_MAJORS = [24, 22, 20];
|
|
8101
8353
|
}
|
|
8102
8354
|
});
|
|
@@ -8184,37 +8436,37 @@ function corePackageDir() {
|
|
|
8184
8436
|
try {
|
|
8185
8437
|
const url = import_meta.url;
|
|
8186
8438
|
if (typeof url === "string" && url.length > 0) {
|
|
8187
|
-
return (0,
|
|
8439
|
+
return (0, import_node_path25.dirname)((0, import_node_url.fileURLToPath)(url));
|
|
8188
8440
|
}
|
|
8189
8441
|
} catch {
|
|
8190
8442
|
}
|
|
8191
8443
|
try {
|
|
8192
|
-
const req = (0, import_node_module.createRequire)((0,
|
|
8193
|
-
return (0,
|
|
8444
|
+
const req = (0, import_node_module.createRequire)((0, import_node_path25.join)(process.cwd(), "package.json"));
|
|
8445
|
+
return (0, import_node_path25.dirname)(req.resolve("@sideboard-ai/core"));
|
|
8194
8446
|
} catch {
|
|
8195
8447
|
return process.cwd();
|
|
8196
8448
|
}
|
|
8197
8449
|
}
|
|
8198
8450
|
function findSideboardMcpJsEntry() {
|
|
8199
8451
|
const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
|
|
8200
|
-
if (override && (0,
|
|
8452
|
+
if (override && (0, import_node_fs24.existsSync)(override)) return override;
|
|
8201
8453
|
const packaged = packagedMcpStdioPath();
|
|
8202
8454
|
if (packaged) return packaged;
|
|
8203
8455
|
let dir = corePackageDir();
|
|
8204
8456
|
for (let i = 0; i < 10; i++) {
|
|
8205
8457
|
const candidates = [
|
|
8206
|
-
(0,
|
|
8207
|
-
(0,
|
|
8208
|
-
(0,
|
|
8209
|
-
(0,
|
|
8210
|
-
(0,
|
|
8211
|
-
(0,
|
|
8212
|
-
(0,
|
|
8458
|
+
(0, import_node_path25.join)(dir, "mcp/run-stdio.js"),
|
|
8459
|
+
(0, import_node_path25.join)(dir, "mcp/run-stdio.cjs"),
|
|
8460
|
+
(0, import_node_path25.join)(dir, "dist/mcp/run-stdio.js"),
|
|
8461
|
+
(0, import_node_path25.join)(dir, "dist/mcp/run-stdio.cjs"),
|
|
8462
|
+
(0, import_node_path25.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
8463
|
+
(0, import_node_path25.join)(dir, "packages/cli/dist/index.js"),
|
|
8464
|
+
(0, import_node_path25.join)(dir, "cli/dist/index.js")
|
|
8213
8465
|
];
|
|
8214
8466
|
for (const p of candidates) {
|
|
8215
|
-
if ((0,
|
|
8467
|
+
if ((0, import_node_fs24.existsSync)(p) && !isAsarPath(p)) return p;
|
|
8216
8468
|
}
|
|
8217
|
-
const parent = (0,
|
|
8469
|
+
const parent = (0, import_node_path25.dirname)(dir);
|
|
8218
8470
|
if (parent === dir) break;
|
|
8219
8471
|
dir = parent;
|
|
8220
8472
|
}
|
|
@@ -8262,6 +8514,7 @@ async function buildInjectedMcpServers(opts) {
|
|
|
8262
8514
|
);
|
|
8263
8515
|
} catch {
|
|
8264
8516
|
}
|
|
8517
|
+
applyAgentRunnerHeapEnv(sideboard.env);
|
|
8265
8518
|
servers.push(sideboard);
|
|
8266
8519
|
}
|
|
8267
8520
|
if (opts.includeBrightsy && isBrightsyConnected()) {
|
|
@@ -8355,22 +8608,22 @@ function writeMcpServersConfig(servers) {
|
|
|
8355
8608
|
...env ? { env } : {}
|
|
8356
8609
|
};
|
|
8357
8610
|
}
|
|
8358
|
-
const dir = (0,
|
|
8359
|
-
const cfgPath = (0,
|
|
8360
|
-
(0,
|
|
8611
|
+
const dir = (0, import_node_fs24.mkdtempSync)((0, import_node_path25.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
|
|
8612
|
+
const cfgPath = (0, import_node_path25.join)(dir, "mcp.json");
|
|
8613
|
+
(0, import_node_fs24.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
|
|
8361
8614
|
return cfgPath;
|
|
8362
8615
|
}
|
|
8363
8616
|
async function writeInjectedMcpConfig(opts) {
|
|
8364
8617
|
return writeMcpServersConfig(await buildInjectedMcpServers(opts));
|
|
8365
8618
|
}
|
|
8366
|
-
var
|
|
8619
|
+
var import_node_fs24, import_node_module, import_node_os8, import_node_path25, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
|
|
8367
8620
|
var init_injected_mcp = __esm({
|
|
8368
8621
|
"src/agents/injected-mcp.ts"() {
|
|
8369
8622
|
"use strict";
|
|
8370
|
-
|
|
8623
|
+
import_node_fs24 = require("fs");
|
|
8371
8624
|
import_node_module = require("module");
|
|
8372
8625
|
import_node_os8 = require("os");
|
|
8373
|
-
|
|
8626
|
+
import_node_path25 = require("path");
|
|
8374
8627
|
import_node_url = require("url");
|
|
8375
8628
|
init_run();
|
|
8376
8629
|
init_config();
|
|
@@ -8548,6 +8801,80 @@ function claudeParentToolUseId(obj) {
|
|
|
8548
8801
|
}
|
|
8549
8802
|
return void 0;
|
|
8550
8803
|
}
|
|
8804
|
+
function claudeString(obj, key) {
|
|
8805
|
+
const v = obj[key];
|
|
8806
|
+
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
8807
|
+
}
|
|
8808
|
+
function eventsFromClaudeSystem(obj) {
|
|
8809
|
+
const subtype = claudeString(obj, "subtype") ?? "";
|
|
8810
|
+
const parentId = claudeParentToolUseId(obj);
|
|
8811
|
+
if (subtype === "init") {
|
|
8812
|
+
if (parentId) return null;
|
|
8813
|
+
const sid = claudeString(obj, "session_id");
|
|
8814
|
+
return sid ? { type: "session_id", data: sid } : null;
|
|
8815
|
+
}
|
|
8816
|
+
if (subtype === "task_started") {
|
|
8817
|
+
const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id");
|
|
8818
|
+
if (!id) return null;
|
|
8819
|
+
const description = claudeString(obj, "description");
|
|
8820
|
+
const taskType = claudeString(obj, "task_type");
|
|
8821
|
+
const prompt = claudeString(obj, "prompt");
|
|
8822
|
+
return withEventParentId(
|
|
8823
|
+
{
|
|
8824
|
+
type: "tool_use",
|
|
8825
|
+
id,
|
|
8826
|
+
name: taskType || "Agent",
|
|
8827
|
+
input: {
|
|
8828
|
+
...description ? { description } : {},
|
|
8829
|
+
...prompt ? { prompt } : {},
|
|
8830
|
+
...claudeString(obj, "task_id") ? { task_id: claudeString(obj, "task_id") } : {}
|
|
8831
|
+
}
|
|
8832
|
+
},
|
|
8833
|
+
parentId
|
|
8834
|
+
);
|
|
8835
|
+
}
|
|
8836
|
+
if (subtype === "task_notification") {
|
|
8837
|
+
const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id") ?? parentId;
|
|
8838
|
+
if (!id) return null;
|
|
8839
|
+
const status = claudeString(obj, "status") ?? "working";
|
|
8840
|
+
const tools = typeof obj.tool_uses === "number" ? obj.tool_uses : void 0;
|
|
8841
|
+
const durationMs = typeof obj.duration_ms === "number" ? obj.duration_ms : void 0;
|
|
8842
|
+
const lastTool = claudeString(obj, "last_tool") ?? claudeString(obj, "current_tool") ?? claudeString(obj, "tool");
|
|
8843
|
+
const snapshot = [
|
|
8844
|
+
status,
|
|
8845
|
+
tools != null ? `${tools} tools` : null,
|
|
8846
|
+
durationMs != null ? `${Math.round(durationMs / 1e3)}s` : null,
|
|
8847
|
+
lastTool
|
|
8848
|
+
].filter((bit) => Boolean(bit)).join(" \xB7 ");
|
|
8849
|
+
return [
|
|
8850
|
+
{
|
|
8851
|
+
type: "tool_use",
|
|
8852
|
+
id,
|
|
8853
|
+
name: claudeString(obj, "task_type") || "Agent",
|
|
8854
|
+
input: {
|
|
8855
|
+
live_status: status,
|
|
8856
|
+
...tools != null ? { live_tool_uses: tools } : {},
|
|
8857
|
+
...durationMs != null ? { live_duration_ms: durationMs } : {},
|
|
8858
|
+
...lastTool ? { live_last_tool: lastTool } : {}
|
|
8859
|
+
}
|
|
8860
|
+
},
|
|
8861
|
+
withEventParentId(
|
|
8862
|
+
{ type: "thinking", data: snapshot, replace: true },
|
|
8863
|
+
id
|
|
8864
|
+
)
|
|
8865
|
+
];
|
|
8866
|
+
}
|
|
8867
|
+
if (subtype === "api_retry") {
|
|
8868
|
+
const attempt = obj.attempt;
|
|
8869
|
+
const max = obj.max_retries;
|
|
8870
|
+
const delay = obj.retry_delay_ms;
|
|
8871
|
+
return {
|
|
8872
|
+
type: "thinking",
|
|
8873
|
+
data: `API retry ${attempt ?? "?"}/${max ?? "?"}${typeof delay === "number" ? ` (wait ${delay}ms)` : ""}`
|
|
8874
|
+
};
|
|
8875
|
+
}
|
|
8876
|
+
return null;
|
|
8877
|
+
}
|
|
8551
8878
|
function parseIssuesJson(raw) {
|
|
8552
8879
|
const text4 = raw.trim();
|
|
8553
8880
|
const candidates = [text4];
|
|
@@ -8573,11 +8900,11 @@ function parseIssuesJson(raw) {
|
|
|
8573
8900
|
}
|
|
8574
8901
|
return [];
|
|
8575
8902
|
}
|
|
8576
|
-
var
|
|
8903
|
+
var import_node_fs25, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
|
|
8577
8904
|
var init_claude = __esm({
|
|
8578
8905
|
"src/agents/claude.ts"() {
|
|
8579
8906
|
"use strict";
|
|
8580
|
-
|
|
8907
|
+
import_node_fs25 = require("fs");
|
|
8581
8908
|
init_run();
|
|
8582
8909
|
init_app_settings();
|
|
8583
8910
|
init_claude_mcp();
|
|
@@ -8597,8 +8924,14 @@ var init_claude = __esm({
|
|
|
8597
8924
|
"WebSearch",
|
|
8598
8925
|
// Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
|
|
8599
8926
|
"Task",
|
|
8600
|
-
"Agent"
|
|
8927
|
+
"Agent",
|
|
8928
|
+
"TaskOutput",
|
|
8929
|
+
"TaskStop",
|
|
8930
|
+
"EnterWorktree",
|
|
8931
|
+
"ExitWorktree",
|
|
8932
|
+
"Skill"
|
|
8601
8933
|
];
|
|
8934
|
+
CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
|
|
8602
8935
|
CLAUDE_CHROME_ALLOWED_TOOLS = [
|
|
8603
8936
|
"mcp__claude-in-chrome",
|
|
8604
8937
|
"mcp__claude-in-chrome__*",
|
|
@@ -8610,7 +8943,7 @@ var init_claude = __esm({
|
|
|
8610
8943
|
async detect() {
|
|
8611
8944
|
const claude = resolveClaudeExecutable();
|
|
8612
8945
|
if (claude !== "claude") {
|
|
8613
|
-
if (!(0,
|
|
8946
|
+
if (!(0, import_node_fs25.existsSync)(claude)) {
|
|
8614
8947
|
return {
|
|
8615
8948
|
agent: "claude",
|
|
8616
8949
|
installed: false,
|
|
@@ -8727,7 +9060,12 @@ var init_claude = __esm({
|
|
|
8727
9060
|
stdin: useStdin ? `${promptText}
|
|
8728
9061
|
` : void 0,
|
|
8729
9062
|
// Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
|
|
8730
|
-
|
|
9063
|
+
// Raise the -p background-agent wait so long TaskOutput polls are not
|
|
9064
|
+
// abandoned at Claude Code’s 10-minute default.
|
|
9065
|
+
env: {
|
|
9066
|
+
CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
|
|
9067
|
+
CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS)
|
|
9068
|
+
}
|
|
8731
9069
|
};
|
|
8732
9070
|
},
|
|
8733
9071
|
parseEvent(line) {
|
|
@@ -8735,13 +9073,8 @@ var init_claude = __esm({
|
|
|
8735
9073
|
if (!trimmed) return null;
|
|
8736
9074
|
try {
|
|
8737
9075
|
const obj = JSON.parse(trimmed);
|
|
8738
|
-
if (obj.type === "system"
|
|
8739
|
-
|
|
8740
|
-
if (typeof sid === "string") return { type: "session_id", data: sid };
|
|
8741
|
-
return null;
|
|
8742
|
-
}
|
|
8743
|
-
if (obj.type === "system" && typeof obj.session_id === "string") {
|
|
8744
|
-
return { type: "session_id", data: obj.session_id };
|
|
9076
|
+
if (obj.type === "system") {
|
|
9077
|
+
return eventsFromClaudeSystem(obj);
|
|
8745
9078
|
}
|
|
8746
9079
|
if (obj.type === "assistant" || obj.type === "user") {
|
|
8747
9080
|
const parentId = claudeParentToolUseId(obj);
|
|
@@ -8861,7 +9194,7 @@ async function listCodexModels() {
|
|
|
8861
9194
|
if (codex === "codex") {
|
|
8862
9195
|
const which = await run("which", ["codex"], { reject: false });
|
|
8863
9196
|
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
8864
|
-
} else if (!(0,
|
|
9197
|
+
} else if (!(0, import_node_fs26.existsSync)(codex)) {
|
|
8865
9198
|
return FALLBACK_CODEX_MODELS;
|
|
8866
9199
|
}
|
|
8867
9200
|
const listed = await run(codex, ["debug", "models"], { reject: false });
|
|
@@ -8896,12 +9229,12 @@ function usageFromCodex(usage) {
|
|
|
8896
9229
|
}
|
|
8897
9230
|
function codexConfigHasNetworkAccess() {
|
|
8898
9231
|
const candidates = [
|
|
8899
|
-
(0,
|
|
8900
|
-
(0,
|
|
9232
|
+
(0, import_node_path26.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
|
|
9233
|
+
(0, import_node_path26.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
|
|
8901
9234
|
];
|
|
8902
9235
|
for (const path2 of candidates) {
|
|
8903
|
-
if (!(0,
|
|
8904
|
-
const text4 = (0,
|
|
9236
|
+
if (!(0, import_node_fs26.existsSync)(path2)) continue;
|
|
9237
|
+
const text4 = (0, import_node_fs26.readFileSync)(path2, "utf8");
|
|
8905
9238
|
if (/network_access\s*=\s*true/.test(text4)) return true;
|
|
8906
9239
|
}
|
|
8907
9240
|
return false;
|
|
@@ -8933,21 +9266,21 @@ function asRecord2(value) {
|
|
|
8933
9266
|
return void 0;
|
|
8934
9267
|
}
|
|
8935
9268
|
function codexLooksAuthenticated() {
|
|
8936
|
-
const authPath = (0,
|
|
8937
|
-
if (!(0,
|
|
9269
|
+
const authPath = (0, import_node_path26.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
|
|
9270
|
+
if (!(0, import_node_fs26.existsSync)(authPath)) return false;
|
|
8938
9271
|
try {
|
|
8939
|
-
return (0,
|
|
9272
|
+
return (0, import_node_fs26.statSync)(authPath).size > 2;
|
|
8940
9273
|
} catch {
|
|
8941
9274
|
return false;
|
|
8942
9275
|
}
|
|
8943
9276
|
}
|
|
8944
|
-
var
|
|
9277
|
+
var import_node_fs26, import_node_os9, import_node_path26, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
8945
9278
|
var init_codex = __esm({
|
|
8946
9279
|
"src/agents/codex.ts"() {
|
|
8947
9280
|
"use strict";
|
|
8948
|
-
|
|
9281
|
+
import_node_fs26 = require("fs");
|
|
8949
9282
|
import_node_os9 = require("os");
|
|
8950
|
-
|
|
9283
|
+
import_node_path26 = require("path");
|
|
8951
9284
|
init_run();
|
|
8952
9285
|
init_app_settings();
|
|
8953
9286
|
init_global_workspace();
|
|
@@ -8972,7 +9305,7 @@ var init_codex = __esm({
|
|
|
8972
9305
|
async detect() {
|
|
8973
9306
|
const codex = resolveAgentExecutable("codex");
|
|
8974
9307
|
if (codex !== "codex") {
|
|
8975
|
-
if (!(0,
|
|
9308
|
+
if (!(0, import_node_fs26.existsSync)(codex)) {
|
|
8976
9309
|
return {
|
|
8977
9310
|
agent: "codex",
|
|
8978
9311
|
installed: false,
|
|
@@ -9161,9 +9494,6 @@ var init_codex = __esm({
|
|
|
9161
9494
|
if (sid && (type === "thread.started" || type === "session" || !type)) {
|
|
9162
9495
|
return { type: "session_id", data: sid };
|
|
9163
9496
|
}
|
|
9164
|
-
if (sid && type.endsWith(".started")) {
|
|
9165
|
-
return { type: "session_id", data: sid };
|
|
9166
|
-
}
|
|
9167
9497
|
if (type === "turn.completed" || type === "turn_completed") {
|
|
9168
9498
|
const usage = usageFromCodex(obj.usage);
|
|
9169
9499
|
return usage ? { type: "usage", data: usage, scope: "turn" } : null;
|
|
@@ -9411,21 +9741,21 @@ function platformRipgrepPackage() {
|
|
|
9411
9741
|
}
|
|
9412
9742
|
function usableRipgrepPath(candidate) {
|
|
9413
9743
|
const raw = candidate?.trim();
|
|
9414
|
-
if (!raw || !(0,
|
|
9744
|
+
if (!raw || !(0, import_node_path27.isAbsolute)(raw)) return null;
|
|
9415
9745
|
const readable = nodeReadableScriptPath(raw);
|
|
9416
|
-
if (!(0,
|
|
9746
|
+
if (!(0, import_node_fs27.existsSync)(readable) || isAsarPath(readable)) return null;
|
|
9417
9747
|
return readable;
|
|
9418
9748
|
}
|
|
9419
9749
|
function walkForBundledRipgrep(startFile) {
|
|
9420
9750
|
if (!startFile) return null;
|
|
9421
9751
|
const pkg = platformRipgrepPackage();
|
|
9422
9752
|
const name = rgBinaryName();
|
|
9423
|
-
let dir = (0,
|
|
9424
|
-
const root = (0,
|
|
9753
|
+
let dir = (0, import_node_path27.dirname)((0, import_node_path27.resolve)(startFile));
|
|
9754
|
+
const root = (0, import_node_path27.parse)(dir).root;
|
|
9425
9755
|
while (dir !== root) {
|
|
9426
|
-
const hit = usableRipgrepPath((0,
|
|
9756
|
+
const hit = usableRipgrepPath((0, import_node_path27.join)(dir, "node_modules", pkg, "bin", name));
|
|
9427
9757
|
if (hit) return hit;
|
|
9428
|
-
const next = (0,
|
|
9758
|
+
const next = (0, import_node_path27.dirname)(dir);
|
|
9429
9759
|
if (next === dir) break;
|
|
9430
9760
|
dir = next;
|
|
9431
9761
|
}
|
|
@@ -9435,7 +9765,7 @@ function requireResolveBundledRipgrep(fromFile) {
|
|
|
9435
9765
|
try {
|
|
9436
9766
|
const req = (0, import_node_module2.createRequire)(fromFile);
|
|
9437
9767
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
9438
|
-
return usableRipgrepPath((0,
|
|
9768
|
+
return usableRipgrepPath((0, import_node_path27.join)((0, import_node_path27.dirname)(pkgJson), "bin", rgBinaryName()));
|
|
9439
9769
|
} catch {
|
|
9440
9770
|
return null;
|
|
9441
9771
|
}
|
|
@@ -9457,13 +9787,13 @@ function cursorRipgrepEnv(opts) {
|
|
|
9457
9787
|
const path2 = resolveCursorRipgrepPath(opts);
|
|
9458
9788
|
return path2 ? { [RIPGREP_ENV]: path2 } : {};
|
|
9459
9789
|
}
|
|
9460
|
-
var
|
|
9790
|
+
var import_node_fs27, import_node_module2, import_node_path27, RIPGREP_ENV;
|
|
9461
9791
|
var init_cursor_ripgrep = __esm({
|
|
9462
9792
|
"src/agents/cursor-ripgrep.ts"() {
|
|
9463
9793
|
"use strict";
|
|
9464
|
-
|
|
9794
|
+
import_node_fs27 = require("fs");
|
|
9465
9795
|
import_node_module2 = require("module");
|
|
9466
|
-
|
|
9796
|
+
import_node_path27 = require("path");
|
|
9467
9797
|
init_node_launch();
|
|
9468
9798
|
init_packaged_runtime();
|
|
9469
9799
|
RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
@@ -9509,11 +9839,11 @@ function entryDir() {
|
|
|
9509
9839
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
9510
9840
|
if (cjsDir) return cjsDir;
|
|
9511
9841
|
try {
|
|
9512
|
-
return (0,
|
|
9842
|
+
return (0, import_node_path28.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
9513
9843
|
} catch {
|
|
9514
9844
|
try {
|
|
9515
9845
|
const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
|
|
9516
|
-
return (0,
|
|
9846
|
+
return (0, import_node_path28.dirname)(req.resolve("@sideboard-ai/core"));
|
|
9517
9847
|
} catch {
|
|
9518
9848
|
return process.cwd();
|
|
9519
9849
|
}
|
|
@@ -9524,27 +9854,27 @@ function cursorRunnerPath() {
|
|
|
9524
9854
|
if (packaged) return packaged;
|
|
9525
9855
|
const root = entryDir();
|
|
9526
9856
|
const candidates = [
|
|
9527
|
-
(0,
|
|
9528
|
-
(0,
|
|
9857
|
+
(0, import_node_path28.join)(root, "agents", "cursor-runner.js"),
|
|
9858
|
+
(0, import_node_path28.join)(root, "agents", "cursor-runner.cjs"),
|
|
9529
9859
|
// If somehow resolved from package root instead of dist/
|
|
9530
|
-
(0,
|
|
9531
|
-
(0,
|
|
9860
|
+
(0, import_node_path28.join)(root, "dist", "agents", "cursor-runner.js"),
|
|
9861
|
+
(0, import_node_path28.join)(root, "dist", "agents", "cursor-runner.cjs"),
|
|
9532
9862
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
9533
|
-
(0,
|
|
9534
|
-
(0,
|
|
9863
|
+
(0, import_node_path28.join)(root, "cursor-runner.ts"),
|
|
9864
|
+
(0, import_node_path28.join)(root, "src", "agents", "cursor-runner.ts")
|
|
9535
9865
|
];
|
|
9536
9866
|
for (const candidate of candidates) {
|
|
9537
|
-
if ((0,
|
|
9867
|
+
if ((0, import_node_fs28.existsSync)(candidate)) return candidate;
|
|
9538
9868
|
}
|
|
9539
9869
|
return candidates[0];
|
|
9540
9870
|
}
|
|
9541
|
-
var
|
|
9871
|
+
var import_node_fs28, import_node_module3, import_node_path28, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
|
|
9542
9872
|
var init_cursor = __esm({
|
|
9543
9873
|
"src/agents/cursor.ts"() {
|
|
9544
9874
|
"use strict";
|
|
9545
|
-
|
|
9875
|
+
import_node_fs28 = require("fs");
|
|
9546
9876
|
import_node_module3 = require("module");
|
|
9547
|
-
|
|
9877
|
+
import_node_path28 = require("path");
|
|
9548
9878
|
import_node_url2 = require("url");
|
|
9549
9879
|
import_sdk = require("@cursor/sdk");
|
|
9550
9880
|
init_run();
|
|
@@ -9694,7 +10024,7 @@ async function listOpencodeModels() {
|
|
|
9694
10024
|
if (opencode === "opencode") {
|
|
9695
10025
|
const which = await run("which", ["opencode"], { reject: false });
|
|
9696
10026
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
9697
|
-
} else if (!(0,
|
|
10027
|
+
} else if (!(0, import_node_fs29.existsSync)(opencode)) {
|
|
9698
10028
|
return FALLBACK_OPENCODE_MODELS;
|
|
9699
10029
|
}
|
|
9700
10030
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -9724,11 +10054,11 @@ function usageFromOpencode(tokens) {
|
|
|
9724
10054
|
cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
|
|
9725
10055
|
};
|
|
9726
10056
|
}
|
|
9727
|
-
var
|
|
10057
|
+
var import_node_fs29, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
|
|
9728
10058
|
var init_opencode = __esm({
|
|
9729
10059
|
"src/agents/opencode.ts"() {
|
|
9730
10060
|
"use strict";
|
|
9731
|
-
|
|
10061
|
+
import_node_fs29 = require("fs");
|
|
9732
10062
|
init_run();
|
|
9733
10063
|
init_app_settings();
|
|
9734
10064
|
init_global_workspace();
|
|
@@ -9755,7 +10085,7 @@ var init_opencode = __esm({
|
|
|
9755
10085
|
async detect() {
|
|
9756
10086
|
const opencode = resolveAgentExecutable("opencode");
|
|
9757
10087
|
if (opencode !== "opencode") {
|
|
9758
|
-
if (!(0,
|
|
10088
|
+
if (!(0, import_node_fs29.existsSync)(opencode)) {
|
|
9759
10089
|
return {
|
|
9760
10090
|
agent: "opencode",
|
|
9761
10091
|
installed: false,
|
|
@@ -9841,7 +10171,8 @@ var init_opencode = __esm({
|
|
|
9841
10171
|
return { type: "stderr", data: detail };
|
|
9842
10172
|
}
|
|
9843
10173
|
const sid = typeof obj.sessionID === "string" && obj.sessionID || typeof obj.sessionId === "string" && obj.sessionId || typeof obj.session_id === "string" && obj.session_id;
|
|
9844
|
-
|
|
10174
|
+
const childSid = str3(obj.childSessionID) ?? str3(obj.childSessionId) ?? str3(obj.parentID) ?? str3(obj.parentId);
|
|
10175
|
+
if (sid && !childSid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
|
|
9845
10176
|
return { type: "session_id", data: sid };
|
|
9846
10177
|
}
|
|
9847
10178
|
if (obj.type === "text") {
|
|
@@ -10572,6 +10903,11 @@ function createAgentStreamCoalescer(emit, opts) {
|
|
|
10572
10903
|
return;
|
|
10573
10904
|
}
|
|
10574
10905
|
if (!event.data) return;
|
|
10906
|
+
if (event.type === "thinking" && event.replace) {
|
|
10907
|
+
flush2();
|
|
10908
|
+
emit(event);
|
|
10909
|
+
return;
|
|
10910
|
+
}
|
|
10575
10911
|
if (pending && pending.type === event.type && parentKey(pending) === parentKey(event)) {
|
|
10576
10912
|
pending.data += event.data;
|
|
10577
10913
|
} else {
|
|
@@ -10628,6 +10964,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
10628
10964
|
}
|
|
10629
10965
|
const env = childEnvWithAppSettings(cmd.env);
|
|
10630
10966
|
applyPromptCacheTtlEnv(thread.agent, env);
|
|
10967
|
+
applyAgentRunnerHeapEnv(env);
|
|
10631
10968
|
try {
|
|
10632
10969
|
if (isOrchestratorThread(thread)) {
|
|
10633
10970
|
mergeAgentGitAuthEnv(env, await resolveAgentGitAuthEnv(env));
|
|
@@ -10735,9 +11072,11 @@ var init_spawn = __esm({
|
|
|
10735
11072
|
init_agents();
|
|
10736
11073
|
init_orchestrator_capable();
|
|
10737
11074
|
init_message_parts();
|
|
11075
|
+
init_node_launch();
|
|
10738
11076
|
init_path();
|
|
10739
11077
|
init_usage();
|
|
10740
11078
|
init_cursor_stream_coalesce();
|
|
11079
|
+
init_node_launch();
|
|
10741
11080
|
}
|
|
10742
11081
|
});
|
|
10743
11082
|
|
|
@@ -11463,21 +11802,21 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
11463
11802
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
11464
11803
|
}
|
|
11465
11804
|
function readTextIfPresent(abs) {
|
|
11466
|
-
if (!(0,
|
|
11805
|
+
if (!(0, import_node_fs30.existsSync)(abs)) return null;
|
|
11467
11806
|
try {
|
|
11468
|
-
const content = (0,
|
|
11807
|
+
const content = (0, import_node_fs30.readFileSync)(abs, "utf8");
|
|
11469
11808
|
return content.trim() ? content : null;
|
|
11470
11809
|
} catch {
|
|
11471
11810
|
return null;
|
|
11472
11811
|
}
|
|
11473
11812
|
}
|
|
11474
11813
|
function readLocalGuidelines(worktreePath) {
|
|
11475
|
-
const localAbs = (0,
|
|
11814
|
+
const localAbs = (0, import_node_path29.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
11476
11815
|
const localContent = readTextIfPresent(localAbs);
|
|
11477
11816
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
11478
11817
|
return { path: REVIEW_REQUEST_PATH, content: localContent };
|
|
11479
11818
|
}
|
|
11480
|
-
const legacyAbs = (0,
|
|
11819
|
+
const legacyAbs = (0, import_node_path29.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
11481
11820
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
11482
11821
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
11483
11822
|
return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
|
|
@@ -11493,20 +11832,20 @@ function skillGuidelines(content, source) {
|
|
|
11493
11832
|
};
|
|
11494
11833
|
}
|
|
11495
11834
|
function ensureReviewSkillFile(worktreePath) {
|
|
11496
|
-
const abs = (0,
|
|
11835
|
+
const abs = (0, import_node_path29.join)(worktreePath, REVIEW_SKILL_PATH);
|
|
11497
11836
|
const existing = readTextIfPresent(abs);
|
|
11498
11837
|
if (existing) {
|
|
11499
11838
|
return { path: REVIEW_SKILL_PATH, content: existing, wrote: false };
|
|
11500
11839
|
}
|
|
11501
|
-
const fromRepo = readTextIfPresent((0,
|
|
11840
|
+
const fromRepo = readTextIfPresent((0, import_node_path29.join)(worktreePath, REPO_REVIEW_PATH));
|
|
11502
11841
|
const fromLocal = readLocalGuidelines(worktreePath)?.content ?? null;
|
|
11503
11842
|
const content = wrapReviewSkillMarkdown(fromRepo ?? fromLocal ?? REVIEW_REQUEST_TEMPLATE);
|
|
11504
|
-
(0,
|
|
11505
|
-
(0,
|
|
11843
|
+
(0, import_node_fs30.mkdirSync)((0, import_node_path29.dirname)(abs), { recursive: true });
|
|
11844
|
+
(0, import_node_fs30.writeFileSync)(abs, content, "utf8");
|
|
11506
11845
|
return { path: REVIEW_SKILL_PATH, content, wrote: true };
|
|
11507
11846
|
}
|
|
11508
11847
|
function resolveReviewGuidelines(worktreePath) {
|
|
11509
|
-
const skillContent = readTextIfPresent((0,
|
|
11848
|
+
const skillContent = readTextIfPresent((0, import_node_path29.join)(worktreePath, REVIEW_SKILL_PATH));
|
|
11510
11849
|
if (skillContent) return skillGuidelines(skillContent, "skill");
|
|
11511
11850
|
const local = readLocalGuidelines(worktreePath);
|
|
11512
11851
|
if (local) {
|
|
@@ -11536,7 +11875,7 @@ function buildReviewRequestAttachment(content, opts) {
|
|
|
11536
11875
|
};
|
|
11537
11876
|
}
|
|
11538
11877
|
function readExistingReviewRequestFile(worktreePath) {
|
|
11539
|
-
return readTextIfPresent((0,
|
|
11878
|
+
return readTextIfPresent((0, import_node_path29.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path29.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path29.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path29.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
11540
11879
|
}
|
|
11541
11880
|
async function requestReview(threadRef, send2) {
|
|
11542
11881
|
const from = findThreadByRef(threadRef);
|
|
@@ -11563,13 +11902,13 @@ async function requestReview(threadRef, send2) {
|
|
|
11563
11902
|
const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
|
|
11564
11903
|
return { tab: started, from };
|
|
11565
11904
|
}
|
|
11566
|
-
var import_node_crypto6,
|
|
11905
|
+
var import_node_crypto6, import_node_fs30, import_node_path29, REPO_REVIEW_PATH, REPO_REVIEW_NAME, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
|
|
11567
11906
|
var init_request_review = __esm({
|
|
11568
11907
|
"src/review/request-review.ts"() {
|
|
11569
11908
|
"use strict";
|
|
11570
11909
|
import_node_crypto6 = require("crypto");
|
|
11571
|
-
|
|
11572
|
-
|
|
11910
|
+
import_node_fs30 = require("fs");
|
|
11911
|
+
import_node_path29 = require("path");
|
|
11573
11912
|
init_global_workspace();
|
|
11574
11913
|
init_chat_tabs();
|
|
11575
11914
|
init_thread_store();
|
|
@@ -11594,9 +11933,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
11594
11933
|
return new RegExp(`^${escaped}$`).test(name);
|
|
11595
11934
|
}
|
|
11596
11935
|
function readWorktreeInclude(repoPath) {
|
|
11597
|
-
const path2 = (0,
|
|
11598
|
-
if (!(0,
|
|
11599
|
-
return (0,
|
|
11936
|
+
const path2 = (0, import_node_path30.join)(repoPath, ".worktreeinclude");
|
|
11937
|
+
if (!(0, import_node_fs31.existsSync)(path2)) return [];
|
|
11938
|
+
return (0, import_node_fs31.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
11600
11939
|
}
|
|
11601
11940
|
function resolveFilesToCopy(repoPath) {
|
|
11602
11941
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -11606,10 +11945,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
11606
11945
|
if (settings?.fileIncludeGlobs?.length) {
|
|
11607
11946
|
const matched = [];
|
|
11608
11947
|
try {
|
|
11609
|
-
for (const entry of (0,
|
|
11948
|
+
for (const entry of (0, import_node_fs31.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
11610
11949
|
if (!entry.isFile()) continue;
|
|
11611
11950
|
for (const glob of settings.fileIncludeGlobs) {
|
|
11612
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
11951
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path30.basename)(glob), entry.name)) {
|
|
11613
11952
|
matched.push(entry.name);
|
|
11614
11953
|
break;
|
|
11615
11954
|
}
|
|
@@ -11621,7 +11960,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
11621
11960
|
}
|
|
11622
11961
|
const defaults = [];
|
|
11623
11962
|
try {
|
|
11624
|
-
for (const entry of (0,
|
|
11963
|
+
for (const entry of (0, import_node_fs31.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
11625
11964
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
11626
11965
|
defaults.push(entry.name);
|
|
11627
11966
|
}
|
|
@@ -11635,11 +11974,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
11635
11974
|
const patterns = resolveFilesToCopy(repoPath);
|
|
11636
11975
|
const copied = [];
|
|
11637
11976
|
for (const rel of patterns) {
|
|
11638
|
-
const src = (0,
|
|
11639
|
-
if (!(0,
|
|
11640
|
-
const dest = (0,
|
|
11641
|
-
(0,
|
|
11642
|
-
(0,
|
|
11977
|
+
const src = (0, import_node_path30.join)(repoPath, rel);
|
|
11978
|
+
if (!(0, import_node_fs31.existsSync)(src)) continue;
|
|
11979
|
+
const dest = (0, import_node_path30.join)(worktreePath, rel);
|
|
11980
|
+
(0, import_node_fs31.mkdirSync)((0, import_node_path30.dirname)(dest), { recursive: true });
|
|
11981
|
+
(0, import_node_fs31.copyFileSync)(src, dest);
|
|
11643
11982
|
copied.push(rel);
|
|
11644
11983
|
}
|
|
11645
11984
|
return copied;
|
|
@@ -11674,7 +12013,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
11674
12013
|
const env = stripNestedElectronEnv({
|
|
11675
12014
|
...baseEnv ?? process.env
|
|
11676
12015
|
});
|
|
11677
|
-
const name = opts.workspaceName ?? (0,
|
|
12016
|
+
const name = opts.workspaceName ?? (0, import_node_path30.basename)(opts.worktreePath);
|
|
11678
12017
|
const ports = opts.ports ?? [];
|
|
11679
12018
|
const primary = ports[0];
|
|
11680
12019
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -11935,13 +12274,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
11935
12274
|
done: handle.done
|
|
11936
12275
|
};
|
|
11937
12276
|
}
|
|
11938
|
-
var
|
|
12277
|
+
var import_node_fs31, import_node_net, import_node_path30, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
11939
12278
|
var init_conductor = __esm({
|
|
11940
12279
|
"src/hook/conductor.ts"() {
|
|
11941
12280
|
"use strict";
|
|
11942
|
-
|
|
12281
|
+
import_node_fs31 = require("fs");
|
|
11943
12282
|
import_node_net = require("net");
|
|
11944
|
-
|
|
12283
|
+
import_node_path30 = require("path");
|
|
11945
12284
|
import_execa4 = require("execa");
|
|
11946
12285
|
import_node_readline3 = require("readline");
|
|
11947
12286
|
init_settings();
|
|
@@ -11967,9 +12306,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11967
12306
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
11968
12307
|
);
|
|
11969
12308
|
const homeRoot = sideboardWorkspacesDir();
|
|
11970
|
-
if ((0,
|
|
12309
|
+
if ((0, import_node_fs32.existsSync)(homeRoot)) {
|
|
11971
12310
|
try {
|
|
11972
|
-
for (const entry of (0,
|
|
12311
|
+
for (const entry of (0, import_node_fs32.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
11973
12312
|
if (!entry.isDirectory()) continue;
|
|
11974
12313
|
void entry;
|
|
11975
12314
|
}
|
|
@@ -11979,7 +12318,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11979
12318
|
const orphans = [];
|
|
11980
12319
|
const seen = /* @__PURE__ */ new Set();
|
|
11981
12320
|
for (const repoPath of repos) {
|
|
11982
|
-
if (!repoPath || !(0,
|
|
12321
|
+
if (!repoPath || !(0, import_node_fs32.existsSync)(repoPath)) continue;
|
|
11983
12322
|
try {
|
|
11984
12323
|
const wts = await listWorktrees(repoPath);
|
|
11985
12324
|
for (const wt of wts) {
|
|
@@ -11990,7 +12329,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11990
12329
|
seen.add(path2);
|
|
11991
12330
|
let mtimeMs = 0;
|
|
11992
12331
|
try {
|
|
11993
|
-
mtimeMs = (0,
|
|
12332
|
+
mtimeMs = (0, import_node_fs32.statSync)(path2).mtimeMs;
|
|
11994
12333
|
} catch {
|
|
11995
12334
|
mtimeMs = 0;
|
|
11996
12335
|
}
|
|
@@ -12000,16 +12339,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
12000
12339
|
}
|
|
12001
12340
|
try {
|
|
12002
12341
|
const root = worktreesRoot(repoPath);
|
|
12003
|
-
if ((0,
|
|
12004
|
-
for (const entry of (0,
|
|
12342
|
+
if ((0, import_node_fs32.existsSync)(root)) {
|
|
12343
|
+
for (const entry of (0, import_node_fs32.readdirSync)(root, { withFileTypes: true })) {
|
|
12005
12344
|
if (!entry.isDirectory()) continue;
|
|
12006
|
-
const path2 = (0,
|
|
12345
|
+
const path2 = (0, import_node_path31.join)(root, entry.name).replace(/\/$/, "");
|
|
12007
12346
|
if (known.has(path2) || seen.has(path2)) continue;
|
|
12008
|
-
if (!(0,
|
|
12347
|
+
if (!(0, import_node_fs32.existsSync)((0, import_node_path31.join)(path2, ".git"))) continue;
|
|
12009
12348
|
seen.add(path2);
|
|
12010
12349
|
let mtimeMs = 0;
|
|
12011
12350
|
try {
|
|
12012
|
-
mtimeMs = (0,
|
|
12351
|
+
mtimeMs = (0, import_node_fs32.statSync)(path2).mtimeMs;
|
|
12013
12352
|
} catch {
|
|
12014
12353
|
mtimeMs = Date.now();
|
|
12015
12354
|
}
|
|
@@ -12070,12 +12409,12 @@ function worktreeCleanupSettings() {
|
|
|
12070
12409
|
autoCleanupOrphans: a.autoCleanupOrphans
|
|
12071
12410
|
};
|
|
12072
12411
|
}
|
|
12073
|
-
var
|
|
12412
|
+
var import_node_fs32, import_node_path31;
|
|
12074
12413
|
var init_orphan_cleanup = __esm({
|
|
12075
12414
|
"src/git/orphan-cleanup.ts"() {
|
|
12076
12415
|
"use strict";
|
|
12077
|
-
|
|
12078
|
-
|
|
12416
|
+
import_node_fs32 = require("fs");
|
|
12417
|
+
import_node_path31 = require("path");
|
|
12079
12418
|
init_worktree();
|
|
12080
12419
|
init_thread_store();
|
|
12081
12420
|
init_paths();
|
|
@@ -12182,38 +12521,38 @@ __export(workspaces_exports, {
|
|
|
12182
12521
|
syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
|
|
12183
12522
|
});
|
|
12184
12523
|
function workspacesFile() {
|
|
12185
|
-
return (0,
|
|
12524
|
+
return (0, import_node_path32.join)(appDataDir(), "workspaces.json");
|
|
12186
12525
|
}
|
|
12187
12526
|
function removedWorkspacesFile() {
|
|
12188
|
-
return (0,
|
|
12527
|
+
return (0, import_node_path32.join)(appDataDir(), "removed-workspaces.json");
|
|
12189
12528
|
}
|
|
12190
12529
|
function readAll2() {
|
|
12191
12530
|
const path2 = workspacesFile();
|
|
12192
|
-
if (!(0,
|
|
12531
|
+
if (!(0, import_node_fs33.existsSync)(path2)) return [];
|
|
12193
12532
|
try {
|
|
12194
|
-
const raw = JSON.parse((0,
|
|
12533
|
+
const raw = JSON.parse((0, import_node_fs33.readFileSync)(path2, "utf8"));
|
|
12195
12534
|
return Array.isArray(raw) ? raw : [];
|
|
12196
12535
|
} catch {
|
|
12197
12536
|
return [];
|
|
12198
12537
|
}
|
|
12199
12538
|
}
|
|
12200
12539
|
function writeAll2(list) {
|
|
12201
|
-
(0,
|
|
12202
|
-
(0,
|
|
12540
|
+
(0, import_node_fs33.mkdirSync)(appDataDir(), { recursive: true });
|
|
12541
|
+
(0, import_node_fs33.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
|
|
12203
12542
|
}
|
|
12204
12543
|
function readRemoved() {
|
|
12205
12544
|
const path2 = removedWorkspacesFile();
|
|
12206
|
-
if (!(0,
|
|
12545
|
+
if (!(0, import_node_fs33.existsSync)(path2)) return /* @__PURE__ */ new Set();
|
|
12207
12546
|
try {
|
|
12208
|
-
const raw = JSON.parse((0,
|
|
12547
|
+
const raw = JSON.parse((0, import_node_fs33.readFileSync)(path2, "utf8"));
|
|
12209
12548
|
return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
|
|
12210
12549
|
} catch {
|
|
12211
12550
|
return /* @__PURE__ */ new Set();
|
|
12212
12551
|
}
|
|
12213
12552
|
}
|
|
12214
12553
|
function writeRemoved(paths) {
|
|
12215
|
-
(0,
|
|
12216
|
-
(0,
|
|
12554
|
+
(0, import_node_fs33.mkdirSync)(appDataDir(), { recursive: true });
|
|
12555
|
+
(0, import_node_fs33.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
|
|
12217
12556
|
}
|
|
12218
12557
|
function rememberRemoved(repoPath) {
|
|
12219
12558
|
const next = readRemoved();
|
|
@@ -12236,7 +12575,7 @@ function listWorkspaces() {
|
|
|
12236
12575
|
async function addWorkspace(repoPath) {
|
|
12237
12576
|
const root = await resolveRepoRoot(repoPath);
|
|
12238
12577
|
if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
|
|
12239
|
-
if (!(0,
|
|
12578
|
+
if (!(0, import_node_fs33.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
|
|
12240
12579
|
forgetRemoved(root);
|
|
12241
12580
|
await ensureGhPreferOrigin(root);
|
|
12242
12581
|
const current = readAll2();
|
|
@@ -12244,7 +12583,7 @@ async function addWorkspace(repoPath) {
|
|
|
12244
12583
|
if (existing) return existing;
|
|
12245
12584
|
const next = {
|
|
12246
12585
|
path: root,
|
|
12247
|
-
name: (0,
|
|
12586
|
+
name: (0, import_node_path32.basename)(root),
|
|
12248
12587
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12249
12588
|
};
|
|
12250
12589
|
writeAll2([...current, next]);
|
|
@@ -12266,10 +12605,10 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
12266
12605
|
if (!path2 || path2 === "/" || isGlobalRepoPath(path2) || byPath.has(path2) || removed.has(path2)) {
|
|
12267
12606
|
continue;
|
|
12268
12607
|
}
|
|
12269
|
-
if (!(0,
|
|
12608
|
+
if (!(0, import_node_fs33.existsSync)(path2)) continue;
|
|
12270
12609
|
const ws = {
|
|
12271
12610
|
path: path2,
|
|
12272
|
-
name: (0,
|
|
12611
|
+
name: (0, import_node_path32.basename)(path2),
|
|
12273
12612
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12274
12613
|
};
|
|
12275
12614
|
byPath.set(path2, ws);
|
|
@@ -12279,12 +12618,12 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
12279
12618
|
if (dirty) writeAll2(next);
|
|
12280
12619
|
return next.sort((a, b) => a.name.localeCompare(b.name));
|
|
12281
12620
|
}
|
|
12282
|
-
var
|
|
12621
|
+
var import_node_fs33, import_node_path32;
|
|
12283
12622
|
var init_workspaces2 = __esm({
|
|
12284
12623
|
"src/store/workspaces.ts"() {
|
|
12285
12624
|
"use strict";
|
|
12286
|
-
|
|
12287
|
-
|
|
12625
|
+
import_node_fs33 = require("fs");
|
|
12626
|
+
import_node_path32 = require("path");
|
|
12288
12627
|
init_paths();
|
|
12289
12628
|
init_global_workspace();
|
|
12290
12629
|
init_worktree();
|
|
@@ -12297,12 +12636,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
12297
12636
|
if (!url) throw new Error("Clone URL is required");
|
|
12298
12637
|
let name = opts.name?.trim();
|
|
12299
12638
|
if (!name) {
|
|
12300
|
-
const leaf = (0,
|
|
12639
|
+
const leaf = (0, import_node_path33.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
12301
12640
|
name = leaf || "repo";
|
|
12302
12641
|
}
|
|
12303
12642
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
12304
|
-
const dest = (0,
|
|
12305
|
-
if ((0,
|
|
12643
|
+
const dest = (0, import_node_path33.join)(sideboardReposDir(), name);
|
|
12644
|
+
if ((0, import_node_fs34.existsSync)(dest)) {
|
|
12306
12645
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
12307
12646
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
12308
12647
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -12317,12 +12656,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
12317
12656
|
const workspace = await ensureWorkspace(repoPath);
|
|
12318
12657
|
return { repoPath, workspace };
|
|
12319
12658
|
}
|
|
12320
|
-
var
|
|
12659
|
+
var import_node_fs34, import_node_path33, import_execa6;
|
|
12321
12660
|
var init_clone_repo = __esm({
|
|
12322
12661
|
"src/git/clone-repo.ts"() {
|
|
12323
12662
|
"use strict";
|
|
12324
|
-
|
|
12325
|
-
|
|
12663
|
+
import_node_fs34 = require("fs");
|
|
12664
|
+
import_node_path33 = require("path");
|
|
12326
12665
|
import_execa6 = require("execa");
|
|
12327
12666
|
init_paths();
|
|
12328
12667
|
init_workspaces2();
|
|
@@ -12380,7 +12719,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
12380
12719
|
});
|
|
12381
12720
|
await requireAgent(resolved.agent);
|
|
12382
12721
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
12383
|
-
if (!(0,
|
|
12722
|
+
if (!(0, import_node_fs35.existsSync)(repoPath)) {
|
|
12384
12723
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
12385
12724
|
}
|
|
12386
12725
|
if (input.cowboy) {
|
|
@@ -12503,11 +12842,11 @@ async function listLinearIssues(agent, repoPath) {
|
|
|
12503
12842
|
}
|
|
12504
12843
|
return adapter.listLinearIssues(repoPath);
|
|
12505
12844
|
}
|
|
12506
|
-
var
|
|
12845
|
+
var import_node_fs35;
|
|
12507
12846
|
var init_create = __esm({
|
|
12508
12847
|
"src/threads/create.ts"() {
|
|
12509
12848
|
"use strict";
|
|
12510
|
-
|
|
12849
|
+
import_node_fs35 = require("fs");
|
|
12511
12850
|
init_detect();
|
|
12512
12851
|
init_worktree();
|
|
12513
12852
|
init_conductor();
|
|
@@ -12552,21 +12891,13 @@ function summarizeTurnLive(parts) {
|
|
|
12552
12891
|
(p) => p.type === "tool"
|
|
12553
12892
|
);
|
|
12554
12893
|
const lastTool = tools[tools.length - 1];
|
|
12555
|
-
const
|
|
12556
|
-
const
|
|
12894
|
+
const interesting = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? lastTool;
|
|
12895
|
+
const lastToolLabel = interesting ? interesting.description || toolDescription(interesting.name, interesting.input) || interesting.name : void 0;
|
|
12557
12896
|
const thinking = lastText(parts, "thinking");
|
|
12558
12897
|
const text4 = lastText(parts, "text");
|
|
12559
12898
|
const excerptRaw = thinking || text4;
|
|
12560
12899
|
const excerpt = excerptRaw.length > 280 ? `${excerptRaw.slice(-280)}` : excerptRaw || void 0;
|
|
12561
|
-
|
|
12562
|
-
if (lastToolLabel) {
|
|
12563
|
-
const verb = running ? lastToolLabel : `Finished ${lastToolLabel}`;
|
|
12564
|
-
summary = tools.length > 1 ? `${verb} (${tools.length} tools)` : verb;
|
|
12565
|
-
} else if (thinking) {
|
|
12566
|
-
summary = "Thinking\u2026";
|
|
12567
|
-
} else if (text4) {
|
|
12568
|
-
summary = "Writing reply\u2026";
|
|
12569
|
-
}
|
|
12900
|
+
const summary = liveActivitySummary(parts);
|
|
12570
12901
|
return {
|
|
12571
12902
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12572
12903
|
summary,
|
|
@@ -12616,20 +12947,20 @@ function writeTurnLive(threadId, progress) {
|
|
|
12616
12947
|
const path2 = threadLivePath(threadId);
|
|
12617
12948
|
const tmp = `${path2}.${process.pid}.tmp`;
|
|
12618
12949
|
try {
|
|
12619
|
-
(0,
|
|
12620
|
-
(0,
|
|
12950
|
+
(0, import_node_fs36.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
|
|
12951
|
+
(0, import_node_fs36.renameSync)(tmp, path2);
|
|
12621
12952
|
} catch {
|
|
12622
12953
|
try {
|
|
12623
|
-
(0,
|
|
12954
|
+
(0, import_node_fs36.unlinkSync)(tmp);
|
|
12624
12955
|
} catch {
|
|
12625
12956
|
}
|
|
12626
12957
|
}
|
|
12627
12958
|
}
|
|
12628
12959
|
function readTurnLive(threadId) {
|
|
12629
12960
|
const path2 = threadLivePath(threadId);
|
|
12630
|
-
if (!(0,
|
|
12961
|
+
if (!(0, import_node_fs36.existsSync)(path2)) return null;
|
|
12631
12962
|
try {
|
|
12632
|
-
const raw = JSON.parse((0,
|
|
12963
|
+
const raw = JSON.parse((0, import_node_fs36.readFileSync)(path2, "utf8"));
|
|
12633
12964
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
12634
12965
|
return raw;
|
|
12635
12966
|
} catch {
|
|
@@ -12641,17 +12972,17 @@ function clearTurnLive(threadId) {
|
|
|
12641
12972
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
12642
12973
|
buffers.delete(threadId);
|
|
12643
12974
|
const path2 = threadLivePath(threadId);
|
|
12644
|
-
if (!(0,
|
|
12975
|
+
if (!(0, import_node_fs36.existsSync)(path2)) return;
|
|
12645
12976
|
try {
|
|
12646
|
-
(0,
|
|
12977
|
+
(0, import_node_fs36.unlinkSync)(path2);
|
|
12647
12978
|
} catch {
|
|
12648
12979
|
}
|
|
12649
12980
|
}
|
|
12650
|
-
var
|
|
12981
|
+
var import_node_fs36, buffers, FLUSH_MS, MAX_PARTS;
|
|
12651
12982
|
var init_turn_live = __esm({
|
|
12652
12983
|
"src/store/turn-live.ts"() {
|
|
12653
12984
|
"use strict";
|
|
12654
|
-
|
|
12985
|
+
import_node_fs36 = require("fs");
|
|
12655
12986
|
init_message_parts();
|
|
12656
12987
|
init_paths();
|
|
12657
12988
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -12830,7 +13161,7 @@ var init_quota_failover = __esm({
|
|
|
12830
13161
|
// src/threads/adopt.ts
|
|
12831
13162
|
function thisModuleFile() {
|
|
12832
13163
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
12833
|
-
return cjsFile || process.argv[1] || (0,
|
|
13164
|
+
return cjsFile || process.argv[1] || (0, import_node_path34.join)(process.cwd(), "package.json");
|
|
12834
13165
|
}
|
|
12835
13166
|
function openReadonlySqlite(file) {
|
|
12836
13167
|
const req = (0, import_node_module4.createRequire)(thisModuleFile());
|
|
@@ -12848,21 +13179,21 @@ function mapAgentType(raw) {
|
|
|
12848
13179
|
return null;
|
|
12849
13180
|
}
|
|
12850
13181
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
12851
|
-
if (!workspacePath || !(0,
|
|
13182
|
+
if (!workspacePath || !(0, import_node_fs37.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
12852
13183
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
12853
13184
|
let best = null;
|
|
12854
13185
|
let hashes;
|
|
12855
13186
|
try {
|
|
12856
|
-
hashes = (0,
|
|
13187
|
+
hashes = (0, import_node_fs37.readdirSync)(CURSOR_SDK_STORE);
|
|
12857
13188
|
} catch {
|
|
12858
13189
|
return null;
|
|
12859
13190
|
}
|
|
12860
13191
|
for (const hash of hashes) {
|
|
12861
|
-
const agentsFile = (0,
|
|
12862
|
-
if (!(0,
|
|
13192
|
+
const agentsFile = (0, import_node_path34.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
13193
|
+
if (!(0, import_node_fs37.existsSync)(agentsFile)) continue;
|
|
12863
13194
|
let text4;
|
|
12864
13195
|
try {
|
|
12865
|
-
text4 = (0,
|
|
13196
|
+
text4 = (0, import_node_fs37.readFileSync)(agentsFile, "utf8");
|
|
12866
13197
|
} catch {
|
|
12867
13198
|
continue;
|
|
12868
13199
|
}
|
|
@@ -12886,7 +13217,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
12886
13217
|
return best?.agentId ?? null;
|
|
12887
13218
|
}
|
|
12888
13219
|
async function adoptThread(input) {
|
|
12889
|
-
if (!(0,
|
|
13220
|
+
if (!(0, import_node_fs37.existsSync)(input.worktreePath)) {
|
|
12890
13221
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
12891
13222
|
}
|
|
12892
13223
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -12913,18 +13244,18 @@ function conductorDbPath() {
|
|
|
12913
13244
|
return CONDUCTOR_DB;
|
|
12914
13245
|
}
|
|
12915
13246
|
function listConductorWorkspaces() {
|
|
12916
|
-
if (!(0,
|
|
13247
|
+
if (!(0, import_node_fs37.existsSync)(CONDUCTOR_DB)) {
|
|
12917
13248
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
12918
13249
|
}
|
|
12919
|
-
const tmp = (0,
|
|
12920
|
-
const snapshot = (0,
|
|
13250
|
+
const tmp = (0, import_node_fs37.mkdtempSync)((0, import_node_path34.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
|
|
13251
|
+
const snapshot = (0, import_node_path34.join)(tmp, "conductor.db");
|
|
12921
13252
|
try {
|
|
12922
|
-
(0,
|
|
13253
|
+
(0, import_node_fs37.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
12923
13254
|
for (const suffix of ["-wal", "-shm"]) {
|
|
12924
13255
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
12925
|
-
if ((0,
|
|
13256
|
+
if ((0, import_node_fs37.existsSync)(src)) {
|
|
12926
13257
|
try {
|
|
12927
|
-
(0,
|
|
13258
|
+
(0, import_node_fs37.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
12928
13259
|
} catch {
|
|
12929
13260
|
}
|
|
12930
13261
|
}
|
|
@@ -13000,22 +13331,22 @@ function listConductorWorkspaces() {
|
|
|
13000
13331
|
db.close();
|
|
13001
13332
|
}
|
|
13002
13333
|
} finally {
|
|
13003
|
-
(0,
|
|
13334
|
+
(0, import_node_fs37.rmSync)(tmp, { recursive: true, force: true });
|
|
13004
13335
|
}
|
|
13005
13336
|
}
|
|
13006
13337
|
function importConductorWorkspace(workspaceId) {
|
|
13007
|
-
if (!(0,
|
|
13338
|
+
if (!(0, import_node_fs37.existsSync)(CONDUCTOR_DB)) {
|
|
13008
13339
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
13009
13340
|
}
|
|
13010
|
-
const tmp = (0,
|
|
13011
|
-
const snapshot = (0,
|
|
13341
|
+
const tmp = (0, import_node_fs37.mkdtempSync)((0, import_node_path34.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
|
|
13342
|
+
const snapshot = (0, import_node_path34.join)(tmp, "conductor.db");
|
|
13012
13343
|
try {
|
|
13013
|
-
(0,
|
|
13344
|
+
(0, import_node_fs37.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
13014
13345
|
for (const suffix of ["-wal", "-shm"]) {
|
|
13015
13346
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
13016
|
-
if ((0,
|
|
13347
|
+
if ((0, import_node_fs37.existsSync)(src)) {
|
|
13017
13348
|
try {
|
|
13018
|
-
(0,
|
|
13349
|
+
(0, import_node_fs37.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
13019
13350
|
} catch {
|
|
13020
13351
|
}
|
|
13021
13352
|
}
|
|
@@ -13033,7 +13364,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
13033
13364
|
).get(workspaceId);
|
|
13034
13365
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
13035
13366
|
const worktreePath = String(row.workspacePath);
|
|
13036
|
-
if (!(0,
|
|
13367
|
+
if (!(0, import_node_fs37.existsSync)(worktreePath)) {
|
|
13037
13368
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
13038
13369
|
}
|
|
13039
13370
|
let sessionId = null;
|
|
@@ -13096,31 +13427,31 @@ function importConductorWorkspace(workspaceId) {
|
|
|
13096
13427
|
db.close();
|
|
13097
13428
|
}
|
|
13098
13429
|
} finally {
|
|
13099
|
-
(0,
|
|
13430
|
+
(0, import_node_fs37.rmSync)(tmp, { recursive: true, force: true });
|
|
13100
13431
|
}
|
|
13101
13432
|
}
|
|
13102
13433
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
13103
13434
|
return importConductorWorkspace(workspaceId);
|
|
13104
13435
|
}
|
|
13105
|
-
var import_node_child_process4,
|
|
13436
|
+
var import_node_child_process4, import_node_fs37, import_node_os10, import_node_path34, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
|
|
13106
13437
|
var init_adopt = __esm({
|
|
13107
13438
|
"src/threads/adopt.ts"() {
|
|
13108
13439
|
"use strict";
|
|
13109
13440
|
import_node_child_process4 = require("child_process");
|
|
13110
|
-
|
|
13441
|
+
import_node_fs37 = require("fs");
|
|
13111
13442
|
import_node_os10 = require("os");
|
|
13112
|
-
|
|
13443
|
+
import_node_path34 = require("path");
|
|
13113
13444
|
import_node_module4 = require("module");
|
|
13114
13445
|
init_worktree();
|
|
13115
13446
|
init_thread_store();
|
|
13116
|
-
CONDUCTOR_APP_SUPPORT = (0,
|
|
13447
|
+
CONDUCTOR_APP_SUPPORT = (0, import_node_path34.join)(
|
|
13117
13448
|
process.env.HOME ?? "",
|
|
13118
13449
|
"Library",
|
|
13119
13450
|
"Application Support",
|
|
13120
13451
|
"com.conductor.app"
|
|
13121
13452
|
);
|
|
13122
|
-
CONDUCTOR_DB = (0,
|
|
13123
|
-
CURSOR_SDK_STORE = (0,
|
|
13453
|
+
CONDUCTOR_DB = (0, import_node_path34.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
13454
|
+
CURSOR_SDK_STORE = (0, import_node_path34.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
13124
13455
|
}
|
|
13125
13456
|
});
|
|
13126
13457
|
|
|
@@ -13187,7 +13518,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
13187
13518
|
let createdWorktree = false;
|
|
13188
13519
|
const trees = await listWorktrees(repoPath);
|
|
13189
13520
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
13190
|
-
if (checkedOut?.path && (0,
|
|
13521
|
+
if (checkedOut?.path && (0, import_node_fs38.existsSync)(checkedOut.path)) {
|
|
13191
13522
|
if (input.reuseExistingWorktree !== false) {
|
|
13192
13523
|
worktreePath = checkedOut.path;
|
|
13193
13524
|
} else {
|
|
@@ -13329,7 +13660,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
13329
13660
|
async function createPrStack(input, onSetupLine) {
|
|
13330
13661
|
await requireAgent(input.agent);
|
|
13331
13662
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
13332
|
-
if (!(0,
|
|
13663
|
+
if (!(0, import_node_fs38.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
13333
13664
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
13334
13665
|
const status = await detectGhStack(repoPath);
|
|
13335
13666
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -13396,7 +13727,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
13396
13727
|
}
|
|
13397
13728
|
}
|
|
13398
13729
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
13399
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
13730
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs38.existsSync)(bootstrap.worktreePath)) {
|
|
13400
13731
|
try {
|
|
13401
13732
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
13402
13733
|
deleteBranch: bootstrap.branchName
|
|
@@ -13416,11 +13747,11 @@ function stackAgentDefaultsFrom(input) {
|
|
|
13416
13747
|
planMode: input.planMode
|
|
13417
13748
|
};
|
|
13418
13749
|
}
|
|
13419
|
-
var
|
|
13750
|
+
var import_node_fs38;
|
|
13420
13751
|
var init_stack_layers = __esm({
|
|
13421
13752
|
"src/threads/stack-layers.ts"() {
|
|
13422
13753
|
"use strict";
|
|
13423
|
-
|
|
13754
|
+
import_node_fs38 = require("fs");
|
|
13424
13755
|
init_detect();
|
|
13425
13756
|
init_run();
|
|
13426
13757
|
init_stack();
|
|
@@ -13433,7 +13764,7 @@ var init_stack_layers = __esm({
|
|
|
13433
13764
|
|
|
13434
13765
|
// src/diff/diff.ts
|
|
13435
13766
|
async function inspectGitWorktree(worktreePath) {
|
|
13436
|
-
if (!worktreePath || !(0,
|
|
13767
|
+
if (!worktreePath || !(0, import_node_fs39.existsSync)(worktreePath)) return "missing_worktree";
|
|
13437
13768
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
13438
13769
|
reject: false
|
|
13439
13770
|
});
|
|
@@ -13441,7 +13772,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
13441
13772
|
return "ok";
|
|
13442
13773
|
}
|
|
13443
13774
|
async function initializeGitRepository(worktreePath) {
|
|
13444
|
-
if (!worktreePath || !(0,
|
|
13775
|
+
if (!worktreePath || !(0, import_node_fs39.existsSync)(worktreePath)) {
|
|
13445
13776
|
throw new Error("Worktree not found");
|
|
13446
13777
|
}
|
|
13447
13778
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -13575,11 +13906,11 @@ new file mode 100644
|
|
|
13575
13906
|
};
|
|
13576
13907
|
}
|
|
13577
13908
|
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
13578
|
-
const abs = (0,
|
|
13909
|
+
const abs = (0, import_node_path35.join)(worktreePath, path2);
|
|
13579
13910
|
try {
|
|
13580
|
-
const st = (0,
|
|
13911
|
+
const st = (0, import_node_fs39.statSync)(abs);
|
|
13581
13912
|
if (st.isFile() && st.size > maxHunk) {
|
|
13582
|
-
const buf = (0,
|
|
13913
|
+
const buf = (0, import_node_fs39.readFileSync)(abs).subarray(0, maxHunk);
|
|
13583
13914
|
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
13584
13915
|
}
|
|
13585
13916
|
} catch {
|
|
@@ -14068,8 +14399,8 @@ function isImageRelativePath(relativePath) {
|
|
|
14068
14399
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
14069
14400
|
assertSafeRelativePath(relativePath);
|
|
14070
14401
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
14071
|
-
const abs = (0,
|
|
14072
|
-
const st = (0,
|
|
14402
|
+
const abs = (0, import_node_path35.join)(worktreePath, relativePath);
|
|
14403
|
+
const st = (0, import_node_fs39.statSync)(abs);
|
|
14073
14404
|
if (!st.isFile()) {
|
|
14074
14405
|
throw new Error(`Not a file: ${relativePath}`);
|
|
14075
14406
|
}
|
|
@@ -14078,7 +14409,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
14078
14409
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
14079
14410
|
);
|
|
14080
14411
|
}
|
|
14081
|
-
const buf = (0,
|
|
14412
|
+
const buf = (0, import_node_fs39.readFileSync)(abs);
|
|
14082
14413
|
return {
|
|
14083
14414
|
path: relativePath,
|
|
14084
14415
|
contentBase64: buf.toString("base64"),
|
|
@@ -14088,12 +14419,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
14088
14419
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
14089
14420
|
assertSafeRelativePath(relativePath);
|
|
14090
14421
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
14091
|
-
const abs = (0,
|
|
14092
|
-
const st = (0,
|
|
14422
|
+
const abs = (0, import_node_path35.join)(worktreePath, relativePath);
|
|
14423
|
+
const st = (0, import_node_fs39.statSync)(abs);
|
|
14093
14424
|
if (!st.isFile()) {
|
|
14094
14425
|
throw new Error(`Not a file: ${relativePath}`);
|
|
14095
14426
|
}
|
|
14096
|
-
const buf = (0,
|
|
14427
|
+
const buf = (0, import_node_fs39.readFileSync)(abs);
|
|
14097
14428
|
if (isImageRelativePath(relativePath)) {
|
|
14098
14429
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
14099
14430
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -14136,9 +14467,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
14136
14467
|
}
|
|
14137
14468
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
14138
14469
|
assertSafeRelativePath(relativePath);
|
|
14139
|
-
const abs = (0,
|
|
14140
|
-
(0,
|
|
14141
|
-
(0,
|
|
14470
|
+
const abs = (0, import_node_path35.join)(worktreePath, relativePath);
|
|
14471
|
+
(0, import_node_fs39.mkdirSync)((0, import_node_path35.dirname)(abs), { recursive: true });
|
|
14472
|
+
(0, import_node_fs39.writeFileSync)(abs, content, "utf8");
|
|
14142
14473
|
return { path: relativePath };
|
|
14143
14474
|
}
|
|
14144
14475
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -14155,12 +14486,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
14155
14486
|
truncated: full.files.length > maxFiles
|
|
14156
14487
|
};
|
|
14157
14488
|
}
|
|
14158
|
-
var
|
|
14489
|
+
var import_node_fs39, import_node_path35, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS, DEFAULT_UPLOAD_MAX_BYTES;
|
|
14159
14490
|
var init_diff = __esm({
|
|
14160
14491
|
"src/diff/diff.ts"() {
|
|
14161
14492
|
"use strict";
|
|
14162
|
-
|
|
14163
|
-
|
|
14493
|
+
import_node_fs39 = require("fs");
|
|
14494
|
+
import_node_path35 = require("path");
|
|
14164
14495
|
init_run();
|
|
14165
14496
|
init_worktree();
|
|
14166
14497
|
mergeBaseCache = /* @__PURE__ */ new Map();
|
|
@@ -14328,7 +14659,7 @@ function parseFrontmatter(content) {
|
|
|
14328
14659
|
}
|
|
14329
14660
|
function readSkill(skillMd, source) {
|
|
14330
14661
|
try {
|
|
14331
|
-
const content = (0,
|
|
14662
|
+
const content = (0, import_node_fs40.readFileSync)(skillMd, "utf8");
|
|
14332
14663
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
14333
14664
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
14334
14665
|
const name = fmName || dirName;
|
|
@@ -14347,19 +14678,19 @@ function readSkill(skillMd, source) {
|
|
|
14347
14678
|
}
|
|
14348
14679
|
}
|
|
14349
14680
|
function scanSkillsDir(dir, source, out) {
|
|
14350
|
-
if (!(0,
|
|
14681
|
+
if (!(0, import_node_fs40.existsSync)(dir)) return;
|
|
14351
14682
|
let entries;
|
|
14352
14683
|
try {
|
|
14353
|
-
entries = (0,
|
|
14684
|
+
entries = (0, import_node_fs40.readdirSync)(dir);
|
|
14354
14685
|
} catch {
|
|
14355
14686
|
return;
|
|
14356
14687
|
}
|
|
14357
14688
|
for (const entry of entries) {
|
|
14358
14689
|
if (entry.startsWith(".")) continue;
|
|
14359
|
-
const skillMd = (0,
|
|
14360
|
-
if (!(0,
|
|
14690
|
+
const skillMd = (0, import_node_path36.join)(dir, entry, "SKILL.md");
|
|
14691
|
+
if (!(0, import_node_fs40.existsSync)(skillMd)) continue;
|
|
14361
14692
|
try {
|
|
14362
|
-
if (!(0,
|
|
14693
|
+
if (!(0, import_node_fs40.statSync)(skillMd).isFile()) continue;
|
|
14363
14694
|
} catch {
|
|
14364
14695
|
continue;
|
|
14365
14696
|
}
|
|
@@ -14368,24 +14699,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
14368
14699
|
}
|
|
14369
14700
|
}
|
|
14370
14701
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
14371
|
-
if (!(0,
|
|
14702
|
+
if (!(0, import_node_fs40.existsSync)(pluginsRoot)) return;
|
|
14372
14703
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
14373
14704
|
if (depth > 7) return;
|
|
14374
14705
|
let entries;
|
|
14375
14706
|
try {
|
|
14376
|
-
entries = (0,
|
|
14707
|
+
entries = (0, import_node_fs40.readdirSync)(dir);
|
|
14377
14708
|
} catch {
|
|
14378
14709
|
return;
|
|
14379
14710
|
}
|
|
14380
14711
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
14381
|
-
const skill = readSkill((0,
|
|
14712
|
+
const skill = readSkill((0, import_node_path36.join)(dir, "SKILL.md"), "cli");
|
|
14382
14713
|
if (skill) out.push(skill);
|
|
14383
14714
|
}
|
|
14384
14715
|
for (const entry of entries) {
|
|
14385
14716
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
14386
|
-
const full = (0,
|
|
14717
|
+
const full = (0, import_node_path36.join)(dir, entry);
|
|
14387
14718
|
try {
|
|
14388
|
-
if (!(0,
|
|
14719
|
+
if (!(0, import_node_fs40.statSync)(full).isDirectory()) continue;
|
|
14389
14720
|
} catch {
|
|
14390
14721
|
continue;
|
|
14391
14722
|
}
|
|
@@ -14403,17 +14734,17 @@ function discoverSkills(worktreePath) {
|
|
|
14403
14734
|
const home = (0, import_node_os11.homedir)();
|
|
14404
14735
|
const collected = [];
|
|
14405
14736
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
14406
|
-
scanSkillsDir((0,
|
|
14737
|
+
scanSkillsDir((0, import_node_path36.join)(worktreePath, rel), "workspace", collected);
|
|
14407
14738
|
}
|
|
14408
14739
|
for (const abs of [
|
|
14409
|
-
(0,
|
|
14410
|
-
(0,
|
|
14411
|
-
(0,
|
|
14412
|
-
(0,
|
|
14740
|
+
(0, import_node_path36.join)(home, ".claude/skills"),
|
|
14741
|
+
(0, import_node_path36.join)(home, ".cursor/skills"),
|
|
14742
|
+
(0, import_node_path36.join)(home, ".sideboard/skills"),
|
|
14743
|
+
(0, import_node_path36.join)(home, ".brightsy/skills")
|
|
14413
14744
|
]) {
|
|
14414
14745
|
scanSkillsDir(abs, "user", collected);
|
|
14415
14746
|
}
|
|
14416
|
-
scanClaudePluginSkills((0,
|
|
14747
|
+
scanClaudePluginSkills((0, import_node_path36.join)(home, ".claude/plugins"), collected);
|
|
14417
14748
|
const rank = { workspace: 0, user: 1, cli: 2 };
|
|
14418
14749
|
const byCommand = /* @__PURE__ */ new Map();
|
|
14419
14750
|
for (const skill of collected) {
|
|
@@ -14425,7 +14756,7 @@ function discoverSkills(worktreePath) {
|
|
|
14425
14756
|
return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
|
|
14426
14757
|
}
|
|
14427
14758
|
function readSkillBody(skillPath, maxChars = 12e3) {
|
|
14428
|
-
const raw = (0,
|
|
14759
|
+
const raw = (0, import_node_fs40.readFileSync)(skillPath, "utf8");
|
|
14429
14760
|
if (raw.startsWith("---")) {
|
|
14430
14761
|
const end = raw.indexOf("\n---", 3);
|
|
14431
14762
|
if (end >= 0) {
|
|
@@ -14439,13 +14770,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
14439
14770
|
|
|
14440
14771
|
\u2026(truncated)` : raw;
|
|
14441
14772
|
}
|
|
14442
|
-
var
|
|
14773
|
+
var import_node_fs40, import_node_os11, import_node_path36;
|
|
14443
14774
|
var init_discover = __esm({
|
|
14444
14775
|
"src/skills/discover.ts"() {
|
|
14445
14776
|
"use strict";
|
|
14446
|
-
|
|
14777
|
+
import_node_fs40 = require("fs");
|
|
14447
14778
|
import_node_os11 = require("os");
|
|
14448
|
-
|
|
14779
|
+
import_node_path36 = require("path");
|
|
14449
14780
|
}
|
|
14450
14781
|
});
|
|
14451
14782
|
|
|
@@ -14536,7 +14867,7 @@ var init_expand = __esm({
|
|
|
14536
14867
|
|
|
14537
14868
|
// src/composer/stage-files.ts
|
|
14538
14869
|
function fileExtension(filePath) {
|
|
14539
|
-
const base = (0,
|
|
14870
|
+
const base = (0, import_node_path37.basename)(filePath).toLowerCase();
|
|
14540
14871
|
return base.includes(".") ? base.split(".").pop() || "" : "";
|
|
14541
14872
|
}
|
|
14542
14873
|
function isImageFilePath(filePath) {
|
|
@@ -14546,22 +14877,22 @@ function imageMimeType(filePath) {
|
|
|
14546
14877
|
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
14547
14878
|
}
|
|
14548
14879
|
function ensureAttachmentsDir(worktreePath) {
|
|
14549
|
-
const dir = (0,
|
|
14550
|
-
(0,
|
|
14551
|
-
const gi = (0,
|
|
14552
|
-
if (!(0,
|
|
14553
|
-
(0,
|
|
14880
|
+
const dir = (0, import_node_path37.join)(worktreePath, ATTACHMENTS_DIR);
|
|
14881
|
+
(0, import_node_fs41.mkdirSync)(dir, { recursive: true });
|
|
14882
|
+
const gi = (0, import_node_path37.join)(dir, ".gitignore");
|
|
14883
|
+
if (!(0, import_node_fs41.existsSync)(gi)) {
|
|
14884
|
+
(0, import_node_fs41.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
|
|
14554
14885
|
}
|
|
14555
14886
|
return dir;
|
|
14556
14887
|
}
|
|
14557
14888
|
function uniqueAttachmentName(dir, originalName) {
|
|
14558
14889
|
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
14559
|
-
if (!(0,
|
|
14560
|
-
const ext = (0,
|
|
14890
|
+
if (!(0, import_node_fs41.existsSync)((0, import_node_path37.join)(dir, safe))) return safe;
|
|
14891
|
+
const ext = (0, import_node_path37.extname)(safe);
|
|
14561
14892
|
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
14562
14893
|
for (let i = 1; i < 1e4; i++) {
|
|
14563
14894
|
const candidate = `${stem}-${i}${ext}`;
|
|
14564
|
-
if (!(0,
|
|
14895
|
+
if (!(0, import_node_fs41.existsSync)((0, import_node_path37.join)(dir, candidate))) return candidate;
|
|
14565
14896
|
}
|
|
14566
14897
|
return `${stem}-${(0, import_node_crypto8.randomUUID)()}${ext}`;
|
|
14567
14898
|
}
|
|
@@ -14613,9 +14944,9 @@ function attachmentFromBuffer(name, buf, opts) {
|
|
|
14613
14944
|
};
|
|
14614
14945
|
}
|
|
14615
14946
|
function attachmentFromAbsolutePath(absolutePath) {
|
|
14616
|
-
const name = (0,
|
|
14947
|
+
const name = (0, import_node_path37.basename)(absolutePath);
|
|
14617
14948
|
try {
|
|
14618
|
-
const st = (0,
|
|
14949
|
+
const st = (0, import_node_fs41.statSync)(absolutePath);
|
|
14619
14950
|
if (!st.isFile()) {
|
|
14620
14951
|
return {
|
|
14621
14952
|
id: (0, import_node_crypto8.randomUUID)(),
|
|
@@ -14624,7 +14955,7 @@ function attachmentFromAbsolutePath(absolutePath) {
|
|
|
14624
14955
|
content: `(not a file: ${absolutePath})`
|
|
14625
14956
|
};
|
|
14626
14957
|
}
|
|
14627
|
-
const buf = (0,
|
|
14958
|
+
const buf = (0, import_node_fs41.readFileSync)(absolutePath);
|
|
14628
14959
|
return attachmentFromBuffer(name, buf, { sourceLabel: absolutePath });
|
|
14629
14960
|
} catch (err) {
|
|
14630
14961
|
return {
|
|
@@ -14640,15 +14971,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
|
14640
14971
|
const dir = ensureAttachmentsDir(worktreePath);
|
|
14641
14972
|
const out = [];
|
|
14642
14973
|
for (const abs of absolutePaths) {
|
|
14643
|
-
const originalName = (0,
|
|
14974
|
+
const originalName = (0, import_node_path37.basename)(abs);
|
|
14644
14975
|
try {
|
|
14645
|
-
const st = (0,
|
|
14976
|
+
const st = (0, import_node_fs41.statSync)(abs);
|
|
14646
14977
|
if (!st.isFile()) continue;
|
|
14647
14978
|
const name = uniqueAttachmentName(dir, originalName);
|
|
14648
|
-
const destAbs = (0,
|
|
14649
|
-
(0,
|
|
14979
|
+
const destAbs = (0, import_node_path37.join)(dir, name);
|
|
14980
|
+
(0, import_node_fs41.copyFileSync)(abs, destAbs);
|
|
14650
14981
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
14651
|
-
const buf = (0,
|
|
14982
|
+
const buf = (0, import_node_fs41.readFileSync)(destAbs);
|
|
14652
14983
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
14653
14984
|
} catch (err) {
|
|
14654
14985
|
out.push({
|
|
@@ -14670,8 +15001,8 @@ function stageBuffersAsAttachments(worktreePath, buffers2) {
|
|
|
14670
15001
|
try {
|
|
14671
15002
|
const buf = Buffer.from(item.dataBase64, "base64");
|
|
14672
15003
|
const name = uniqueAttachmentName(dir, originalName);
|
|
14673
|
-
const destAbs = (0,
|
|
14674
|
-
(0,
|
|
15004
|
+
const destAbs = (0, import_node_path37.join)(dir, name);
|
|
15005
|
+
(0, import_node_fs41.writeFileSync)(destAbs, buf);
|
|
14675
15006
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
14676
15007
|
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
14677
15008
|
} catch (err) {
|
|
@@ -14707,18 +15038,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
14707
15038
|
if (!rel || rel.includes("..") || rel.startsWith("/")) {
|
|
14708
15039
|
out.push({
|
|
14709
15040
|
id: (0, import_node_crypto8.randomUUID)(),
|
|
14710
|
-
name: (0,
|
|
15041
|
+
name: (0, import_node_path37.basename)(rel) || "file",
|
|
14711
15042
|
kind: "file",
|
|
14712
15043
|
content: `(invalid path: ${rel})`
|
|
14713
15044
|
});
|
|
14714
15045
|
continue;
|
|
14715
15046
|
}
|
|
14716
|
-
const name = (0,
|
|
15047
|
+
const name = (0, import_node_path37.basename)(rel);
|
|
14717
15048
|
try {
|
|
14718
|
-
const abs = (0,
|
|
14719
|
-
const st = (0,
|
|
15049
|
+
const abs = (0, import_node_path37.join)(worktreePath, rel);
|
|
15050
|
+
const st = (0, import_node_fs41.statSync)(abs);
|
|
14720
15051
|
if (!st.isFile()) continue;
|
|
14721
|
-
const buf = (0,
|
|
15052
|
+
const buf = (0, import_node_fs41.readFileSync)(abs);
|
|
14722
15053
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
14723
15054
|
} catch (err) {
|
|
14724
15055
|
out.push({
|
|
@@ -14731,12 +15062,12 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
14731
15062
|
}
|
|
14732
15063
|
return out;
|
|
14733
15064
|
}
|
|
14734
|
-
var
|
|
15065
|
+
var import_node_fs41, import_node_path37, import_node_crypto8, IMAGE_EXTENSIONS2, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES;
|
|
14735
15066
|
var init_stage_files = __esm({
|
|
14736
15067
|
"src/composer/stage-files.ts"() {
|
|
14737
15068
|
"use strict";
|
|
14738
|
-
|
|
14739
|
-
|
|
15069
|
+
import_node_fs41 = require("fs");
|
|
15070
|
+
import_node_path37 = require("path");
|
|
14740
15071
|
import_node_crypto8 = require("crypto");
|
|
14741
15072
|
init_workspace_scratch();
|
|
14742
15073
|
IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
@@ -14912,11 +15243,11 @@ function loadAgentInstructions(worktreePath, agent) {
|
|
|
14912
15243
|
const out = [];
|
|
14913
15244
|
for (const rel of candidates) {
|
|
14914
15245
|
if (seenPaths.has(rel)) continue;
|
|
14915
|
-
const abs = (0,
|
|
14916
|
-
if (!(0,
|
|
15246
|
+
const abs = (0, import_node_path38.join)(worktreePath, rel);
|
|
15247
|
+
if (!(0, import_node_fs42.existsSync)(abs)) continue;
|
|
14917
15248
|
try {
|
|
14918
|
-
if (!(0,
|
|
14919
|
-
let content = (0,
|
|
15249
|
+
if (!(0, import_node_fs42.statSync)(abs).isFile()) continue;
|
|
15250
|
+
let content = (0, import_node_fs42.readFileSync)(abs, "utf8");
|
|
14920
15251
|
if (!content.trim()) continue;
|
|
14921
15252
|
if (content.length > MAX_CHARS_PER_FILE) {
|
|
14922
15253
|
content = `${content.slice(0, MAX_CHARS_PER_FILE)}
|
|
@@ -14956,12 +15287,12 @@ function withAgentInstructions(prompt, files) {
|
|
|
14956
15287
|
|
|
14957
15288
|
${prompt}`;
|
|
14958
15289
|
}
|
|
14959
|
-
var
|
|
15290
|
+
var import_node_fs42, import_node_path38, FILES_BY_AGENT, MAX_CHARS_PER_FILE;
|
|
14960
15291
|
var init_instructions = __esm({
|
|
14961
15292
|
"src/agents/instructions.ts"() {
|
|
14962
15293
|
"use strict";
|
|
14963
|
-
|
|
14964
|
-
|
|
15294
|
+
import_node_fs42 = require("fs");
|
|
15295
|
+
import_node_path38 = require("path");
|
|
14965
15296
|
init_git_auth_mode();
|
|
14966
15297
|
init_worktree_labels();
|
|
14967
15298
|
FILES_BY_AGENT = {
|
|
@@ -15051,40 +15382,40 @@ __export(plan_file_exports, {
|
|
|
15051
15382
|
writePlanFile: () => writePlanFile
|
|
15052
15383
|
});
|
|
15053
15384
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
15054
|
-
const gitignoreAbs = (0,
|
|
15055
|
-
if ((0,
|
|
15056
|
-
(0,
|
|
15057
|
-
(0,
|
|
15385
|
+
const gitignoreAbs = (0, import_node_path39.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
15386
|
+
if ((0, import_node_fs43.existsSync)(gitignoreAbs)) return;
|
|
15387
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path39.dirname)(gitignoreAbs), { recursive: true });
|
|
15388
|
+
(0, import_node_fs43.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
15058
15389
|
}
|
|
15059
15390
|
function planFileAbs(worktreePath) {
|
|
15060
|
-
return (0,
|
|
15391
|
+
return (0, import_node_path39.join)(worktreePath, PLAN_FILE_REL);
|
|
15061
15392
|
}
|
|
15062
15393
|
function readTextIfPresent2(abs) {
|
|
15063
|
-
if (!(0,
|
|
15394
|
+
if (!(0, import_node_fs43.existsSync)(abs)) return null;
|
|
15064
15395
|
try {
|
|
15065
|
-
const content = (0,
|
|
15396
|
+
const content = (0, import_node_fs43.readFileSync)(abs, "utf8");
|
|
15066
15397
|
return content.trim() ? content : null;
|
|
15067
15398
|
} catch {
|
|
15068
15399
|
return null;
|
|
15069
15400
|
}
|
|
15070
15401
|
}
|
|
15071
15402
|
function readPlanFile(worktreePath) {
|
|
15072
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
15403
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path39.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path39.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
15073
15404
|
}
|
|
15074
15405
|
function writePlanFile(worktreePath, content) {
|
|
15075
15406
|
ensureAttachmentsGitignore(worktreePath);
|
|
15076
15407
|
const abs = planFileAbs(worktreePath);
|
|
15077
|
-
(0,
|
|
15408
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path39.dirname)(abs), { recursive: true });
|
|
15078
15409
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
15079
|
-
(0,
|
|
15410
|
+
(0, import_node_fs43.writeFileSync)(abs, body, "utf8");
|
|
15080
15411
|
return PLAN_FILE_REL;
|
|
15081
15412
|
}
|
|
15082
|
-
var
|
|
15413
|
+
var import_node_fs43, import_node_path39;
|
|
15083
15414
|
var init_plan_file = __esm({
|
|
15084
15415
|
"src/plan/plan-file.ts"() {
|
|
15085
15416
|
"use strict";
|
|
15086
|
-
|
|
15087
|
-
|
|
15417
|
+
import_node_fs43 = require("fs");
|
|
15418
|
+
import_node_path39 = require("path");
|
|
15088
15419
|
init_workspace_scratch();
|
|
15089
15420
|
init_plan_present();
|
|
15090
15421
|
init_plan_present();
|
|
@@ -15138,10 +15469,10 @@ __export(cursor_recover_exports, {
|
|
|
15138
15469
|
function recoverFinishedCursorRun(opts) {
|
|
15139
15470
|
const agentId = opts.agentId.trim();
|
|
15140
15471
|
if (!agentId) return null;
|
|
15141
|
-
const runsPath = (0,
|
|
15142
|
-
if (!(0,
|
|
15472
|
+
const runsPath = (0, import_node_path40.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
|
|
15473
|
+
if (!(0, import_node_fs44.existsSync)(runsPath)) return null;
|
|
15143
15474
|
try {
|
|
15144
|
-
const lines = (0,
|
|
15475
|
+
const lines = (0, import_node_fs44.readFileSync)(runsPath, "utf8").split("\n");
|
|
15145
15476
|
let best = null;
|
|
15146
15477
|
for (const line of lines) {
|
|
15147
15478
|
const trimmed = line.trim();
|
|
@@ -15167,12 +15498,12 @@ function recoverFinishedCursorRun(opts) {
|
|
|
15167
15498
|
return null;
|
|
15168
15499
|
}
|
|
15169
15500
|
}
|
|
15170
|
-
var
|
|
15501
|
+
var import_node_fs44, import_node_path40;
|
|
15171
15502
|
var init_cursor_recover = __esm({
|
|
15172
15503
|
"src/agents/cursor-recover.ts"() {
|
|
15173
15504
|
"use strict";
|
|
15174
|
-
|
|
15175
|
-
|
|
15505
|
+
import_node_fs44 = require("fs");
|
|
15506
|
+
import_node_path40 = require("path");
|
|
15176
15507
|
init_paths();
|
|
15177
15508
|
}
|
|
15178
15509
|
});
|
|
@@ -15303,14 +15634,16 @@ async function startOrchestration(opts) {
|
|
|
15303
15634
|
}
|
|
15304
15635
|
return updated;
|
|
15305
15636
|
}
|
|
15306
|
-
var import_node_events,
|
|
15637
|
+
var import_node_events, import_node_fs45, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
|
|
15307
15638
|
var init_orchestrator = __esm({
|
|
15308
15639
|
"src/orchestrator/orchestrator.ts"() {
|
|
15309
15640
|
"use strict";
|
|
15310
15641
|
import_node_events = require("events");
|
|
15311
15642
|
init_outbound_watch();
|
|
15312
|
-
|
|
15643
|
+
import_node_fs45 = require("fs");
|
|
15313
15644
|
init_error_detail();
|
|
15645
|
+
init_run();
|
|
15646
|
+
init_stale_lock();
|
|
15314
15647
|
init_spawn();
|
|
15315
15648
|
init_agents();
|
|
15316
15649
|
init_worktree();
|
|
@@ -15426,7 +15759,7 @@ var init_orchestrator = __esm({
|
|
|
15426
15759
|
}
|
|
15427
15760
|
continue;
|
|
15428
15761
|
}
|
|
15429
|
-
if (!(0,
|
|
15762
|
+
if (!(0, import_node_fs45.existsSync)(thread.worktreePath)) {
|
|
15430
15763
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
15431
15764
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
15432
15765
|
continue;
|
|
@@ -16019,7 +16352,15 @@ var init_orchestrator = __esm({
|
|
|
16019
16352
|
hasSession: Boolean(this.requireThread(threadId).sessionId)
|
|
16020
16353
|
})) {
|
|
16021
16354
|
updateThread(threadId, { sessionId: null });
|
|
16022
|
-
|
|
16355
|
+
try {
|
|
16356
|
+
const gitDirs = await resolveGitDirsForLockRecovery(thread.worktreePath);
|
|
16357
|
+
const clearedLocks = clearStaleIndexLocks(gitDirs, 2e3);
|
|
16358
|
+
if (clearedLocks.length > 0) {
|
|
16359
|
+
pushTurnStderr(stderrTail, "Cleared a stale git lock left by the crashed agent process");
|
|
16360
|
+
}
|
|
16361
|
+
} catch {
|
|
16362
|
+
}
|
|
16363
|
+
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";
|
|
16023
16364
|
pushTurnStderr(stderrTail, retryNote);
|
|
16024
16365
|
this.emit({
|
|
16025
16366
|
type: "turn_output",
|
|
@@ -16491,13 +16832,14 @@ var init_orchestrator = __esm({
|
|
|
16491
16832
|
const text4 = (lastAgent?.text ?? "").trim() || (thread.status === "error" ? lastError ?? "" : "");
|
|
16492
16833
|
const stillRunning = thread.status === "running" || thread.status === "queued";
|
|
16493
16834
|
const live = stillRunning ? readTurnLive(thread.id) : null;
|
|
16835
|
+
const queuedHint = thread.status === "queued" && !live?.summary ? "Queued \u2014 waiting for a concurrency slot" : null;
|
|
16494
16836
|
return {
|
|
16495
16837
|
text: text4,
|
|
16496
16838
|
status: thread.status,
|
|
16497
16839
|
sessionId: thread.sessionId,
|
|
16498
16840
|
lastError,
|
|
16499
16841
|
stillRunning,
|
|
16500
|
-
progress: live?.summary ??
|
|
16842
|
+
progress: live?.summary ?? queuedHint,
|
|
16501
16843
|
lastActivityAt: live?.updatedAt ?? null
|
|
16502
16844
|
};
|
|
16503
16845
|
}
|
|
@@ -17014,7 +17356,7 @@ var init_orchestrator = __esm({
|
|
|
17014
17356
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
17015
17357
|
return restored2;
|
|
17016
17358
|
}
|
|
17017
|
-
if (!(0,
|
|
17359
|
+
if (!(0, import_node_fs45.existsSync)(thread.worktreePath)) {
|
|
17018
17360
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
17019
17361
|
throw new Error(
|
|
17020
17362
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -17216,6 +17558,7 @@ var init_schedule_runner = __esm({
|
|
|
17216
17558
|
var index_exports = {};
|
|
17217
17559
|
__export(index_exports, {
|
|
17218
17560
|
AGENT_GIT_ACTIONS: () => AGENT_GIT_ACTIONS,
|
|
17561
|
+
AGENT_RUNNER_MAX_OLD_SPACE_MB: () => AGENT_RUNNER_MAX_OLD_SPACE_MB,
|
|
17219
17562
|
ATTACHMENTS_DIR: () => ATTACHMENTS_DIR,
|
|
17220
17563
|
BAKED_SLACK_RELAY_URL: () => BAKED_SLACK_RELAY_URL,
|
|
17221
17564
|
BRIGHTSY_MCP_ALLOWED_TOOLS: () => BRIGHTSY_MCP_ALLOWED_TOOLS,
|
|
@@ -17291,6 +17634,7 @@ __export(index_exports, {
|
|
|
17291
17634
|
appendIndexedGitConfig: () => appendIndexedGitConfig,
|
|
17292
17635
|
appendMessage: () => appendMessage,
|
|
17293
17636
|
applyAgentEvent: () => applyAgentEvent,
|
|
17637
|
+
applyAgentRunnerHeapEnv: () => applyAgentRunnerHeapEnv,
|
|
17294
17638
|
applyAppEnvironment: () => applyAppEnvironment,
|
|
17295
17639
|
applyCompaction: () => applyCompaction,
|
|
17296
17640
|
applyGithubGitAuthEnv: () => applyGithubGitAuthEnv,
|
|
@@ -17524,6 +17868,7 @@ __export(index_exports, {
|
|
|
17524
17868
|
isOrchestratorThread: () => isOrchestratorThread,
|
|
17525
17869
|
isPidAlive: () => isPidAlive,
|
|
17526
17870
|
isPlaceholderBranch: () => isPlaceholderBranch,
|
|
17871
|
+
isPollWrapperToolName: () => isPollWrapperToolName,
|
|
17527
17872
|
isPrNotMergeableError: () => isPrNotMergeableError,
|
|
17528
17873
|
isPresentPlanToolName: () => isPresentPlanToolName,
|
|
17529
17874
|
isPrimaryCheckoutThread: () => isPrimaryCheckoutThread,
|
|
@@ -17569,6 +17914,7 @@ __export(index_exports, {
|
|
|
17569
17914
|
listWorkspaces: () => listWorkspaces,
|
|
17570
17915
|
listWorktreeFiles: () => listWorktreeFiles,
|
|
17571
17916
|
listWorktrees: () => listWorktrees,
|
|
17917
|
+
liveActivitySummary: () => liveActivitySummary,
|
|
17572
17918
|
loadAgentInstructions: () => loadAgentInstructions,
|
|
17573
17919
|
loadAppSettings: () => loadAppSettings,
|
|
17574
17920
|
loadBrightsyConfig: () => loadBrightsyConfig,
|
|
@@ -17662,6 +18008,7 @@ __export(index_exports, {
|
|
|
17662
18008
|
resolveEffectiveIssueSource: () => resolveEffectiveIssueSource,
|
|
17663
18009
|
resolveFilesToCopy: () => resolveFilesToCopy,
|
|
17664
18010
|
resolveGhAuthToken: () => resolveGhAuthToken,
|
|
18011
|
+
resolveGitDirsForLockRecovery: () => resolveGitDirsForLockRecovery,
|
|
17665
18012
|
resolveGithubAgentToken: () => resolveGithubAgentToken,
|
|
17666
18013
|
resolveGithubRepoSlug: () => resolveGithubRepoSlug,
|
|
17667
18014
|
resolveLinearState: () => resolveLinearState,
|
|
@@ -17755,6 +18102,7 @@ __export(index_exports, {
|
|
|
17755
18102
|
threadsDir: () => threadsDir,
|
|
17756
18103
|
threadsSharingWorktree: () => threadsSharingWorktree,
|
|
17757
18104
|
toPublicAppSettings: () => toPublicAppSettings,
|
|
18105
|
+
toolActivityLine: () => toolActivityLine,
|
|
17758
18106
|
toolDescription: () => toolDescription,
|
|
17759
18107
|
toolDetail: () => toolDetail,
|
|
17760
18108
|
toolFilePath: () => toolFilePath,
|
|
@@ -17780,6 +18128,7 @@ __export(index_exports, {
|
|
|
17780
18128
|
withEventParentId: () => withEventParentId,
|
|
17781
18129
|
withEventsParentId: () => withEventsParentId,
|
|
17782
18130
|
withExportedPath: () => withExportedPath,
|
|
18131
|
+
withMaxOldSpaceSize: () => withMaxOldSpaceSize,
|
|
17783
18132
|
withThreadLock: () => withThreadLock,
|
|
17784
18133
|
workspaceSettingsSourceLabel: () => workspaceSettingsSourceLabel,
|
|
17785
18134
|
worktreeCleanupSettings: () => worktreeCleanupSettings,
|
|
@@ -18751,7 +19100,7 @@ init_orphan_cleanup();
|
|
|
18751
19100
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
18752
19101
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
18753
19102
|
var import_zod4 = require("zod");
|
|
18754
|
-
var
|
|
19103
|
+
var import_node_path41 = require("path");
|
|
18755
19104
|
init_orchestrator();
|
|
18756
19105
|
init_worktree();
|
|
18757
19106
|
init_create();
|
|
@@ -18778,6 +19127,10 @@ function mcpWaitForTurnTimeoutMs(requested) {
|
|
|
18778
19127
|
return Math.min(Math.max(1e3, Math.floor(n)), MCP_WAIT_FOR_TURN_MAX_MS);
|
|
18779
19128
|
}
|
|
18780
19129
|
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.";
|
|
19130
|
+
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.";
|
|
19131
|
+
function mcpWaitStillRunningHint(status) {
|
|
19132
|
+
return status === "queued" ? MCP_WAIT_QUEUED_HINT : MCP_WAIT_STILL_RUNNING_HINT;
|
|
19133
|
+
}
|
|
18781
19134
|
|
|
18782
19135
|
// src/mcp/server.ts
|
|
18783
19136
|
init_turn_live();
|
|
@@ -19624,7 +19977,7 @@ async function startMcpServer() {
|
|
|
19624
19977
|
async () => {
|
|
19625
19978
|
const threads = orch.getThreads(true);
|
|
19626
19979
|
const lines = threads.map((t) => {
|
|
19627
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
19980
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path41.basename)(t.repoPath) || t.repoPath;
|
|
19628
19981
|
const live = t.status === "running" || t.status === "queued" ? readTurnLive(t.id) : null;
|
|
19629
19982
|
const progress = live?.summary ? ` ${live.summary}` : "";
|
|
19630
19983
|
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}`;
|
|
@@ -19660,7 +20013,7 @@ async function startMcpServer() {
|
|
|
19660
20013
|
prUrl: t.prUrl,
|
|
19661
20014
|
lastError: t.lastError ?? null,
|
|
19662
20015
|
stillRunning: t.status === "running" || t.status === "queued",
|
|
19663
|
-
progress: live?.summary ?? null,
|
|
20016
|
+
progress: live?.summary ?? (t.status === "queued" ? "Queued \u2014 waiting for a concurrency slot" : null),
|
|
19664
20017
|
lastActivityAt: live?.updatedAt ?? null
|
|
19665
20018
|
};
|
|
19666
20019
|
return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
|
|
@@ -19994,7 +20347,7 @@ async function startMcpServer() {
|
|
|
19994
20347
|
);
|
|
19995
20348
|
server.tool(
|
|
19996
20349
|
"wait_for_turn",
|
|
19997
|
-
"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 \
|
|
20350
|
+
"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.",
|
|
19998
20351
|
{
|
|
19999
20352
|
ref: import_zod4.z.string(),
|
|
20000
20353
|
timeoutMs: import_zod4.z.number().optional()
|
|
@@ -20016,7 +20369,7 @@ async function startMcpServer() {
|
|
|
20016
20369
|
stillRunning: result.stillRunning,
|
|
20017
20370
|
progress: result.progress,
|
|
20018
20371
|
lastActivityAt: result.lastActivityAt,
|
|
20019
|
-
hint: result.stillRunning ?
|
|
20372
|
+
hint: result.stillRunning ? mcpWaitStillRunningHint(result.status) : void 0
|
|
20020
20373
|
})
|
|
20021
20374
|
}
|
|
20022
20375
|
]
|
|
@@ -20035,7 +20388,7 @@ async function startMcpServer() {
|
|
|
20035
20388
|
type: "text",
|
|
20036
20389
|
text: JSON.stringify({
|
|
20037
20390
|
...result,
|
|
20038
|
-
hint: result.stillRunning ?
|
|
20391
|
+
hint: result.stillRunning ? mcpWaitStillRunningHint(result.status) : void 0
|
|
20039
20392
|
})
|
|
20040
20393
|
}
|
|
20041
20394
|
]
|
|
@@ -20964,16 +21317,16 @@ init_connected_teams();
|
|
|
20964
21317
|
init_injected_mcp();
|
|
20965
21318
|
|
|
20966
21319
|
// src/agents/user-mcp-config.ts
|
|
20967
|
-
var
|
|
21320
|
+
var import_node_fs46 = require("fs");
|
|
20968
21321
|
var import_node_os12 = require("os");
|
|
20969
|
-
var
|
|
21322
|
+
var import_node_path42 = require("path");
|
|
20970
21323
|
init_paths();
|
|
20971
21324
|
init_injected_mcp();
|
|
20972
21325
|
function userCursorMcpConfigPath() {
|
|
20973
|
-
return (0,
|
|
21326
|
+
return (0, import_node_path42.join)((0, import_node_os12.homedir)(), ".cursor", "mcp.json");
|
|
20974
21327
|
}
|
|
20975
21328
|
function userClaudeMcpConfigPath() {
|
|
20976
|
-
return (0,
|
|
21329
|
+
return (0, import_node_path42.join)((0, import_node_os12.homedir)(), ".claude.json");
|
|
20977
21330
|
}
|
|
20978
21331
|
function asObject(value) {
|
|
20979
21332
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
@@ -21000,16 +21353,16 @@ function mergeSideboardIntoMcpServersJson(existing, sideboard) {
|
|
|
21000
21353
|
}
|
|
21001
21354
|
function writeMergedMcpServersJson(configPath, sideboard) {
|
|
21002
21355
|
let existing = {};
|
|
21003
|
-
if ((0,
|
|
21356
|
+
if ((0, import_node_fs46.existsSync)(configPath)) {
|
|
21004
21357
|
try {
|
|
21005
|
-
existing = JSON.parse((0,
|
|
21358
|
+
existing = JSON.parse((0, import_node_fs46.readFileSync)(configPath, "utf8"));
|
|
21006
21359
|
} catch {
|
|
21007
21360
|
existing = {};
|
|
21008
21361
|
}
|
|
21009
21362
|
}
|
|
21010
21363
|
const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
|
|
21011
|
-
(0,
|
|
21012
|
-
(0,
|
|
21364
|
+
(0, import_node_fs46.mkdirSync)((0, import_node_path42.dirname)(configPath), { recursive: true });
|
|
21365
|
+
(0, import_node_fs46.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
|
|
21013
21366
|
`);
|
|
21014
21367
|
}
|
|
21015
21368
|
function launchFromResolved(server) {
|
|
@@ -21027,7 +21380,7 @@ async function registerPackagedUserMcpClients() {
|
|
|
21027
21380
|
const cursor = userCursorMcpConfigPath();
|
|
21028
21381
|
writeMergedMcpServersJson(cursor, launch);
|
|
21029
21382
|
const claude = userClaudeMcpConfigPath();
|
|
21030
|
-
if ((0,
|
|
21383
|
+
if ((0, import_node_fs46.existsSync)(claude)) {
|
|
21031
21384
|
writeMergedMcpServersJson(claude, launch);
|
|
21032
21385
|
return { cursor, claude };
|
|
21033
21386
|
}
|
|
@@ -22657,9 +23010,9 @@ var import_node_http3 = require("http");
|
|
|
22657
23010
|
var import_ws3 = require("ws");
|
|
22658
23011
|
|
|
22659
23012
|
// src/slack/relay-static.ts
|
|
22660
|
-
var
|
|
23013
|
+
var import_node_fs47 = require("fs");
|
|
22661
23014
|
var import_promises = require("fs/promises");
|
|
22662
|
-
var
|
|
23015
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
22663
23016
|
var TYPES = {
|
|
22664
23017
|
".css": "text/css; charset=utf-8",
|
|
22665
23018
|
".html": "text/html; charset=utf-8",
|
|
@@ -22690,9 +23043,9 @@ function resolveStaticPath(root, requestUrl) {
|
|
|
22690
23043
|
return null;
|
|
22691
23044
|
}
|
|
22692
23045
|
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
22693
|
-
const rootResolved =
|
|
22694
|
-
const candidate =
|
|
22695
|
-
if (candidate !== rootResolved && !candidate.startsWith(rootResolved +
|
|
23046
|
+
const rootResolved = import_node_path43.default.resolve(root);
|
|
23047
|
+
const candidate = import_node_path43.default.resolve(rootResolved, `.${pathname}`);
|
|
23048
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path43.default.sep)) {
|
|
22696
23049
|
return null;
|
|
22697
23050
|
}
|
|
22698
23051
|
return candidate;
|
|
@@ -22706,7 +23059,7 @@ async function fileSize(file) {
|
|
|
22706
23059
|
}
|
|
22707
23060
|
}
|
|
22708
23061
|
function sendFile(req, res, file, size) {
|
|
22709
|
-
const ext =
|
|
23062
|
+
const ext = import_node_path43.default.extname(file).toLowerCase();
|
|
22710
23063
|
res.writeHead(200, {
|
|
22711
23064
|
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
22712
23065
|
"Content-Length": size,
|
|
@@ -22716,7 +23069,7 @@ function sendFile(req, res, file, size) {
|
|
|
22716
23069
|
res.end();
|
|
22717
23070
|
return true;
|
|
22718
23071
|
}
|
|
22719
|
-
(0,
|
|
23072
|
+
(0, import_node_fs47.createReadStream)(file).pipe(res);
|
|
22720
23073
|
return true;
|
|
22721
23074
|
}
|
|
22722
23075
|
async function tryServeStatic(req, res, root) {
|
|
@@ -22725,7 +23078,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
22725
23078
|
if (!candidate) return false;
|
|
22726
23079
|
const direct = await fileSize(candidate);
|
|
22727
23080
|
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
22728
|
-
const asIndex =
|
|
23081
|
+
const asIndex = import_node_path43.default.join(candidate, "index.html");
|
|
22729
23082
|
const indexSize = await fileSize(asIndex);
|
|
22730
23083
|
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
22731
23084
|
return false;
|
|
@@ -22961,6 +23314,7 @@ init_outbound_watch();
|
|
|
22961
23314
|
// Annotate the CommonJS export names for ESM import in node:
|
|
22962
23315
|
0 && (module.exports = {
|
|
22963
23316
|
AGENT_GIT_ACTIONS,
|
|
23317
|
+
AGENT_RUNNER_MAX_OLD_SPACE_MB,
|
|
22964
23318
|
ATTACHMENTS_DIR,
|
|
22965
23319
|
BAKED_SLACK_RELAY_URL,
|
|
22966
23320
|
BRIGHTSY_MCP_ALLOWED_TOOLS,
|
|
@@ -23036,6 +23390,7 @@ init_outbound_watch();
|
|
|
23036
23390
|
appendIndexedGitConfig,
|
|
23037
23391
|
appendMessage,
|
|
23038
23392
|
applyAgentEvent,
|
|
23393
|
+
applyAgentRunnerHeapEnv,
|
|
23039
23394
|
applyAppEnvironment,
|
|
23040
23395
|
applyCompaction,
|
|
23041
23396
|
applyGithubGitAuthEnv,
|
|
@@ -23269,6 +23624,7 @@ init_outbound_watch();
|
|
|
23269
23624
|
isOrchestratorThread,
|
|
23270
23625
|
isPidAlive,
|
|
23271
23626
|
isPlaceholderBranch,
|
|
23627
|
+
isPollWrapperToolName,
|
|
23272
23628
|
isPrNotMergeableError,
|
|
23273
23629
|
isPresentPlanToolName,
|
|
23274
23630
|
isPrimaryCheckoutThread,
|
|
@@ -23314,6 +23670,7 @@ init_outbound_watch();
|
|
|
23314
23670
|
listWorkspaces,
|
|
23315
23671
|
listWorktreeFiles,
|
|
23316
23672
|
listWorktrees,
|
|
23673
|
+
liveActivitySummary,
|
|
23317
23674
|
loadAgentInstructions,
|
|
23318
23675
|
loadAppSettings,
|
|
23319
23676
|
loadBrightsyConfig,
|
|
@@ -23407,6 +23764,7 @@ init_outbound_watch();
|
|
|
23407
23764
|
resolveEffectiveIssueSource,
|
|
23408
23765
|
resolveFilesToCopy,
|
|
23409
23766
|
resolveGhAuthToken,
|
|
23767
|
+
resolveGitDirsForLockRecovery,
|
|
23410
23768
|
resolveGithubAgentToken,
|
|
23411
23769
|
resolveGithubRepoSlug,
|
|
23412
23770
|
resolveLinearState,
|
|
@@ -23500,6 +23858,7 @@ init_outbound_watch();
|
|
|
23500
23858
|
threadsDir,
|
|
23501
23859
|
threadsSharingWorktree,
|
|
23502
23860
|
toPublicAppSettings,
|
|
23861
|
+
toolActivityLine,
|
|
23503
23862
|
toolDescription,
|
|
23504
23863
|
toolDetail,
|
|
23505
23864
|
toolFilePath,
|
|
@@ -23525,6 +23884,7 @@ init_outbound_watch();
|
|
|
23525
23884
|
withEventParentId,
|
|
23526
23885
|
withEventsParentId,
|
|
23527
23886
|
withExportedPath,
|
|
23887
|
+
withMaxOldSpaceSize,
|
|
23528
23888
|
withThreadLock,
|
|
23529
23889
|
workspaceSettingsSourceLabel,
|
|
23530
23890
|
worktreeCleanupSettings,
|