@sideboard-ai/core 0.1.111 → 0.1.116
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/cursor-runner.cjs +51 -21
- package/dist/agents/cursor-runner.js +3 -3
- package/dist/{agents-NN22A4G5.js → agents-7NIX44RB.js} +7 -7
- package/dist/{agents-GH3FWDW2.js → agents-DU7DHY7A.js} +10 -10
- package/dist/{chunk-JTQQPJAU.js → chunk-4HOFVKPC.js} +52 -38
- package/dist/{chunk-4EWPKYOU.js → chunk-4OJMZ6P2.js} +2 -2
- package/dist/{chunk-NC3U42ZP.js → chunk-5KSLD4MU.js} +317 -33
- package/dist/{chunk-KQBI5HNT.js → chunk-7WC5UWEB.js} +2 -2
- package/dist/{chunk-WIHKHR5R.js → chunk-AXQ4ZWHK.js} +5 -0
- package/dist/{chunk-LGXBYZZA.js → chunk-DVM4ID64.js} +69 -13
- package/dist/{chunk-DMJKOFTO.js → chunk-DWP25N32.js} +44 -35
- package/dist/{chunk-2GO3YKBA.js → chunk-EKIDHL2T.js} +4 -4
- package/dist/{chunk-C4KHDW3U.js → chunk-FZCIQYNQ.js} +1 -1
- package/dist/{chunk-363Z34PY.js → chunk-GBY7OOMB.js} +273 -218
- package/dist/{chunk-7KWYXGIU.js → chunk-K3TIQXOH.js} +2 -2
- package/dist/{chunk-3KETJKYA.js → chunk-KPIYENTF.js} +69 -13
- package/dist/{chunk-KVFNTWFG.js → chunk-OFF5AFCR.js} +300 -43
- package/dist/{chunk-VOD3HFLP.js → chunk-XOYQ7LNQ.js} +2 -2
- package/dist/{chunk-7YKXHBIW.js → chunk-YMRT2DU6.js} +3 -3
- package/dist/{chunk-YXDR43ZC.js → chunk-ZMROW673.js} +5 -5
- package/dist/{chunk-YFAXVUY2.js → chunk-ZRCX43LS.js} +2 -2
- package/dist/{chunk-AROMOP3C.js → chunk-ZYEFCSZJ.js} +2 -2
- package/dist/{connected-teams-M5XNXRI5.js → connected-teams-O6D4PM7A.js} +2 -2
- package/dist/{connected-teams-J4I5AKMR.js → connected-teams-ZCOU6KCD.js} +2 -2
- package/dist/{coordinator-prompt-AR66L3N4.js → coordinator-prompt-4KCALEKD.js} +3 -3
- package/dist/{coordinator-prompt-BHMLWL64.js → coordinator-prompt-FML4I5AR.js} +3 -3
- package/dist/{global-workspace-XSUFEIAQ.js → global-workspace-CSWABOG5.js} +4 -4
- package/dist/{global-workspace-SKFODUQQ.js → global-workspace-H4YNASM6.js} +4 -4
- package/dist/index.cjs +855 -440
- package/dist/index.d.cts +59 -1
- package/dist/index.d.ts +59 -1
- package/dist/index.js +37 -17
- package/dist/mcp/run-stdio.cjs +966 -635
- package/dist/mcp/run-stdio.js +20 -16
- package/dist/{orchestrator-4T2SXDZ7.js → orchestrator-NXPANCZA.js} +8 -8
- package/dist/{orchestrator-EP57AB5W.js → orchestrator-ZY4RUJKT.js} +10 -10
- package/dist/{run-XKTAJRWF.js → run-USF6FRKV.js} +3 -1
- package/dist/{run-CFKZPY7F.js → run-XQKGHQZ2.js} +3 -1
- package/dist/{workspaces-XAQVKTLO.js → workspaces-HJ3EVATC.js} +5 -5
- package/dist/{workspaces-HV3J4TTW.js → workspaces-QG6PGFQR.js} +5 -5
- package/dist/{worktree-XFJED3VU.js → worktree-IW3BX26B.js} +2 -2
- package/dist/{worktree-N2EV24EE.js → worktree-OTFQO2W7.js} +2 -2
- package/package.json +1 -1
package/dist/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,151 @@ 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 isShellToolName(name) {
|
|
7770
|
+
return classifyTool(name ?? "") === "shell";
|
|
7771
|
+
}
|
|
7772
|
+
function toolActivityLine(parts) {
|
|
7773
|
+
const tools = parts.filter((p) => {
|
|
7774
|
+
if (p.type !== "tool" || p.parentId) return false;
|
|
7775
|
+
if (isPollWrapperToolName(p.name)) return false;
|
|
7776
|
+
if (/present_plan$/i.test(p.name ?? "")) return false;
|
|
7777
|
+
if (/ask_user|AskUserQuestion/i.test(p.name ?? "")) return false;
|
|
7778
|
+
return true;
|
|
7779
|
+
});
|
|
7780
|
+
if (tools.length === 0) return null;
|
|
7781
|
+
const edited = [];
|
|
7782
|
+
let reads = 0;
|
|
7783
|
+
let searches = 0;
|
|
7784
|
+
let shells = 0;
|
|
7785
|
+
let others = 0;
|
|
7786
|
+
let additions = 0;
|
|
7787
|
+
let deletions = 0;
|
|
7788
|
+
for (const tool of tools) {
|
|
7789
|
+
const kind = classifyTool(tool.name);
|
|
7790
|
+
if (kind === "edit") {
|
|
7791
|
+
const path2 = tool.filePath ?? toolFilePath(tool.input);
|
|
7792
|
+
edited.push({
|
|
7793
|
+
name: path2 ? fileBasename(path2) : tool.name,
|
|
7794
|
+
running: tool.status === "running"
|
|
7795
|
+
});
|
|
7796
|
+
} else if (kind === "read") reads += 1;
|
|
7797
|
+
else if (kind === "search") searches += 1;
|
|
7798
|
+
else if (kind === "shell") shells += 1;
|
|
7799
|
+
else others += 1;
|
|
7800
|
+
if (typeof tool.additions === "number") additions += tool.additions;
|
|
7801
|
+
if (typeof tool.deletions === "number") deletions += tool.deletions;
|
|
7802
|
+
}
|
|
7803
|
+
const bits = [];
|
|
7804
|
+
const editing = edited.filter((e) => e.running);
|
|
7805
|
+
const editedDone = edited.filter((e) => !e.running);
|
|
7806
|
+
if (editing.length === 1) bits.push(`Editing ${editing[0].name}`);
|
|
7807
|
+
else if (editing.length > 1) bits.push(`Editing ${editing.length} files`);
|
|
7808
|
+
if (editedDone.length === 1) bits.push(`${editing.length ? "edited" : "Edited"} ${editedDone[0].name}`);
|
|
7809
|
+
else if (editedDone.length > 1) {
|
|
7810
|
+
bits.push(`${editing.length ? "edited" : "Edited"} ${editedDone.length} files`);
|
|
7811
|
+
}
|
|
7812
|
+
if (reads === 1) bits.push("explored 1 file");
|
|
7813
|
+
else if (reads > 1) bits.push(`explored ${reads} files`);
|
|
7814
|
+
if (searches === 1) bits.push("1 search");
|
|
7815
|
+
else if (searches > 1) bits.push(`${searches} searches`);
|
|
7816
|
+
if (shells === 1) bits.push("ran 1 command");
|
|
7817
|
+
else if (shells > 1) bits.push(`ran ${shells} commands`);
|
|
7818
|
+
if (others === 1) bits.push("1 tool");
|
|
7819
|
+
else if (others > 1) bits.push(`${others} tools`);
|
|
7820
|
+
if (bits.length === 0) return null;
|
|
7821
|
+
return { text: bits.join(", "), additions, deletions };
|
|
7822
|
+
}
|
|
7823
|
+
function liveActivitySummary(parts, opts) {
|
|
7824
|
+
if (opts?.queued && parts.length === 0) {
|
|
7825
|
+
return "Queued \u2014 waiting for a slot";
|
|
7826
|
+
}
|
|
7827
|
+
const tools = parts.filter((p) => p.type === "tool");
|
|
7828
|
+
const runningSubs = tools.filter(
|
|
7829
|
+
(t) => t.status === "running" && !t.parentId && isSubagentToolName(t.name)
|
|
7830
|
+
);
|
|
7831
|
+
const runningNested = [...tools].reverse().find((t) => t.status === "running" && t.parentId && !isPollWrapperToolName(t.name));
|
|
7832
|
+
const runningTop = [...tools].reverse().find(
|
|
7833
|
+
(t) => t.status === "running" && !t.parentId && !isPollWrapperToolName(t.name) && !isSubagentToolName(t.name)
|
|
7834
|
+
);
|
|
7835
|
+
const runningPoll = [...tools].reverse().find((t) => t.status === "running" && isPollWrapperToolName(t.name));
|
|
7836
|
+
const thinking = lastTextPart(parts, "thinking");
|
|
7837
|
+
const text4 = lastTextPart(parts, "text");
|
|
7838
|
+
if (runningSubs.length > 0) {
|
|
7839
|
+
const heads = runningSubs.map(toolLabel);
|
|
7840
|
+
const head = runningSubs.length === 1 ? heads[0] : `${runningSubs.length} subagents \xB7 ${heads.slice(0, 2).join(" \xB7 ")}`;
|
|
7841
|
+
if (runningNested) return `${head} \xB7 ${toolLabel(runningNested)}`;
|
|
7842
|
+
return head;
|
|
7843
|
+
}
|
|
7844
|
+
if (runningTop) return toolLabel(runningTop);
|
|
7845
|
+
if (runningPoll) return toolLabel(runningPoll);
|
|
7846
|
+
if (thinking) return thinking.length > 96 ? `\u2026${thinking.slice(-96)}` : thinking;
|
|
7847
|
+
if (text4) return "Writing reply\u2026";
|
|
7848
|
+
const last = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? tools.at(-1);
|
|
7849
|
+
if (last) {
|
|
7850
|
+
const label = toolLabel(last);
|
|
7851
|
+
return last.status === "running" ? label : `Finished ${label}`;
|
|
7852
|
+
}
|
|
7853
|
+
return "Working\u2026";
|
|
7854
|
+
}
|
|
7654
7855
|
function messagePartParentId(part) {
|
|
7655
7856
|
if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
|
|
7656
7857
|
return part.parentId;
|
|
@@ -7736,6 +7937,25 @@ function applyAgentEvent(parts, event) {
|
|
|
7736
7937
|
const data = event.data;
|
|
7737
7938
|
if (!data) return parts;
|
|
7738
7939
|
const next = [...parts];
|
|
7940
|
+
if (event.replace) {
|
|
7941
|
+
for (let i = next.length - 1; i >= 0; i--) {
|
|
7942
|
+
const prev = next[i];
|
|
7943
|
+
if (prev?.type === "thinking" && sameParentId(prev.parentId, event.parentId)) {
|
|
7944
|
+
next[i] = {
|
|
7945
|
+
type: "thinking",
|
|
7946
|
+
text: data,
|
|
7947
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
7948
|
+
};
|
|
7949
|
+
return next;
|
|
7950
|
+
}
|
|
7951
|
+
}
|
|
7952
|
+
next.push({
|
|
7953
|
+
type: "thinking",
|
|
7954
|
+
text: data,
|
|
7955
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
7956
|
+
});
|
|
7957
|
+
return next;
|
|
7958
|
+
}
|
|
7739
7959
|
const last = next[next.length - 1];
|
|
7740
7960
|
if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
|
|
7741
7961
|
next[next.length - 1] = {
|
|
@@ -7759,14 +7979,18 @@ function applyAgentEvent(parts, event) {
|
|
|
7759
7979
|
if (existing >= 0) {
|
|
7760
7980
|
const prev = parts[existing];
|
|
7761
7981
|
const next = [...parts];
|
|
7762
|
-
const mergedInput =
|
|
7982
|
+
const mergedInput = {
|
|
7983
|
+
...prev.input ?? {},
|
|
7984
|
+
...input ?? {}
|
|
7985
|
+
};
|
|
7986
|
+
const mergedRecord = Object.keys(mergedInput).length > 0 ? mergedInput : void 0;
|
|
7763
7987
|
next[existing] = {
|
|
7764
7988
|
...prev,
|
|
7765
7989
|
name: event.name || prev.name,
|
|
7766
|
-
input:
|
|
7767
|
-
description: toolDescription(event.name || prev.name,
|
|
7768
|
-
detail: toolDetail(event.name || prev.name,
|
|
7769
|
-
filePath: toolFilePath(
|
|
7990
|
+
input: mergedRecord,
|
|
7991
|
+
description: toolDescription(event.name || prev.name, mergedRecord),
|
|
7992
|
+
detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
|
|
7993
|
+
filePath: toolFilePath(mergedRecord) ?? prev.filePath,
|
|
7770
7994
|
additions: diff.additions ?? prev.additions,
|
|
7771
7995
|
deletions: diff.deletions ?? prev.deletions,
|
|
7772
7996
|
parentId: event.parentId ?? prev.parentId
|
|
@@ -7792,6 +8016,30 @@ function applyAgentEvent(parts, event) {
|
|
|
7792
8016
|
if (event.type === "tool_result") {
|
|
7793
8017
|
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
7794
8018
|
const fromResult = parseDiffStat(event.content);
|
|
8019
|
+
if (event.partial) {
|
|
8020
|
+
if (existing < 0) {
|
|
8021
|
+
return [
|
|
8022
|
+
...parts,
|
|
8023
|
+
{
|
|
8024
|
+
type: "tool",
|
|
8025
|
+
id: event.id,
|
|
8026
|
+
name: "tool",
|
|
8027
|
+
description: "tool",
|
|
8028
|
+
status: event.isError ? "error" : "running",
|
|
8029
|
+
result: event.content,
|
|
8030
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
8031
|
+
}
|
|
8032
|
+
];
|
|
8033
|
+
}
|
|
8034
|
+
return parts.map((p, i) => {
|
|
8035
|
+
if (i !== existing || p.type !== "tool") return p;
|
|
8036
|
+
if (p.status === "done" || p.status === "error") return p;
|
|
8037
|
+
return {
|
|
8038
|
+
...p,
|
|
8039
|
+
result: event.content ?? p.result
|
|
8040
|
+
};
|
|
8041
|
+
});
|
|
8042
|
+
}
|
|
7795
8043
|
if (existing < 0) {
|
|
7796
8044
|
return [
|
|
7797
8045
|
...parts,
|
|
@@ -7884,47 +8132,68 @@ function electronResourcesPath() {
|
|
|
7884
8132
|
function packagedCursorRuntimeDir() {
|
|
7885
8133
|
const resources = electronResourcesPath();
|
|
7886
8134
|
if (!resources) return null;
|
|
7887
|
-
const dir = (0,
|
|
7888
|
-
if (!(0,
|
|
8135
|
+
const dir = (0, import_node_path23.join)(resources, "cursor-runtime");
|
|
8136
|
+
if (!(0, import_node_fs22.existsSync)((0, import_node_path23.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
|
|
7889
8137
|
return dir;
|
|
7890
8138
|
}
|
|
7891
8139
|
function packagedCursorRunnerPath() {
|
|
7892
8140
|
const dir = packagedCursorRuntimeDir();
|
|
7893
|
-
return dir ? (0,
|
|
8141
|
+
return dir ? (0, import_node_path23.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
|
|
7894
8142
|
}
|
|
7895
8143
|
function packagedMcpDir() {
|
|
7896
8144
|
const resources = electronResourcesPath();
|
|
7897
8145
|
if (!resources) return null;
|
|
7898
|
-
const dir = (0,
|
|
7899
|
-
if (!(0,
|
|
8146
|
+
const dir = (0, import_node_path23.join)(resources, "sideboard-mcp");
|
|
8147
|
+
if (!(0, import_node_fs22.existsSync)((0, import_node_path23.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
|
|
7900
8148
|
return dir;
|
|
7901
8149
|
}
|
|
7902
8150
|
function packagedMcpStdioPath() {
|
|
7903
8151
|
const dir = packagedMcpDir();
|
|
7904
|
-
return dir ? (0,
|
|
8152
|
+
return dir ? (0, import_node_path23.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
|
|
7905
8153
|
}
|
|
7906
8154
|
function packagedBundledNodePath() {
|
|
7907
8155
|
const resources = electronResourcesPath();
|
|
7908
8156
|
if (!resources) return null;
|
|
7909
|
-
const bin = (0,
|
|
7910
|
-
if (!(0,
|
|
8157
|
+
const bin = (0, import_node_path23.join)(resources, "node", "bin", "node");
|
|
8158
|
+
if (!(0, import_node_fs22.existsSync)(bin)) return null;
|
|
7911
8159
|
return bin;
|
|
7912
8160
|
}
|
|
7913
8161
|
function packagedCursorRipgrepCandidate(platformPkg, binName) {
|
|
7914
8162
|
const dir = packagedCursorRuntimeDir();
|
|
7915
8163
|
if (!dir) return null;
|
|
7916
|
-
return (0,
|
|
8164
|
+
return (0, import_node_path23.join)(dir, "node_modules", platformPkg, "bin", binName);
|
|
7917
8165
|
}
|
|
7918
|
-
var
|
|
8166
|
+
var import_node_fs22, import_node_path23;
|
|
7919
8167
|
var init_packaged_runtime = __esm({
|
|
7920
8168
|
"src/agents/packaged-runtime.ts"() {
|
|
7921
8169
|
"use strict";
|
|
7922
|
-
|
|
7923
|
-
|
|
8170
|
+
import_node_fs22 = require("fs");
|
|
8171
|
+
import_node_path23 = require("path");
|
|
7924
8172
|
}
|
|
7925
8173
|
});
|
|
7926
8174
|
|
|
7927
8175
|
// src/agents/node-launch.ts
|
|
8176
|
+
function withMaxOldSpaceSize(nodeOptions, heapMb) {
|
|
8177
|
+
const existing = (nodeOptions ?? "").trim();
|
|
8178
|
+
const match = MAX_OLD_SPACE_FLAG.exec(existing);
|
|
8179
|
+
if (match) {
|
|
8180
|
+
const current = match[2] ? Number(match[2]) : 0;
|
|
8181
|
+
if (Number.isFinite(current) && current >= heapMb) return existing;
|
|
8182
|
+
return existing.replace(MAX_OLD_SPACE_FLAG, ` --max-old-space-size=${heapMb}`).trim();
|
|
8183
|
+
}
|
|
8184
|
+
return existing ? `${existing} --max-old-space-size=${heapMb}` : `--max-old-space-size=${heapMb}`;
|
|
8185
|
+
}
|
|
8186
|
+
function applyAgentRunnerHeapEnv(env) {
|
|
8187
|
+
env.NODE_OPTIONS = withMaxOldSpaceSize(
|
|
8188
|
+
env.NODE_OPTIONS,
|
|
8189
|
+
AGENT_RUNNER_MAX_OLD_SPACE_MB
|
|
8190
|
+
);
|
|
8191
|
+
}
|
|
8192
|
+
function envWithAgentHeap(env) {
|
|
8193
|
+
const next = { ...env };
|
|
8194
|
+
applyAgentRunnerHeapEnv(next);
|
|
8195
|
+
return next;
|
|
8196
|
+
}
|
|
7928
8197
|
function isAsarPath(filePath) {
|
|
7929
8198
|
if (/\.asar\.unpacked([/\\]|$)/.test(filePath)) return false;
|
|
7930
8199
|
return /\.asar([/\\]|$)/.test(filePath);
|
|
@@ -7933,7 +8202,7 @@ function unpackedAsarPath(filePath) {
|
|
|
7933
8202
|
if (!isAsarPath(filePath)) return null;
|
|
7934
8203
|
const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
|
|
7935
8204
|
if (unpacked === filePath) return null;
|
|
7936
|
-
return (0,
|
|
8205
|
+
return (0, import_node_fs23.existsSync)(unpacked) ? unpacked : null;
|
|
7937
8206
|
}
|
|
7938
8207
|
function nodeReadableScriptPath(scriptPath) {
|
|
7939
8208
|
return unpackedAsarPath(scriptPath) ?? scriptPath;
|
|
@@ -7973,37 +8242,37 @@ function pickPreferredNode(candidates) {
|
|
|
7973
8242
|
return best;
|
|
7974
8243
|
}
|
|
7975
8244
|
function versionDirNodeBins(root, toBin) {
|
|
7976
|
-
if (!(0,
|
|
8245
|
+
if (!(0, import_node_fs23.existsSync)(root)) return [];
|
|
7977
8246
|
try {
|
|
7978
|
-
return (0,
|
|
8247
|
+
return (0, import_node_fs23.readdirSync)(root).map(toBin);
|
|
7979
8248
|
} catch {
|
|
7980
8249
|
return [];
|
|
7981
8250
|
}
|
|
7982
8251
|
}
|
|
7983
8252
|
function defaultNodeBinCandidates(home = (0, import_node_os7.homedir)()) {
|
|
7984
8253
|
const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
|
|
7985
|
-
(prefix) => PREFERRED_LTS_MAJORS.map((major) => (0,
|
|
8254
|
+
(prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path24.join)(prefix, "opt", `node@${major}`, "bin", "node"))
|
|
7986
8255
|
);
|
|
7987
8256
|
return [
|
|
7988
8257
|
...kegs,
|
|
7989
8258
|
"/opt/homebrew/bin/node",
|
|
7990
8259
|
"/usr/local/bin/node",
|
|
7991
|
-
(0,
|
|
7992
|
-
(0,
|
|
7993
|
-
(0,
|
|
7994
|
-
(0,
|
|
7995
|
-
(0,
|
|
8260
|
+
(0, import_node_path24.join)(home, ".local/share/fnm/aliases/default/bin/node"),
|
|
8261
|
+
(0, import_node_path24.join)(home, ".nvm/current/bin/node"),
|
|
8262
|
+
(0, import_node_path24.join)(home, ".volta/bin/node"),
|
|
8263
|
+
(0, import_node_path24.join)(home, ".asdf/shims/node"),
|
|
8264
|
+
(0, import_node_path24.join)(home, ".local/share/mise/shims/node"),
|
|
7996
8265
|
...versionDirNodeBins(
|
|
7997
|
-
(0,
|
|
7998
|
-
(name) => (0,
|
|
8266
|
+
(0, import_node_path24.join)(home, ".nvm", "versions", "node"),
|
|
8267
|
+
(name) => (0, import_node_path24.join)(home, ".nvm", "versions", "node", name, "bin", "node")
|
|
7999
8268
|
),
|
|
8000
8269
|
...versionDirNodeBins(
|
|
8001
|
-
(0,
|
|
8002
|
-
(name) => (0,
|
|
8270
|
+
(0, import_node_path24.join)(home, ".local/share/fnm", "node-versions"),
|
|
8271
|
+
(name) => (0, import_node_path24.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
|
|
8003
8272
|
),
|
|
8004
8273
|
...versionDirNodeBins(
|
|
8005
|
-
(0,
|
|
8006
|
-
(name) => (0,
|
|
8274
|
+
(0, import_node_path24.join)(home, ".volta", "tools", "image", "node"),
|
|
8275
|
+
(name) => (0, import_node_path24.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
|
|
8007
8276
|
)
|
|
8008
8277
|
];
|
|
8009
8278
|
}
|
|
@@ -8012,10 +8281,10 @@ function uniqueExistingNodeBins(paths) {
|
|
|
8012
8281
|
const out = [];
|
|
8013
8282
|
for (const raw of paths) {
|
|
8014
8283
|
const p = raw.trim();
|
|
8015
|
-
if (!p || !(0,
|
|
8284
|
+
if (!p || !(0, import_node_fs23.existsSync)(p) || isElectronLikeCommand(p)) continue;
|
|
8016
8285
|
let key = p;
|
|
8017
8286
|
try {
|
|
8018
|
-
key = (0,
|
|
8287
|
+
key = (0, import_node_fs23.realpathSync)(p);
|
|
8019
8288
|
} catch {
|
|
8020
8289
|
continue;
|
|
8021
8290
|
}
|
|
@@ -8060,13 +8329,21 @@ async function findSystemNode() {
|
|
|
8060
8329
|
function applyNodeLaunch(launch, args) {
|
|
8061
8330
|
const readableArgs = args.map(nodeReadableScriptPath);
|
|
8062
8331
|
if (!launch.env.ELECTRON_RUN_AS_NODE) {
|
|
8063
|
-
return {
|
|
8332
|
+
return {
|
|
8333
|
+
file: launch.file,
|
|
8334
|
+
args: readableArgs,
|
|
8335
|
+
env: envWithAgentHeap(launch.env)
|
|
8336
|
+
};
|
|
8064
8337
|
}
|
|
8065
8338
|
const wrapped = wrapElectronAsNodeLaunch(launch.file, readableArgs);
|
|
8066
8339
|
if (process.platform === "win32") {
|
|
8067
|
-
return {
|
|
8340
|
+
return {
|
|
8341
|
+
file: wrapped.file,
|
|
8342
|
+
args: wrapped.args,
|
|
8343
|
+
env: envWithAgentHeap(launch.env)
|
|
8344
|
+
};
|
|
8068
8345
|
}
|
|
8069
|
-
const env =
|
|
8346
|
+
const env = envWithAgentHeap(launch.env);
|
|
8070
8347
|
delete env.ELECTRON_RUN_AS_NODE;
|
|
8071
8348
|
return { file: wrapped.file, args: wrapped.args, env };
|
|
8072
8349
|
}
|
|
@@ -8087,16 +8364,18 @@ async function resolveNodeLaunch(scriptPath) {
|
|
|
8087
8364
|
env: { ELECTRON_RUN_AS_NODE: "1" }
|
|
8088
8365
|
};
|
|
8089
8366
|
}
|
|
8090
|
-
var
|
|
8367
|
+
var import_node_fs23, import_node_os7, import_node_path24, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
|
|
8091
8368
|
var init_node_launch = __esm({
|
|
8092
8369
|
"src/agents/node-launch.ts"() {
|
|
8093
8370
|
"use strict";
|
|
8094
|
-
|
|
8371
|
+
import_node_fs23 = require("fs");
|
|
8095
8372
|
import_node_os7 = require("os");
|
|
8096
|
-
|
|
8373
|
+
import_node_path24 = require("path");
|
|
8097
8374
|
init_nested_electron_env();
|
|
8098
8375
|
init_run();
|
|
8099
8376
|
init_packaged_runtime();
|
|
8377
|
+
AGENT_RUNNER_MAX_OLD_SPACE_MB = 8192;
|
|
8378
|
+
MAX_OLD_SPACE_FLAG = /(?:^|\s)(--max[-_]old[-_]space[-_]size)(?:[= ](\d+))?(?=\s|$)/;
|
|
8100
8379
|
PREFERRED_LTS_MAJORS = [24, 22, 20];
|
|
8101
8380
|
}
|
|
8102
8381
|
});
|
|
@@ -8184,37 +8463,37 @@ function corePackageDir() {
|
|
|
8184
8463
|
try {
|
|
8185
8464
|
const url = import_meta.url;
|
|
8186
8465
|
if (typeof url === "string" && url.length > 0) {
|
|
8187
|
-
return (0,
|
|
8466
|
+
return (0, import_node_path25.dirname)((0, import_node_url.fileURLToPath)(url));
|
|
8188
8467
|
}
|
|
8189
8468
|
} catch {
|
|
8190
8469
|
}
|
|
8191
8470
|
try {
|
|
8192
|
-
const req = (0, import_node_module.createRequire)((0,
|
|
8193
|
-
return (0,
|
|
8471
|
+
const req = (0, import_node_module.createRequire)((0, import_node_path25.join)(process.cwd(), "package.json"));
|
|
8472
|
+
return (0, import_node_path25.dirname)(req.resolve("@sideboard-ai/core"));
|
|
8194
8473
|
} catch {
|
|
8195
8474
|
return process.cwd();
|
|
8196
8475
|
}
|
|
8197
8476
|
}
|
|
8198
8477
|
function findSideboardMcpJsEntry() {
|
|
8199
8478
|
const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
|
|
8200
|
-
if (override && (0,
|
|
8479
|
+
if (override && (0, import_node_fs24.existsSync)(override)) return override;
|
|
8201
8480
|
const packaged = packagedMcpStdioPath();
|
|
8202
8481
|
if (packaged) return packaged;
|
|
8203
8482
|
let dir = corePackageDir();
|
|
8204
8483
|
for (let i = 0; i < 10; i++) {
|
|
8205
8484
|
const candidates = [
|
|
8206
|
-
(0,
|
|
8207
|
-
(0,
|
|
8208
|
-
(0,
|
|
8209
|
-
(0,
|
|
8210
|
-
(0,
|
|
8211
|
-
(0,
|
|
8212
|
-
(0,
|
|
8485
|
+
(0, import_node_path25.join)(dir, "mcp/run-stdio.js"),
|
|
8486
|
+
(0, import_node_path25.join)(dir, "mcp/run-stdio.cjs"),
|
|
8487
|
+
(0, import_node_path25.join)(dir, "dist/mcp/run-stdio.js"),
|
|
8488
|
+
(0, import_node_path25.join)(dir, "dist/mcp/run-stdio.cjs"),
|
|
8489
|
+
(0, import_node_path25.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
8490
|
+
(0, import_node_path25.join)(dir, "packages/cli/dist/index.js"),
|
|
8491
|
+
(0, import_node_path25.join)(dir, "cli/dist/index.js")
|
|
8213
8492
|
];
|
|
8214
8493
|
for (const p of candidates) {
|
|
8215
|
-
if ((0,
|
|
8494
|
+
if ((0, import_node_fs24.existsSync)(p) && !isAsarPath(p)) return p;
|
|
8216
8495
|
}
|
|
8217
|
-
const parent = (0,
|
|
8496
|
+
const parent = (0, import_node_path25.dirname)(dir);
|
|
8218
8497
|
if (parent === dir) break;
|
|
8219
8498
|
dir = parent;
|
|
8220
8499
|
}
|
|
@@ -8262,6 +8541,7 @@ async function buildInjectedMcpServers(opts) {
|
|
|
8262
8541
|
);
|
|
8263
8542
|
} catch {
|
|
8264
8543
|
}
|
|
8544
|
+
applyAgentRunnerHeapEnv(sideboard.env);
|
|
8265
8545
|
servers.push(sideboard);
|
|
8266
8546
|
}
|
|
8267
8547
|
if (opts.includeBrightsy && isBrightsyConnected()) {
|
|
@@ -8355,22 +8635,22 @@ function writeMcpServersConfig(servers) {
|
|
|
8355
8635
|
...env ? { env } : {}
|
|
8356
8636
|
};
|
|
8357
8637
|
}
|
|
8358
|
-
const dir = (0,
|
|
8359
|
-
const cfgPath = (0,
|
|
8360
|
-
(0,
|
|
8638
|
+
const dir = (0, import_node_fs24.mkdtempSync)((0, import_node_path25.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
|
|
8639
|
+
const cfgPath = (0, import_node_path25.join)(dir, "mcp.json");
|
|
8640
|
+
(0, import_node_fs24.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
|
|
8361
8641
|
return cfgPath;
|
|
8362
8642
|
}
|
|
8363
8643
|
async function writeInjectedMcpConfig(opts) {
|
|
8364
8644
|
return writeMcpServersConfig(await buildInjectedMcpServers(opts));
|
|
8365
8645
|
}
|
|
8366
|
-
var
|
|
8646
|
+
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
8647
|
var init_injected_mcp = __esm({
|
|
8368
8648
|
"src/agents/injected-mcp.ts"() {
|
|
8369
8649
|
"use strict";
|
|
8370
|
-
|
|
8650
|
+
import_node_fs24 = require("fs");
|
|
8371
8651
|
import_node_module = require("module");
|
|
8372
8652
|
import_node_os8 = require("os");
|
|
8373
|
-
|
|
8653
|
+
import_node_path25 = require("path");
|
|
8374
8654
|
import_node_url = require("url");
|
|
8375
8655
|
init_run();
|
|
8376
8656
|
init_config();
|
|
@@ -8548,6 +8828,80 @@ function claudeParentToolUseId(obj) {
|
|
|
8548
8828
|
}
|
|
8549
8829
|
return void 0;
|
|
8550
8830
|
}
|
|
8831
|
+
function claudeString(obj, key) {
|
|
8832
|
+
const v = obj[key];
|
|
8833
|
+
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
8834
|
+
}
|
|
8835
|
+
function eventsFromClaudeSystem(obj) {
|
|
8836
|
+
const subtype = claudeString(obj, "subtype") ?? "";
|
|
8837
|
+
const parentId = claudeParentToolUseId(obj);
|
|
8838
|
+
if (subtype === "init") {
|
|
8839
|
+
if (parentId) return null;
|
|
8840
|
+
const sid = claudeString(obj, "session_id");
|
|
8841
|
+
return sid ? { type: "session_id", data: sid } : null;
|
|
8842
|
+
}
|
|
8843
|
+
if (subtype === "task_started") {
|
|
8844
|
+
const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id");
|
|
8845
|
+
if (!id) return null;
|
|
8846
|
+
const description = claudeString(obj, "description");
|
|
8847
|
+
const taskType = claudeString(obj, "task_type");
|
|
8848
|
+
const prompt = claudeString(obj, "prompt");
|
|
8849
|
+
return withEventParentId(
|
|
8850
|
+
{
|
|
8851
|
+
type: "tool_use",
|
|
8852
|
+
id,
|
|
8853
|
+
name: taskType || "Agent",
|
|
8854
|
+
input: {
|
|
8855
|
+
...description ? { description } : {},
|
|
8856
|
+
...prompt ? { prompt } : {},
|
|
8857
|
+
...claudeString(obj, "task_id") ? { task_id: claudeString(obj, "task_id") } : {}
|
|
8858
|
+
}
|
|
8859
|
+
},
|
|
8860
|
+
parentId
|
|
8861
|
+
);
|
|
8862
|
+
}
|
|
8863
|
+
if (subtype === "task_notification") {
|
|
8864
|
+
const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id") ?? parentId;
|
|
8865
|
+
if (!id) return null;
|
|
8866
|
+
const status = claudeString(obj, "status") ?? "working";
|
|
8867
|
+
const tools = typeof obj.tool_uses === "number" ? obj.tool_uses : void 0;
|
|
8868
|
+
const durationMs = typeof obj.duration_ms === "number" ? obj.duration_ms : void 0;
|
|
8869
|
+
const lastTool = claudeString(obj, "last_tool") ?? claudeString(obj, "current_tool") ?? claudeString(obj, "tool");
|
|
8870
|
+
const snapshot = [
|
|
8871
|
+
status,
|
|
8872
|
+
tools != null ? `${tools} tools` : null,
|
|
8873
|
+
durationMs != null ? `${Math.round(durationMs / 1e3)}s` : null,
|
|
8874
|
+
lastTool
|
|
8875
|
+
].filter((bit) => Boolean(bit)).join(" \xB7 ");
|
|
8876
|
+
return [
|
|
8877
|
+
{
|
|
8878
|
+
type: "tool_use",
|
|
8879
|
+
id,
|
|
8880
|
+
name: claudeString(obj, "task_type") || "Agent",
|
|
8881
|
+
input: {
|
|
8882
|
+
live_status: status,
|
|
8883
|
+
...tools != null ? { live_tool_uses: tools } : {},
|
|
8884
|
+
...durationMs != null ? { live_duration_ms: durationMs } : {},
|
|
8885
|
+
...lastTool ? { live_last_tool: lastTool } : {}
|
|
8886
|
+
}
|
|
8887
|
+
},
|
|
8888
|
+
withEventParentId(
|
|
8889
|
+
{ type: "thinking", data: snapshot, replace: true },
|
|
8890
|
+
id
|
|
8891
|
+
)
|
|
8892
|
+
];
|
|
8893
|
+
}
|
|
8894
|
+
if (subtype === "api_retry") {
|
|
8895
|
+
const attempt = obj.attempt;
|
|
8896
|
+
const max = obj.max_retries;
|
|
8897
|
+
const delay = obj.retry_delay_ms;
|
|
8898
|
+
return {
|
|
8899
|
+
type: "thinking",
|
|
8900
|
+
data: `API retry ${attempt ?? "?"}/${max ?? "?"}${typeof delay === "number" ? ` (wait ${delay}ms)` : ""}`
|
|
8901
|
+
};
|
|
8902
|
+
}
|
|
8903
|
+
return null;
|
|
8904
|
+
}
|
|
8551
8905
|
function parseIssuesJson(raw) {
|
|
8552
8906
|
const text4 = raw.trim();
|
|
8553
8907
|
const candidates = [text4];
|
|
@@ -8573,11 +8927,11 @@ function parseIssuesJson(raw) {
|
|
|
8573
8927
|
}
|
|
8574
8928
|
return [];
|
|
8575
8929
|
}
|
|
8576
|
-
var
|
|
8930
|
+
var import_node_fs25, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
|
|
8577
8931
|
var init_claude = __esm({
|
|
8578
8932
|
"src/agents/claude.ts"() {
|
|
8579
8933
|
"use strict";
|
|
8580
|
-
|
|
8934
|
+
import_node_fs25 = require("fs");
|
|
8581
8935
|
init_run();
|
|
8582
8936
|
init_app_settings();
|
|
8583
8937
|
init_claude_mcp();
|
|
@@ -8597,8 +8951,14 @@ var init_claude = __esm({
|
|
|
8597
8951
|
"WebSearch",
|
|
8598
8952
|
// Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
|
|
8599
8953
|
"Task",
|
|
8600
|
-
"Agent"
|
|
8954
|
+
"Agent",
|
|
8955
|
+
"TaskOutput",
|
|
8956
|
+
"TaskStop",
|
|
8957
|
+
"EnterWorktree",
|
|
8958
|
+
"ExitWorktree",
|
|
8959
|
+
"Skill"
|
|
8601
8960
|
];
|
|
8961
|
+
CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
|
|
8602
8962
|
CLAUDE_CHROME_ALLOWED_TOOLS = [
|
|
8603
8963
|
"mcp__claude-in-chrome",
|
|
8604
8964
|
"mcp__claude-in-chrome__*",
|
|
@@ -8610,7 +8970,7 @@ var init_claude = __esm({
|
|
|
8610
8970
|
async detect() {
|
|
8611
8971
|
const claude = resolveClaudeExecutable();
|
|
8612
8972
|
if (claude !== "claude") {
|
|
8613
|
-
if (!(0,
|
|
8973
|
+
if (!(0, import_node_fs25.existsSync)(claude)) {
|
|
8614
8974
|
return {
|
|
8615
8975
|
agent: "claude",
|
|
8616
8976
|
installed: false,
|
|
@@ -8727,7 +9087,12 @@ var init_claude = __esm({
|
|
|
8727
9087
|
stdin: useStdin ? `${promptText}
|
|
8728
9088
|
` : void 0,
|
|
8729
9089
|
// Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
|
|
8730
|
-
|
|
9090
|
+
// Raise the -p background-agent wait so long TaskOutput polls are not
|
|
9091
|
+
// abandoned at Claude Code’s 10-minute default.
|
|
9092
|
+
env: {
|
|
9093
|
+
CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
|
|
9094
|
+
CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS)
|
|
9095
|
+
}
|
|
8731
9096
|
};
|
|
8732
9097
|
},
|
|
8733
9098
|
parseEvent(line) {
|
|
@@ -8735,13 +9100,8 @@ var init_claude = __esm({
|
|
|
8735
9100
|
if (!trimmed) return null;
|
|
8736
9101
|
try {
|
|
8737
9102
|
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 };
|
|
9103
|
+
if (obj.type === "system") {
|
|
9104
|
+
return eventsFromClaudeSystem(obj);
|
|
8745
9105
|
}
|
|
8746
9106
|
if (obj.type === "assistant" || obj.type === "user") {
|
|
8747
9107
|
const parentId = claudeParentToolUseId(obj);
|
|
@@ -8861,7 +9221,7 @@ async function listCodexModels() {
|
|
|
8861
9221
|
if (codex === "codex") {
|
|
8862
9222
|
const which = await run("which", ["codex"], { reject: false });
|
|
8863
9223
|
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
8864
|
-
} else if (!(0,
|
|
9224
|
+
} else if (!(0, import_node_fs26.existsSync)(codex)) {
|
|
8865
9225
|
return FALLBACK_CODEX_MODELS;
|
|
8866
9226
|
}
|
|
8867
9227
|
const listed = await run(codex, ["debug", "models"], { reject: false });
|
|
@@ -8896,12 +9256,12 @@ function usageFromCodex(usage) {
|
|
|
8896
9256
|
}
|
|
8897
9257
|
function codexConfigHasNetworkAccess() {
|
|
8898
9258
|
const candidates = [
|
|
8899
|
-
(0,
|
|
8900
|
-
(0,
|
|
9259
|
+
(0, import_node_path26.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
|
|
9260
|
+
(0, import_node_path26.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
|
|
8901
9261
|
];
|
|
8902
9262
|
for (const path2 of candidates) {
|
|
8903
|
-
if (!(0,
|
|
8904
|
-
const text4 = (0,
|
|
9263
|
+
if (!(0, import_node_fs26.existsSync)(path2)) continue;
|
|
9264
|
+
const text4 = (0, import_node_fs26.readFileSync)(path2, "utf8");
|
|
8905
9265
|
if (/network_access\s*=\s*true/.test(text4)) return true;
|
|
8906
9266
|
}
|
|
8907
9267
|
return false;
|
|
@@ -8933,21 +9293,21 @@ function asRecord2(value) {
|
|
|
8933
9293
|
return void 0;
|
|
8934
9294
|
}
|
|
8935
9295
|
function codexLooksAuthenticated() {
|
|
8936
|
-
const authPath = (0,
|
|
8937
|
-
if (!(0,
|
|
9296
|
+
const authPath = (0, import_node_path26.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
|
|
9297
|
+
if (!(0, import_node_fs26.existsSync)(authPath)) return false;
|
|
8938
9298
|
try {
|
|
8939
|
-
return (0,
|
|
9299
|
+
return (0, import_node_fs26.statSync)(authPath).size > 2;
|
|
8940
9300
|
} catch {
|
|
8941
9301
|
return false;
|
|
8942
9302
|
}
|
|
8943
9303
|
}
|
|
8944
|
-
var
|
|
9304
|
+
var import_node_fs26, import_node_os9, import_node_path26, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
8945
9305
|
var init_codex = __esm({
|
|
8946
9306
|
"src/agents/codex.ts"() {
|
|
8947
9307
|
"use strict";
|
|
8948
|
-
|
|
9308
|
+
import_node_fs26 = require("fs");
|
|
8949
9309
|
import_node_os9 = require("os");
|
|
8950
|
-
|
|
9310
|
+
import_node_path26 = require("path");
|
|
8951
9311
|
init_run();
|
|
8952
9312
|
init_app_settings();
|
|
8953
9313
|
init_global_workspace();
|
|
@@ -8972,7 +9332,7 @@ var init_codex = __esm({
|
|
|
8972
9332
|
async detect() {
|
|
8973
9333
|
const codex = resolveAgentExecutable("codex");
|
|
8974
9334
|
if (codex !== "codex") {
|
|
8975
|
-
if (!(0,
|
|
9335
|
+
if (!(0, import_node_fs26.existsSync)(codex)) {
|
|
8976
9336
|
return {
|
|
8977
9337
|
agent: "codex",
|
|
8978
9338
|
installed: false,
|
|
@@ -9112,13 +9472,22 @@ var init_codex = __esm({
|
|
|
9112
9472
|
const events = [
|
|
9113
9473
|
{ type: "tool_use", id: item.id, name: "Bash", input }
|
|
9114
9474
|
];
|
|
9115
|
-
|
|
9475
|
+
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
9476
|
+
const output = typeof item.aggregated_output === "string" && item.aggregated_output ? item.aggregated_output : void 0;
|
|
9477
|
+
if (finished) {
|
|
9116
9478
|
events.push({
|
|
9117
9479
|
type: "tool_result",
|
|
9118
9480
|
id: item.id,
|
|
9119
|
-
content:
|
|
9481
|
+
content: output,
|
|
9120
9482
|
isError: item.status === "failed"
|
|
9121
9483
|
});
|
|
9484
|
+
} else if (output) {
|
|
9485
|
+
events.push({
|
|
9486
|
+
type: "tool_result",
|
|
9487
|
+
id: item.id,
|
|
9488
|
+
content: output,
|
|
9489
|
+
partial: true
|
|
9490
|
+
});
|
|
9122
9491
|
}
|
|
9123
9492
|
return events.length === 1 ? events[0] : events;
|
|
9124
9493
|
}
|
|
@@ -9161,9 +9530,6 @@ var init_codex = __esm({
|
|
|
9161
9530
|
if (sid && (type === "thread.started" || type === "session" || !type)) {
|
|
9162
9531
|
return { type: "session_id", data: sid };
|
|
9163
9532
|
}
|
|
9164
|
-
if (sid && type.endsWith(".started")) {
|
|
9165
|
-
return { type: "session_id", data: sid };
|
|
9166
|
-
}
|
|
9167
9533
|
if (type === "turn.completed" || type === "turn_completed") {
|
|
9168
9534
|
const usage = usageFromCodex(obj.usage);
|
|
9169
9535
|
return usage ? { type: "usage", data: usage, scope: "turn" } : null;
|
|
@@ -9337,7 +9703,7 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
9337
9703
|
if (msg.type === "tool_call" && msg.call_id && msg.name) {
|
|
9338
9704
|
const normalized = normalizeCursorToolCall(msg.name, msg.args);
|
|
9339
9705
|
if (msg.status === "running") {
|
|
9340
|
-
|
|
9706
|
+
const events = [
|
|
9341
9707
|
{
|
|
9342
9708
|
type: "tool_use",
|
|
9343
9709
|
id: msg.call_id,
|
|
@@ -9345,6 +9711,16 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
9345
9711
|
input: normalized.input
|
|
9346
9712
|
}
|
|
9347
9713
|
];
|
|
9714
|
+
const live = unwrapCursorToolResult(msg.result);
|
|
9715
|
+
if (live) {
|
|
9716
|
+
events.push({
|
|
9717
|
+
type: "tool_result",
|
|
9718
|
+
id: msg.call_id,
|
|
9719
|
+
content: live,
|
|
9720
|
+
partial: true
|
|
9721
|
+
});
|
|
9722
|
+
}
|
|
9723
|
+
return events;
|
|
9348
9724
|
}
|
|
9349
9725
|
if (msg.status === "completed" || msg.status === "error") {
|
|
9350
9726
|
return [
|
|
@@ -9411,21 +9787,21 @@ function platformRipgrepPackage() {
|
|
|
9411
9787
|
}
|
|
9412
9788
|
function usableRipgrepPath(candidate) {
|
|
9413
9789
|
const raw = candidate?.trim();
|
|
9414
|
-
if (!raw || !(0,
|
|
9790
|
+
if (!raw || !(0, import_node_path27.isAbsolute)(raw)) return null;
|
|
9415
9791
|
const readable = nodeReadableScriptPath(raw);
|
|
9416
|
-
if (!(0,
|
|
9792
|
+
if (!(0, import_node_fs27.existsSync)(readable) || isAsarPath(readable)) return null;
|
|
9417
9793
|
return readable;
|
|
9418
9794
|
}
|
|
9419
9795
|
function walkForBundledRipgrep(startFile) {
|
|
9420
9796
|
if (!startFile) return null;
|
|
9421
9797
|
const pkg = platformRipgrepPackage();
|
|
9422
9798
|
const name = rgBinaryName();
|
|
9423
|
-
let dir = (0,
|
|
9424
|
-
const root = (0,
|
|
9799
|
+
let dir = (0, import_node_path27.dirname)((0, import_node_path27.resolve)(startFile));
|
|
9800
|
+
const root = (0, import_node_path27.parse)(dir).root;
|
|
9425
9801
|
while (dir !== root) {
|
|
9426
|
-
const hit = usableRipgrepPath((0,
|
|
9802
|
+
const hit = usableRipgrepPath((0, import_node_path27.join)(dir, "node_modules", pkg, "bin", name));
|
|
9427
9803
|
if (hit) return hit;
|
|
9428
|
-
const next = (0,
|
|
9804
|
+
const next = (0, import_node_path27.dirname)(dir);
|
|
9429
9805
|
if (next === dir) break;
|
|
9430
9806
|
dir = next;
|
|
9431
9807
|
}
|
|
@@ -9435,7 +9811,7 @@ function requireResolveBundledRipgrep(fromFile) {
|
|
|
9435
9811
|
try {
|
|
9436
9812
|
const req = (0, import_node_module2.createRequire)(fromFile);
|
|
9437
9813
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
9438
|
-
return usableRipgrepPath((0,
|
|
9814
|
+
return usableRipgrepPath((0, import_node_path27.join)((0, import_node_path27.dirname)(pkgJson), "bin", rgBinaryName()));
|
|
9439
9815
|
} catch {
|
|
9440
9816
|
return null;
|
|
9441
9817
|
}
|
|
@@ -9457,13 +9833,13 @@ function cursorRipgrepEnv(opts) {
|
|
|
9457
9833
|
const path2 = resolveCursorRipgrepPath(opts);
|
|
9458
9834
|
return path2 ? { [RIPGREP_ENV]: path2 } : {};
|
|
9459
9835
|
}
|
|
9460
|
-
var
|
|
9836
|
+
var import_node_fs27, import_node_module2, import_node_path27, RIPGREP_ENV;
|
|
9461
9837
|
var init_cursor_ripgrep = __esm({
|
|
9462
9838
|
"src/agents/cursor-ripgrep.ts"() {
|
|
9463
9839
|
"use strict";
|
|
9464
|
-
|
|
9840
|
+
import_node_fs27 = require("fs");
|
|
9465
9841
|
import_node_module2 = require("module");
|
|
9466
|
-
|
|
9842
|
+
import_node_path27 = require("path");
|
|
9467
9843
|
init_node_launch();
|
|
9468
9844
|
init_packaged_runtime();
|
|
9469
9845
|
RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
@@ -9509,11 +9885,11 @@ function entryDir() {
|
|
|
9509
9885
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
9510
9886
|
if (cjsDir) return cjsDir;
|
|
9511
9887
|
try {
|
|
9512
|
-
return (0,
|
|
9888
|
+
return (0, import_node_path28.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
9513
9889
|
} catch {
|
|
9514
9890
|
try {
|
|
9515
9891
|
const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
|
|
9516
|
-
return (0,
|
|
9892
|
+
return (0, import_node_path28.dirname)(req.resolve("@sideboard-ai/core"));
|
|
9517
9893
|
} catch {
|
|
9518
9894
|
return process.cwd();
|
|
9519
9895
|
}
|
|
@@ -9524,27 +9900,27 @@ function cursorRunnerPath() {
|
|
|
9524
9900
|
if (packaged) return packaged;
|
|
9525
9901
|
const root = entryDir();
|
|
9526
9902
|
const candidates = [
|
|
9527
|
-
(0,
|
|
9528
|
-
(0,
|
|
9903
|
+
(0, import_node_path28.join)(root, "agents", "cursor-runner.js"),
|
|
9904
|
+
(0, import_node_path28.join)(root, "agents", "cursor-runner.cjs"),
|
|
9529
9905
|
// If somehow resolved from package root instead of dist/
|
|
9530
|
-
(0,
|
|
9531
|
-
(0,
|
|
9906
|
+
(0, import_node_path28.join)(root, "dist", "agents", "cursor-runner.js"),
|
|
9907
|
+
(0, import_node_path28.join)(root, "dist", "agents", "cursor-runner.cjs"),
|
|
9532
9908
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
9533
|
-
(0,
|
|
9534
|
-
(0,
|
|
9909
|
+
(0, import_node_path28.join)(root, "cursor-runner.ts"),
|
|
9910
|
+
(0, import_node_path28.join)(root, "src", "agents", "cursor-runner.ts")
|
|
9535
9911
|
];
|
|
9536
9912
|
for (const candidate of candidates) {
|
|
9537
|
-
if ((0,
|
|
9913
|
+
if ((0, import_node_fs28.existsSync)(candidate)) return candidate;
|
|
9538
9914
|
}
|
|
9539
9915
|
return candidates[0];
|
|
9540
9916
|
}
|
|
9541
|
-
var
|
|
9917
|
+
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
9918
|
var init_cursor = __esm({
|
|
9543
9919
|
"src/agents/cursor.ts"() {
|
|
9544
9920
|
"use strict";
|
|
9545
|
-
|
|
9921
|
+
import_node_fs28 = require("fs");
|
|
9546
9922
|
import_node_module3 = require("module");
|
|
9547
|
-
|
|
9923
|
+
import_node_path28 = require("path");
|
|
9548
9924
|
import_node_url2 = require("url");
|
|
9549
9925
|
import_sdk = require("@cursor/sdk");
|
|
9550
9926
|
init_run();
|
|
@@ -9694,7 +10070,7 @@ async function listOpencodeModels() {
|
|
|
9694
10070
|
if (opencode === "opencode") {
|
|
9695
10071
|
const which = await run("which", ["opencode"], { reject: false });
|
|
9696
10072
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
9697
|
-
} else if (!(0,
|
|
10073
|
+
} else if (!(0, import_node_fs29.existsSync)(opencode)) {
|
|
9698
10074
|
return FALLBACK_OPENCODE_MODELS;
|
|
9699
10075
|
}
|
|
9700
10076
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -9724,11 +10100,11 @@ function usageFromOpencode(tokens) {
|
|
|
9724
10100
|
cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
|
|
9725
10101
|
};
|
|
9726
10102
|
}
|
|
9727
|
-
var
|
|
10103
|
+
var import_node_fs29, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
|
|
9728
10104
|
var init_opencode = __esm({
|
|
9729
10105
|
"src/agents/opencode.ts"() {
|
|
9730
10106
|
"use strict";
|
|
9731
|
-
|
|
10107
|
+
import_node_fs29 = require("fs");
|
|
9732
10108
|
init_run();
|
|
9733
10109
|
init_app_settings();
|
|
9734
10110
|
init_global_workspace();
|
|
@@ -9755,7 +10131,7 @@ var init_opencode = __esm({
|
|
|
9755
10131
|
async detect() {
|
|
9756
10132
|
const opencode = resolveAgentExecutable("opencode");
|
|
9757
10133
|
if (opencode !== "opencode") {
|
|
9758
|
-
if (!(0,
|
|
10134
|
+
if (!(0, import_node_fs29.existsSync)(opencode)) {
|
|
9759
10135
|
return {
|
|
9760
10136
|
agent: "opencode",
|
|
9761
10137
|
installed: false,
|
|
@@ -9841,7 +10217,8 @@ var init_opencode = __esm({
|
|
|
9841
10217
|
return { type: "stderr", data: detail };
|
|
9842
10218
|
}
|
|
9843
10219
|
const sid = typeof obj.sessionID === "string" && obj.sessionID || typeof obj.sessionId === "string" && obj.sessionId || typeof obj.session_id === "string" && obj.session_id;
|
|
9844
|
-
|
|
10220
|
+
const childSid = str3(obj.childSessionID) ?? str3(obj.childSessionId) ?? str3(obj.parentID) ?? str3(obj.parentId);
|
|
10221
|
+
if (sid && !childSid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
|
|
9845
10222
|
return { type: "session_id", data: sid };
|
|
9846
10223
|
}
|
|
9847
10224
|
if (obj.type === "text") {
|
|
@@ -9861,13 +10238,16 @@ var init_opencode = __esm({
|
|
|
9861
10238
|
);
|
|
9862
10239
|
const events = [{ type: "tool_use", id, name, input }];
|
|
9863
10240
|
const output = state?.output;
|
|
9864
|
-
|
|
10241
|
+
const finished = state?.status === "completed" || state?.status === "error" || state?.status === "failed";
|
|
10242
|
+
const running = state?.status === "running" || state?.status === "in_progress" || state?.status === "pending";
|
|
10243
|
+
if (output != null || finished) {
|
|
9865
10244
|
const content = typeof output === "string" ? output : output != null ? JSON.stringify(output) : formatUnknownDetail(state?.error) || void 0;
|
|
9866
10245
|
events.push({
|
|
9867
10246
|
type: "tool_result",
|
|
9868
10247
|
id,
|
|
9869
10248
|
content,
|
|
9870
|
-
isError: state?.status === "error" || state?.status === "failed"
|
|
10249
|
+
isError: state?.status === "error" || state?.status === "failed",
|
|
10250
|
+
...running && !finished ? { partial: true } : {}
|
|
9871
10251
|
});
|
|
9872
10252
|
}
|
|
9873
10253
|
return events.length === 1 ? events[0] : events;
|
|
@@ -9902,14 +10282,17 @@ var init_opencode = __esm({
|
|
|
9902
10282
|
withEventParentId({ type: "tool_use", id, name, input }, parentId)
|
|
9903
10283
|
];
|
|
9904
10284
|
const output = state?.output ?? part.output;
|
|
9905
|
-
|
|
10285
|
+
const finished = state?.status === "completed" || state?.status === "error" || state?.status === "failed";
|
|
10286
|
+
const running = state?.status === "running" || state?.status === "in_progress" || state?.status === "pending";
|
|
10287
|
+
if (output != null || finished) {
|
|
9906
10288
|
nested.push(
|
|
9907
10289
|
withEventParentId(
|
|
9908
10290
|
{
|
|
9909
10291
|
type: "tool_result",
|
|
9910
10292
|
id,
|
|
9911
10293
|
content: typeof output === "string" ? output : output != null ? JSON.stringify(output) : void 0,
|
|
9912
|
-
isError: state?.status === "error" || state?.status === "failed"
|
|
10294
|
+
isError: state?.status === "error" || state?.status === "failed",
|
|
10295
|
+
...running && !finished ? { partial: true } : {}
|
|
9913
10296
|
},
|
|
9914
10297
|
parentId
|
|
9915
10298
|
)
|
|
@@ -10572,6 +10955,11 @@ function createAgentStreamCoalescer(emit, opts) {
|
|
|
10572
10955
|
return;
|
|
10573
10956
|
}
|
|
10574
10957
|
if (!event.data) return;
|
|
10958
|
+
if (event.type === "thinking" && event.replace) {
|
|
10959
|
+
flush2();
|
|
10960
|
+
emit(event);
|
|
10961
|
+
return;
|
|
10962
|
+
}
|
|
10575
10963
|
if (pending && pending.type === event.type && parentKey(pending) === parentKey(event)) {
|
|
10576
10964
|
pending.data += event.data;
|
|
10577
10965
|
} else {
|
|
@@ -10628,6 +11016,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
10628
11016
|
}
|
|
10629
11017
|
const env = childEnvWithAppSettings(cmd.env);
|
|
10630
11018
|
applyPromptCacheTtlEnv(thread.agent, env);
|
|
11019
|
+
applyAgentRunnerHeapEnv(env);
|
|
10631
11020
|
try {
|
|
10632
11021
|
if (isOrchestratorThread(thread)) {
|
|
10633
11022
|
mergeAgentGitAuthEnv(env, await resolveAgentGitAuthEnv(env));
|
|
@@ -10735,9 +11124,11 @@ var init_spawn = __esm({
|
|
|
10735
11124
|
init_agents();
|
|
10736
11125
|
init_orchestrator_capable();
|
|
10737
11126
|
init_message_parts();
|
|
11127
|
+
init_node_launch();
|
|
10738
11128
|
init_path();
|
|
10739
11129
|
init_usage();
|
|
10740
11130
|
init_cursor_stream_coalesce();
|
|
11131
|
+
init_node_launch();
|
|
10741
11132
|
}
|
|
10742
11133
|
});
|
|
10743
11134
|
|
|
@@ -11463,21 +11854,21 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
11463
11854
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
11464
11855
|
}
|
|
11465
11856
|
function readTextIfPresent(abs) {
|
|
11466
|
-
if (!(0,
|
|
11857
|
+
if (!(0, import_node_fs30.existsSync)(abs)) return null;
|
|
11467
11858
|
try {
|
|
11468
|
-
const content = (0,
|
|
11859
|
+
const content = (0, import_node_fs30.readFileSync)(abs, "utf8");
|
|
11469
11860
|
return content.trim() ? content : null;
|
|
11470
11861
|
} catch {
|
|
11471
11862
|
return null;
|
|
11472
11863
|
}
|
|
11473
11864
|
}
|
|
11474
11865
|
function readLocalGuidelines(worktreePath) {
|
|
11475
|
-
const localAbs = (0,
|
|
11866
|
+
const localAbs = (0, import_node_path29.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
11476
11867
|
const localContent = readTextIfPresent(localAbs);
|
|
11477
11868
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
11478
11869
|
return { path: REVIEW_REQUEST_PATH, content: localContent };
|
|
11479
11870
|
}
|
|
11480
|
-
const legacyAbs = (0,
|
|
11871
|
+
const legacyAbs = (0, import_node_path29.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
11481
11872
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
11482
11873
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
11483
11874
|
return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
|
|
@@ -11493,20 +11884,20 @@ function skillGuidelines(content, source) {
|
|
|
11493
11884
|
};
|
|
11494
11885
|
}
|
|
11495
11886
|
function ensureReviewSkillFile(worktreePath) {
|
|
11496
|
-
const abs = (0,
|
|
11887
|
+
const abs = (0, import_node_path29.join)(worktreePath, REVIEW_SKILL_PATH);
|
|
11497
11888
|
const existing = readTextIfPresent(abs);
|
|
11498
11889
|
if (existing) {
|
|
11499
11890
|
return { path: REVIEW_SKILL_PATH, content: existing, wrote: false };
|
|
11500
11891
|
}
|
|
11501
|
-
const fromRepo = readTextIfPresent((0,
|
|
11892
|
+
const fromRepo = readTextIfPresent((0, import_node_path29.join)(worktreePath, REPO_REVIEW_PATH));
|
|
11502
11893
|
const fromLocal = readLocalGuidelines(worktreePath)?.content ?? null;
|
|
11503
11894
|
const content = wrapReviewSkillMarkdown(fromRepo ?? fromLocal ?? REVIEW_REQUEST_TEMPLATE);
|
|
11504
|
-
(0,
|
|
11505
|
-
(0,
|
|
11895
|
+
(0, import_node_fs30.mkdirSync)((0, import_node_path29.dirname)(abs), { recursive: true });
|
|
11896
|
+
(0, import_node_fs30.writeFileSync)(abs, content, "utf8");
|
|
11506
11897
|
return { path: REVIEW_SKILL_PATH, content, wrote: true };
|
|
11507
11898
|
}
|
|
11508
11899
|
function resolveReviewGuidelines(worktreePath) {
|
|
11509
|
-
const skillContent = readTextIfPresent((0,
|
|
11900
|
+
const skillContent = readTextIfPresent((0, import_node_path29.join)(worktreePath, REVIEW_SKILL_PATH));
|
|
11510
11901
|
if (skillContent) return skillGuidelines(skillContent, "skill");
|
|
11511
11902
|
const local = readLocalGuidelines(worktreePath);
|
|
11512
11903
|
if (local) {
|
|
@@ -11536,7 +11927,7 @@ function buildReviewRequestAttachment(content, opts) {
|
|
|
11536
11927
|
};
|
|
11537
11928
|
}
|
|
11538
11929
|
function readExistingReviewRequestFile(worktreePath) {
|
|
11539
|
-
return readTextIfPresent((0,
|
|
11930
|
+
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
11931
|
}
|
|
11541
11932
|
async function requestReview(threadRef, send2) {
|
|
11542
11933
|
const from = findThreadByRef(threadRef);
|
|
@@ -11563,13 +11954,13 @@ async function requestReview(threadRef, send2) {
|
|
|
11563
11954
|
const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
|
|
11564
11955
|
return { tab: started, from };
|
|
11565
11956
|
}
|
|
11566
|
-
var import_node_crypto6,
|
|
11957
|
+
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
11958
|
var init_request_review = __esm({
|
|
11568
11959
|
"src/review/request-review.ts"() {
|
|
11569
11960
|
"use strict";
|
|
11570
11961
|
import_node_crypto6 = require("crypto");
|
|
11571
|
-
|
|
11572
|
-
|
|
11962
|
+
import_node_fs30 = require("fs");
|
|
11963
|
+
import_node_path29 = require("path");
|
|
11573
11964
|
init_global_workspace();
|
|
11574
11965
|
init_chat_tabs();
|
|
11575
11966
|
init_thread_store();
|
|
@@ -11594,9 +11985,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
11594
11985
|
return new RegExp(`^${escaped}$`).test(name);
|
|
11595
11986
|
}
|
|
11596
11987
|
function readWorktreeInclude(repoPath) {
|
|
11597
|
-
const path2 = (0,
|
|
11598
|
-
if (!(0,
|
|
11599
|
-
return (0,
|
|
11988
|
+
const path2 = (0, import_node_path30.join)(repoPath, ".worktreeinclude");
|
|
11989
|
+
if (!(0, import_node_fs31.existsSync)(path2)) return [];
|
|
11990
|
+
return (0, import_node_fs31.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
11600
11991
|
}
|
|
11601
11992
|
function resolveFilesToCopy(repoPath) {
|
|
11602
11993
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -11606,10 +11997,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
11606
11997
|
if (settings?.fileIncludeGlobs?.length) {
|
|
11607
11998
|
const matched = [];
|
|
11608
11999
|
try {
|
|
11609
|
-
for (const entry of (0,
|
|
12000
|
+
for (const entry of (0, import_node_fs31.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
11610
12001
|
if (!entry.isFile()) continue;
|
|
11611
12002
|
for (const glob of settings.fileIncludeGlobs) {
|
|
11612
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
12003
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path30.basename)(glob), entry.name)) {
|
|
11613
12004
|
matched.push(entry.name);
|
|
11614
12005
|
break;
|
|
11615
12006
|
}
|
|
@@ -11621,7 +12012,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
11621
12012
|
}
|
|
11622
12013
|
const defaults = [];
|
|
11623
12014
|
try {
|
|
11624
|
-
for (const entry of (0,
|
|
12015
|
+
for (const entry of (0, import_node_fs31.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
11625
12016
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
11626
12017
|
defaults.push(entry.name);
|
|
11627
12018
|
}
|
|
@@ -11635,11 +12026,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
11635
12026
|
const patterns = resolveFilesToCopy(repoPath);
|
|
11636
12027
|
const copied = [];
|
|
11637
12028
|
for (const rel of patterns) {
|
|
11638
|
-
const src = (0,
|
|
11639
|
-
if (!(0,
|
|
11640
|
-
const dest = (0,
|
|
11641
|
-
(0,
|
|
11642
|
-
(0,
|
|
12029
|
+
const src = (0, import_node_path30.join)(repoPath, rel);
|
|
12030
|
+
if (!(0, import_node_fs31.existsSync)(src)) continue;
|
|
12031
|
+
const dest = (0, import_node_path30.join)(worktreePath, rel);
|
|
12032
|
+
(0, import_node_fs31.mkdirSync)((0, import_node_path30.dirname)(dest), { recursive: true });
|
|
12033
|
+
(0, import_node_fs31.copyFileSync)(src, dest);
|
|
11643
12034
|
copied.push(rel);
|
|
11644
12035
|
}
|
|
11645
12036
|
return copied;
|
|
@@ -11674,7 +12065,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
11674
12065
|
const env = stripNestedElectronEnv({
|
|
11675
12066
|
...baseEnv ?? process.env
|
|
11676
12067
|
});
|
|
11677
|
-
const name = opts.workspaceName ?? (0,
|
|
12068
|
+
const name = opts.workspaceName ?? (0, import_node_path30.basename)(opts.worktreePath);
|
|
11678
12069
|
const ports = opts.ports ?? [];
|
|
11679
12070
|
const primary = ports[0];
|
|
11680
12071
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -11935,13 +12326,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
11935
12326
|
done: handle.done
|
|
11936
12327
|
};
|
|
11937
12328
|
}
|
|
11938
|
-
var
|
|
12329
|
+
var import_node_fs31, import_node_net, import_node_path30, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
11939
12330
|
var init_conductor = __esm({
|
|
11940
12331
|
"src/hook/conductor.ts"() {
|
|
11941
12332
|
"use strict";
|
|
11942
|
-
|
|
12333
|
+
import_node_fs31 = require("fs");
|
|
11943
12334
|
import_node_net = require("net");
|
|
11944
|
-
|
|
12335
|
+
import_node_path30 = require("path");
|
|
11945
12336
|
import_execa4 = require("execa");
|
|
11946
12337
|
import_node_readline3 = require("readline");
|
|
11947
12338
|
init_settings();
|
|
@@ -11967,9 +12358,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11967
12358
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
11968
12359
|
);
|
|
11969
12360
|
const homeRoot = sideboardWorkspacesDir();
|
|
11970
|
-
if ((0,
|
|
12361
|
+
if ((0, import_node_fs32.existsSync)(homeRoot)) {
|
|
11971
12362
|
try {
|
|
11972
|
-
for (const entry of (0,
|
|
12363
|
+
for (const entry of (0, import_node_fs32.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
11973
12364
|
if (!entry.isDirectory()) continue;
|
|
11974
12365
|
void entry;
|
|
11975
12366
|
}
|
|
@@ -11979,7 +12370,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11979
12370
|
const orphans = [];
|
|
11980
12371
|
const seen = /* @__PURE__ */ new Set();
|
|
11981
12372
|
for (const repoPath of repos) {
|
|
11982
|
-
if (!repoPath || !(0,
|
|
12373
|
+
if (!repoPath || !(0, import_node_fs32.existsSync)(repoPath)) continue;
|
|
11983
12374
|
try {
|
|
11984
12375
|
const wts = await listWorktrees(repoPath);
|
|
11985
12376
|
for (const wt of wts) {
|
|
@@ -11990,7 +12381,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
11990
12381
|
seen.add(path2);
|
|
11991
12382
|
let mtimeMs = 0;
|
|
11992
12383
|
try {
|
|
11993
|
-
mtimeMs = (0,
|
|
12384
|
+
mtimeMs = (0, import_node_fs32.statSync)(path2).mtimeMs;
|
|
11994
12385
|
} catch {
|
|
11995
12386
|
mtimeMs = 0;
|
|
11996
12387
|
}
|
|
@@ -12000,16 +12391,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
12000
12391
|
}
|
|
12001
12392
|
try {
|
|
12002
12393
|
const root = worktreesRoot(repoPath);
|
|
12003
|
-
if ((0,
|
|
12004
|
-
for (const entry of (0,
|
|
12394
|
+
if ((0, import_node_fs32.existsSync)(root)) {
|
|
12395
|
+
for (const entry of (0, import_node_fs32.readdirSync)(root, { withFileTypes: true })) {
|
|
12005
12396
|
if (!entry.isDirectory()) continue;
|
|
12006
|
-
const path2 = (0,
|
|
12397
|
+
const path2 = (0, import_node_path31.join)(root, entry.name).replace(/\/$/, "");
|
|
12007
12398
|
if (known.has(path2) || seen.has(path2)) continue;
|
|
12008
|
-
if (!(0,
|
|
12399
|
+
if (!(0, import_node_fs32.existsSync)((0, import_node_path31.join)(path2, ".git"))) continue;
|
|
12009
12400
|
seen.add(path2);
|
|
12010
12401
|
let mtimeMs = 0;
|
|
12011
12402
|
try {
|
|
12012
|
-
mtimeMs = (0,
|
|
12403
|
+
mtimeMs = (0, import_node_fs32.statSync)(path2).mtimeMs;
|
|
12013
12404
|
} catch {
|
|
12014
12405
|
mtimeMs = Date.now();
|
|
12015
12406
|
}
|
|
@@ -12070,12 +12461,12 @@ function worktreeCleanupSettings() {
|
|
|
12070
12461
|
autoCleanupOrphans: a.autoCleanupOrphans
|
|
12071
12462
|
};
|
|
12072
12463
|
}
|
|
12073
|
-
var
|
|
12464
|
+
var import_node_fs32, import_node_path31;
|
|
12074
12465
|
var init_orphan_cleanup = __esm({
|
|
12075
12466
|
"src/git/orphan-cleanup.ts"() {
|
|
12076
12467
|
"use strict";
|
|
12077
|
-
|
|
12078
|
-
|
|
12468
|
+
import_node_fs32 = require("fs");
|
|
12469
|
+
import_node_path31 = require("path");
|
|
12079
12470
|
init_worktree();
|
|
12080
12471
|
init_thread_store();
|
|
12081
12472
|
init_paths();
|
|
@@ -12182,38 +12573,38 @@ __export(workspaces_exports, {
|
|
|
12182
12573
|
syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
|
|
12183
12574
|
});
|
|
12184
12575
|
function workspacesFile() {
|
|
12185
|
-
return (0,
|
|
12576
|
+
return (0, import_node_path32.join)(appDataDir(), "workspaces.json");
|
|
12186
12577
|
}
|
|
12187
12578
|
function removedWorkspacesFile() {
|
|
12188
|
-
return (0,
|
|
12579
|
+
return (0, import_node_path32.join)(appDataDir(), "removed-workspaces.json");
|
|
12189
12580
|
}
|
|
12190
12581
|
function readAll2() {
|
|
12191
12582
|
const path2 = workspacesFile();
|
|
12192
|
-
if (!(0,
|
|
12583
|
+
if (!(0, import_node_fs33.existsSync)(path2)) return [];
|
|
12193
12584
|
try {
|
|
12194
|
-
const raw = JSON.parse((0,
|
|
12585
|
+
const raw = JSON.parse((0, import_node_fs33.readFileSync)(path2, "utf8"));
|
|
12195
12586
|
return Array.isArray(raw) ? raw : [];
|
|
12196
12587
|
} catch {
|
|
12197
12588
|
return [];
|
|
12198
12589
|
}
|
|
12199
12590
|
}
|
|
12200
12591
|
function writeAll2(list) {
|
|
12201
|
-
(0,
|
|
12202
|
-
(0,
|
|
12592
|
+
(0, import_node_fs33.mkdirSync)(appDataDir(), { recursive: true });
|
|
12593
|
+
(0, import_node_fs33.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
|
|
12203
12594
|
}
|
|
12204
12595
|
function readRemoved() {
|
|
12205
12596
|
const path2 = removedWorkspacesFile();
|
|
12206
|
-
if (!(0,
|
|
12597
|
+
if (!(0, import_node_fs33.existsSync)(path2)) return /* @__PURE__ */ new Set();
|
|
12207
12598
|
try {
|
|
12208
|
-
const raw = JSON.parse((0,
|
|
12599
|
+
const raw = JSON.parse((0, import_node_fs33.readFileSync)(path2, "utf8"));
|
|
12209
12600
|
return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
|
|
12210
12601
|
} catch {
|
|
12211
12602
|
return /* @__PURE__ */ new Set();
|
|
12212
12603
|
}
|
|
12213
12604
|
}
|
|
12214
12605
|
function writeRemoved(paths) {
|
|
12215
|
-
(0,
|
|
12216
|
-
(0,
|
|
12606
|
+
(0, import_node_fs33.mkdirSync)(appDataDir(), { recursive: true });
|
|
12607
|
+
(0, import_node_fs33.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
|
|
12217
12608
|
}
|
|
12218
12609
|
function rememberRemoved(repoPath) {
|
|
12219
12610
|
const next = readRemoved();
|
|
@@ -12236,7 +12627,7 @@ function listWorkspaces() {
|
|
|
12236
12627
|
async function addWorkspace(repoPath) {
|
|
12237
12628
|
const root = await resolveRepoRoot(repoPath);
|
|
12238
12629
|
if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
|
|
12239
|
-
if (!(0,
|
|
12630
|
+
if (!(0, import_node_fs33.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
|
|
12240
12631
|
forgetRemoved(root);
|
|
12241
12632
|
await ensureGhPreferOrigin(root);
|
|
12242
12633
|
const current = readAll2();
|
|
@@ -12244,7 +12635,7 @@ async function addWorkspace(repoPath) {
|
|
|
12244
12635
|
if (existing) return existing;
|
|
12245
12636
|
const next = {
|
|
12246
12637
|
path: root,
|
|
12247
|
-
name: (0,
|
|
12638
|
+
name: (0, import_node_path32.basename)(root),
|
|
12248
12639
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12249
12640
|
};
|
|
12250
12641
|
writeAll2([...current, next]);
|
|
@@ -12266,10 +12657,10 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
12266
12657
|
if (!path2 || path2 === "/" || isGlobalRepoPath(path2) || byPath.has(path2) || removed.has(path2)) {
|
|
12267
12658
|
continue;
|
|
12268
12659
|
}
|
|
12269
|
-
if (!(0,
|
|
12660
|
+
if (!(0, import_node_fs33.existsSync)(path2)) continue;
|
|
12270
12661
|
const ws = {
|
|
12271
12662
|
path: path2,
|
|
12272
|
-
name: (0,
|
|
12663
|
+
name: (0, import_node_path32.basename)(path2),
|
|
12273
12664
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12274
12665
|
};
|
|
12275
12666
|
byPath.set(path2, ws);
|
|
@@ -12279,12 +12670,12 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
12279
12670
|
if (dirty) writeAll2(next);
|
|
12280
12671
|
return next.sort((a, b) => a.name.localeCompare(b.name));
|
|
12281
12672
|
}
|
|
12282
|
-
var
|
|
12673
|
+
var import_node_fs33, import_node_path32;
|
|
12283
12674
|
var init_workspaces2 = __esm({
|
|
12284
12675
|
"src/store/workspaces.ts"() {
|
|
12285
12676
|
"use strict";
|
|
12286
|
-
|
|
12287
|
-
|
|
12677
|
+
import_node_fs33 = require("fs");
|
|
12678
|
+
import_node_path32 = require("path");
|
|
12288
12679
|
init_paths();
|
|
12289
12680
|
init_global_workspace();
|
|
12290
12681
|
init_worktree();
|
|
@@ -12297,12 +12688,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
12297
12688
|
if (!url) throw new Error("Clone URL is required");
|
|
12298
12689
|
let name = opts.name?.trim();
|
|
12299
12690
|
if (!name) {
|
|
12300
|
-
const leaf = (0,
|
|
12691
|
+
const leaf = (0, import_node_path33.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
12301
12692
|
name = leaf || "repo";
|
|
12302
12693
|
}
|
|
12303
12694
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
12304
|
-
const dest = (0,
|
|
12305
|
-
if ((0,
|
|
12695
|
+
const dest = (0, import_node_path33.join)(sideboardReposDir(), name);
|
|
12696
|
+
if ((0, import_node_fs34.existsSync)(dest)) {
|
|
12306
12697
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
12307
12698
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
12308
12699
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -12317,12 +12708,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
12317
12708
|
const workspace = await ensureWorkspace(repoPath);
|
|
12318
12709
|
return { repoPath, workspace };
|
|
12319
12710
|
}
|
|
12320
|
-
var
|
|
12711
|
+
var import_node_fs34, import_node_path33, import_execa6;
|
|
12321
12712
|
var init_clone_repo = __esm({
|
|
12322
12713
|
"src/git/clone-repo.ts"() {
|
|
12323
12714
|
"use strict";
|
|
12324
|
-
|
|
12325
|
-
|
|
12715
|
+
import_node_fs34 = require("fs");
|
|
12716
|
+
import_node_path33 = require("path");
|
|
12326
12717
|
import_execa6 = require("execa");
|
|
12327
12718
|
init_paths();
|
|
12328
12719
|
init_workspaces2();
|
|
@@ -12380,7 +12771,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
12380
12771
|
});
|
|
12381
12772
|
await requireAgent(resolved.agent);
|
|
12382
12773
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
12383
|
-
if (!(0,
|
|
12774
|
+
if (!(0, import_node_fs35.existsSync)(repoPath)) {
|
|
12384
12775
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
12385
12776
|
}
|
|
12386
12777
|
if (input.cowboy) {
|
|
@@ -12503,11 +12894,11 @@ async function listLinearIssues(agent, repoPath) {
|
|
|
12503
12894
|
}
|
|
12504
12895
|
return adapter.listLinearIssues(repoPath);
|
|
12505
12896
|
}
|
|
12506
|
-
var
|
|
12897
|
+
var import_node_fs35;
|
|
12507
12898
|
var init_create = __esm({
|
|
12508
12899
|
"src/threads/create.ts"() {
|
|
12509
12900
|
"use strict";
|
|
12510
|
-
|
|
12901
|
+
import_node_fs35 = require("fs");
|
|
12511
12902
|
init_detect();
|
|
12512
12903
|
init_worktree();
|
|
12513
12904
|
init_conductor();
|
|
@@ -12552,21 +12943,13 @@ function summarizeTurnLive(parts) {
|
|
|
12552
12943
|
(p) => p.type === "tool"
|
|
12553
12944
|
);
|
|
12554
12945
|
const lastTool = tools[tools.length - 1];
|
|
12555
|
-
const
|
|
12556
|
-
const
|
|
12946
|
+
const interesting = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? lastTool;
|
|
12947
|
+
const lastToolLabel = interesting ? interesting.description || toolDescription(interesting.name, interesting.input) || interesting.name : void 0;
|
|
12557
12948
|
const thinking = lastText(parts, "thinking");
|
|
12558
12949
|
const text4 = lastText(parts, "text");
|
|
12559
12950
|
const excerptRaw = thinking || text4;
|
|
12560
12951
|
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
|
-
}
|
|
12952
|
+
const summary = liveActivitySummary(parts);
|
|
12570
12953
|
return {
|
|
12571
12954
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12572
12955
|
summary,
|
|
@@ -12616,20 +12999,20 @@ function writeTurnLive(threadId, progress) {
|
|
|
12616
12999
|
const path2 = threadLivePath(threadId);
|
|
12617
13000
|
const tmp = `${path2}.${process.pid}.tmp`;
|
|
12618
13001
|
try {
|
|
12619
|
-
(0,
|
|
12620
|
-
(0,
|
|
13002
|
+
(0, import_node_fs36.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
|
|
13003
|
+
(0, import_node_fs36.renameSync)(tmp, path2);
|
|
12621
13004
|
} catch {
|
|
12622
13005
|
try {
|
|
12623
|
-
(0,
|
|
13006
|
+
(0, import_node_fs36.unlinkSync)(tmp);
|
|
12624
13007
|
} catch {
|
|
12625
13008
|
}
|
|
12626
13009
|
}
|
|
12627
13010
|
}
|
|
12628
13011
|
function readTurnLive(threadId) {
|
|
12629
13012
|
const path2 = threadLivePath(threadId);
|
|
12630
|
-
if (!(0,
|
|
13013
|
+
if (!(0, import_node_fs36.existsSync)(path2)) return null;
|
|
12631
13014
|
try {
|
|
12632
|
-
const raw = JSON.parse((0,
|
|
13015
|
+
const raw = JSON.parse((0, import_node_fs36.readFileSync)(path2, "utf8"));
|
|
12633
13016
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
12634
13017
|
return raw;
|
|
12635
13018
|
} catch {
|
|
@@ -12641,17 +13024,17 @@ function clearTurnLive(threadId) {
|
|
|
12641
13024
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
12642
13025
|
buffers.delete(threadId);
|
|
12643
13026
|
const path2 = threadLivePath(threadId);
|
|
12644
|
-
if (!(0,
|
|
13027
|
+
if (!(0, import_node_fs36.existsSync)(path2)) return;
|
|
12645
13028
|
try {
|
|
12646
|
-
(0,
|
|
13029
|
+
(0, import_node_fs36.unlinkSync)(path2);
|
|
12647
13030
|
} catch {
|
|
12648
13031
|
}
|
|
12649
13032
|
}
|
|
12650
|
-
var
|
|
13033
|
+
var import_node_fs36, buffers, FLUSH_MS, MAX_PARTS;
|
|
12651
13034
|
var init_turn_live = __esm({
|
|
12652
13035
|
"src/store/turn-live.ts"() {
|
|
12653
13036
|
"use strict";
|
|
12654
|
-
|
|
13037
|
+
import_node_fs36 = require("fs");
|
|
12655
13038
|
init_message_parts();
|
|
12656
13039
|
init_paths();
|
|
12657
13040
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -12830,7 +13213,7 @@ var init_quota_failover = __esm({
|
|
|
12830
13213
|
// src/threads/adopt.ts
|
|
12831
13214
|
function thisModuleFile() {
|
|
12832
13215
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
12833
|
-
return cjsFile || process.argv[1] || (0,
|
|
13216
|
+
return cjsFile || process.argv[1] || (0, import_node_path34.join)(process.cwd(), "package.json");
|
|
12834
13217
|
}
|
|
12835
13218
|
function openReadonlySqlite(file) {
|
|
12836
13219
|
const req = (0, import_node_module4.createRequire)(thisModuleFile());
|
|
@@ -12848,21 +13231,21 @@ function mapAgentType(raw) {
|
|
|
12848
13231
|
return null;
|
|
12849
13232
|
}
|
|
12850
13233
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
12851
|
-
if (!workspacePath || !(0,
|
|
13234
|
+
if (!workspacePath || !(0, import_node_fs37.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
12852
13235
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
12853
13236
|
let best = null;
|
|
12854
13237
|
let hashes;
|
|
12855
13238
|
try {
|
|
12856
|
-
hashes = (0,
|
|
13239
|
+
hashes = (0, import_node_fs37.readdirSync)(CURSOR_SDK_STORE);
|
|
12857
13240
|
} catch {
|
|
12858
13241
|
return null;
|
|
12859
13242
|
}
|
|
12860
13243
|
for (const hash of hashes) {
|
|
12861
|
-
const agentsFile = (0,
|
|
12862
|
-
if (!(0,
|
|
13244
|
+
const agentsFile = (0, import_node_path34.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
13245
|
+
if (!(0, import_node_fs37.existsSync)(agentsFile)) continue;
|
|
12863
13246
|
let text4;
|
|
12864
13247
|
try {
|
|
12865
|
-
text4 = (0,
|
|
13248
|
+
text4 = (0, import_node_fs37.readFileSync)(agentsFile, "utf8");
|
|
12866
13249
|
} catch {
|
|
12867
13250
|
continue;
|
|
12868
13251
|
}
|
|
@@ -12886,7 +13269,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
12886
13269
|
return best?.agentId ?? null;
|
|
12887
13270
|
}
|
|
12888
13271
|
async function adoptThread(input) {
|
|
12889
|
-
if (!(0,
|
|
13272
|
+
if (!(0, import_node_fs37.existsSync)(input.worktreePath)) {
|
|
12890
13273
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
12891
13274
|
}
|
|
12892
13275
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -12913,18 +13296,18 @@ function conductorDbPath() {
|
|
|
12913
13296
|
return CONDUCTOR_DB;
|
|
12914
13297
|
}
|
|
12915
13298
|
function listConductorWorkspaces() {
|
|
12916
|
-
if (!(0,
|
|
13299
|
+
if (!(0, import_node_fs37.existsSync)(CONDUCTOR_DB)) {
|
|
12917
13300
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
12918
13301
|
}
|
|
12919
|
-
const tmp = (0,
|
|
12920
|
-
const snapshot = (0,
|
|
13302
|
+
const tmp = (0, import_node_fs37.mkdtempSync)((0, import_node_path34.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
|
|
13303
|
+
const snapshot = (0, import_node_path34.join)(tmp, "conductor.db");
|
|
12921
13304
|
try {
|
|
12922
|
-
(0,
|
|
13305
|
+
(0, import_node_fs37.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
12923
13306
|
for (const suffix of ["-wal", "-shm"]) {
|
|
12924
13307
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
12925
|
-
if ((0,
|
|
13308
|
+
if ((0, import_node_fs37.existsSync)(src)) {
|
|
12926
13309
|
try {
|
|
12927
|
-
(0,
|
|
13310
|
+
(0, import_node_fs37.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
12928
13311
|
} catch {
|
|
12929
13312
|
}
|
|
12930
13313
|
}
|
|
@@ -13000,22 +13383,22 @@ function listConductorWorkspaces() {
|
|
|
13000
13383
|
db.close();
|
|
13001
13384
|
}
|
|
13002
13385
|
} finally {
|
|
13003
|
-
(0,
|
|
13386
|
+
(0, import_node_fs37.rmSync)(tmp, { recursive: true, force: true });
|
|
13004
13387
|
}
|
|
13005
13388
|
}
|
|
13006
13389
|
function importConductorWorkspace(workspaceId) {
|
|
13007
|
-
if (!(0,
|
|
13390
|
+
if (!(0, import_node_fs37.existsSync)(CONDUCTOR_DB)) {
|
|
13008
13391
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
13009
13392
|
}
|
|
13010
|
-
const tmp = (0,
|
|
13011
|
-
const snapshot = (0,
|
|
13393
|
+
const tmp = (0, import_node_fs37.mkdtempSync)((0, import_node_path34.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
|
|
13394
|
+
const snapshot = (0, import_node_path34.join)(tmp, "conductor.db");
|
|
13012
13395
|
try {
|
|
13013
|
-
(0,
|
|
13396
|
+
(0, import_node_fs37.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
13014
13397
|
for (const suffix of ["-wal", "-shm"]) {
|
|
13015
13398
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
13016
|
-
if ((0,
|
|
13399
|
+
if ((0, import_node_fs37.existsSync)(src)) {
|
|
13017
13400
|
try {
|
|
13018
|
-
(0,
|
|
13401
|
+
(0, import_node_fs37.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
13019
13402
|
} catch {
|
|
13020
13403
|
}
|
|
13021
13404
|
}
|
|
@@ -13033,7 +13416,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
13033
13416
|
).get(workspaceId);
|
|
13034
13417
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
13035
13418
|
const worktreePath = String(row.workspacePath);
|
|
13036
|
-
if (!(0,
|
|
13419
|
+
if (!(0, import_node_fs37.existsSync)(worktreePath)) {
|
|
13037
13420
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
13038
13421
|
}
|
|
13039
13422
|
let sessionId = null;
|
|
@@ -13096,31 +13479,31 @@ function importConductorWorkspace(workspaceId) {
|
|
|
13096
13479
|
db.close();
|
|
13097
13480
|
}
|
|
13098
13481
|
} finally {
|
|
13099
|
-
(0,
|
|
13482
|
+
(0, import_node_fs37.rmSync)(tmp, { recursive: true, force: true });
|
|
13100
13483
|
}
|
|
13101
13484
|
}
|
|
13102
13485
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
13103
13486
|
return importConductorWorkspace(workspaceId);
|
|
13104
13487
|
}
|
|
13105
|
-
var import_node_child_process4,
|
|
13488
|
+
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
13489
|
var init_adopt = __esm({
|
|
13107
13490
|
"src/threads/adopt.ts"() {
|
|
13108
13491
|
"use strict";
|
|
13109
13492
|
import_node_child_process4 = require("child_process");
|
|
13110
|
-
|
|
13493
|
+
import_node_fs37 = require("fs");
|
|
13111
13494
|
import_node_os10 = require("os");
|
|
13112
|
-
|
|
13495
|
+
import_node_path34 = require("path");
|
|
13113
13496
|
import_node_module4 = require("module");
|
|
13114
13497
|
init_worktree();
|
|
13115
13498
|
init_thread_store();
|
|
13116
|
-
CONDUCTOR_APP_SUPPORT = (0,
|
|
13499
|
+
CONDUCTOR_APP_SUPPORT = (0, import_node_path34.join)(
|
|
13117
13500
|
process.env.HOME ?? "",
|
|
13118
13501
|
"Library",
|
|
13119
13502
|
"Application Support",
|
|
13120
13503
|
"com.conductor.app"
|
|
13121
13504
|
);
|
|
13122
|
-
CONDUCTOR_DB = (0,
|
|
13123
|
-
CURSOR_SDK_STORE = (0,
|
|
13505
|
+
CONDUCTOR_DB = (0, import_node_path34.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
13506
|
+
CURSOR_SDK_STORE = (0, import_node_path34.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
13124
13507
|
}
|
|
13125
13508
|
});
|
|
13126
13509
|
|
|
@@ -13187,7 +13570,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
13187
13570
|
let createdWorktree = false;
|
|
13188
13571
|
const trees = await listWorktrees(repoPath);
|
|
13189
13572
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
13190
|
-
if (checkedOut?.path && (0,
|
|
13573
|
+
if (checkedOut?.path && (0, import_node_fs38.existsSync)(checkedOut.path)) {
|
|
13191
13574
|
if (input.reuseExistingWorktree !== false) {
|
|
13192
13575
|
worktreePath = checkedOut.path;
|
|
13193
13576
|
} else {
|
|
@@ -13329,7 +13712,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
13329
13712
|
async function createPrStack(input, onSetupLine) {
|
|
13330
13713
|
await requireAgent(input.agent);
|
|
13331
13714
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
13332
|
-
if (!(0,
|
|
13715
|
+
if (!(0, import_node_fs38.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
13333
13716
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
13334
13717
|
const status = await detectGhStack(repoPath);
|
|
13335
13718
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -13396,7 +13779,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
13396
13779
|
}
|
|
13397
13780
|
}
|
|
13398
13781
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
13399
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
13782
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs38.existsSync)(bootstrap.worktreePath)) {
|
|
13400
13783
|
try {
|
|
13401
13784
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
13402
13785
|
deleteBranch: bootstrap.branchName
|
|
@@ -13416,11 +13799,11 @@ function stackAgentDefaultsFrom(input) {
|
|
|
13416
13799
|
planMode: input.planMode
|
|
13417
13800
|
};
|
|
13418
13801
|
}
|
|
13419
|
-
var
|
|
13802
|
+
var import_node_fs38;
|
|
13420
13803
|
var init_stack_layers = __esm({
|
|
13421
13804
|
"src/threads/stack-layers.ts"() {
|
|
13422
13805
|
"use strict";
|
|
13423
|
-
|
|
13806
|
+
import_node_fs38 = require("fs");
|
|
13424
13807
|
init_detect();
|
|
13425
13808
|
init_run();
|
|
13426
13809
|
init_stack();
|
|
@@ -13433,7 +13816,7 @@ var init_stack_layers = __esm({
|
|
|
13433
13816
|
|
|
13434
13817
|
// src/diff/diff.ts
|
|
13435
13818
|
async function inspectGitWorktree(worktreePath) {
|
|
13436
|
-
if (!worktreePath || !(0,
|
|
13819
|
+
if (!worktreePath || !(0, import_node_fs39.existsSync)(worktreePath)) return "missing_worktree";
|
|
13437
13820
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
13438
13821
|
reject: false
|
|
13439
13822
|
});
|
|
@@ -13441,7 +13824,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
13441
13824
|
return "ok";
|
|
13442
13825
|
}
|
|
13443
13826
|
async function initializeGitRepository(worktreePath) {
|
|
13444
|
-
if (!worktreePath || !(0,
|
|
13827
|
+
if (!worktreePath || !(0, import_node_fs39.existsSync)(worktreePath)) {
|
|
13445
13828
|
throw new Error("Worktree not found");
|
|
13446
13829
|
}
|
|
13447
13830
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -13575,11 +13958,11 @@ new file mode 100644
|
|
|
13575
13958
|
};
|
|
13576
13959
|
}
|
|
13577
13960
|
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
13578
|
-
const abs = (0,
|
|
13961
|
+
const abs = (0, import_node_path35.join)(worktreePath, path2);
|
|
13579
13962
|
try {
|
|
13580
|
-
const st = (0,
|
|
13963
|
+
const st = (0, import_node_fs39.statSync)(abs);
|
|
13581
13964
|
if (st.isFile() && st.size > maxHunk) {
|
|
13582
|
-
const buf = (0,
|
|
13965
|
+
const buf = (0, import_node_fs39.readFileSync)(abs).subarray(0, maxHunk);
|
|
13583
13966
|
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
13584
13967
|
}
|
|
13585
13968
|
} catch {
|
|
@@ -14068,8 +14451,8 @@ function isImageRelativePath(relativePath) {
|
|
|
14068
14451
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
14069
14452
|
assertSafeRelativePath(relativePath);
|
|
14070
14453
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
14071
|
-
const abs = (0,
|
|
14072
|
-
const st = (0,
|
|
14454
|
+
const abs = (0, import_node_path35.join)(worktreePath, relativePath);
|
|
14455
|
+
const st = (0, import_node_fs39.statSync)(abs);
|
|
14073
14456
|
if (!st.isFile()) {
|
|
14074
14457
|
throw new Error(`Not a file: ${relativePath}`);
|
|
14075
14458
|
}
|
|
@@ -14078,7 +14461,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
14078
14461
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
14079
14462
|
);
|
|
14080
14463
|
}
|
|
14081
|
-
const buf = (0,
|
|
14464
|
+
const buf = (0, import_node_fs39.readFileSync)(abs);
|
|
14082
14465
|
return {
|
|
14083
14466
|
path: relativePath,
|
|
14084
14467
|
contentBase64: buf.toString("base64"),
|
|
@@ -14088,12 +14471,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
14088
14471
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
14089
14472
|
assertSafeRelativePath(relativePath);
|
|
14090
14473
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
14091
|
-
const abs = (0,
|
|
14092
|
-
const st = (0,
|
|
14474
|
+
const abs = (0, import_node_path35.join)(worktreePath, relativePath);
|
|
14475
|
+
const st = (0, import_node_fs39.statSync)(abs);
|
|
14093
14476
|
if (!st.isFile()) {
|
|
14094
14477
|
throw new Error(`Not a file: ${relativePath}`);
|
|
14095
14478
|
}
|
|
14096
|
-
const buf = (0,
|
|
14479
|
+
const buf = (0, import_node_fs39.readFileSync)(abs);
|
|
14097
14480
|
if (isImageRelativePath(relativePath)) {
|
|
14098
14481
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
14099
14482
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -14136,9 +14519,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
14136
14519
|
}
|
|
14137
14520
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
14138
14521
|
assertSafeRelativePath(relativePath);
|
|
14139
|
-
const abs = (0,
|
|
14140
|
-
(0,
|
|
14141
|
-
(0,
|
|
14522
|
+
const abs = (0, import_node_path35.join)(worktreePath, relativePath);
|
|
14523
|
+
(0, import_node_fs39.mkdirSync)((0, import_node_path35.dirname)(abs), { recursive: true });
|
|
14524
|
+
(0, import_node_fs39.writeFileSync)(abs, content, "utf8");
|
|
14142
14525
|
return { path: relativePath };
|
|
14143
14526
|
}
|
|
14144
14527
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -14155,12 +14538,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
14155
14538
|
truncated: full.files.length > maxFiles
|
|
14156
14539
|
};
|
|
14157
14540
|
}
|
|
14158
|
-
var
|
|
14541
|
+
var import_node_fs39, import_node_path35, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS, DEFAULT_UPLOAD_MAX_BYTES;
|
|
14159
14542
|
var init_diff = __esm({
|
|
14160
14543
|
"src/diff/diff.ts"() {
|
|
14161
14544
|
"use strict";
|
|
14162
|
-
|
|
14163
|
-
|
|
14545
|
+
import_node_fs39 = require("fs");
|
|
14546
|
+
import_node_path35 = require("path");
|
|
14164
14547
|
init_run();
|
|
14165
14548
|
init_worktree();
|
|
14166
14549
|
mergeBaseCache = /* @__PURE__ */ new Map();
|
|
@@ -14328,7 +14711,7 @@ function parseFrontmatter(content) {
|
|
|
14328
14711
|
}
|
|
14329
14712
|
function readSkill(skillMd, source) {
|
|
14330
14713
|
try {
|
|
14331
|
-
const content = (0,
|
|
14714
|
+
const content = (0, import_node_fs40.readFileSync)(skillMd, "utf8");
|
|
14332
14715
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
14333
14716
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
14334
14717
|
const name = fmName || dirName;
|
|
@@ -14347,19 +14730,19 @@ function readSkill(skillMd, source) {
|
|
|
14347
14730
|
}
|
|
14348
14731
|
}
|
|
14349
14732
|
function scanSkillsDir(dir, source, out) {
|
|
14350
|
-
if (!(0,
|
|
14733
|
+
if (!(0, import_node_fs40.existsSync)(dir)) return;
|
|
14351
14734
|
let entries;
|
|
14352
14735
|
try {
|
|
14353
|
-
entries = (0,
|
|
14736
|
+
entries = (0, import_node_fs40.readdirSync)(dir);
|
|
14354
14737
|
} catch {
|
|
14355
14738
|
return;
|
|
14356
14739
|
}
|
|
14357
14740
|
for (const entry of entries) {
|
|
14358
14741
|
if (entry.startsWith(".")) continue;
|
|
14359
|
-
const skillMd = (0,
|
|
14360
|
-
if (!(0,
|
|
14742
|
+
const skillMd = (0, import_node_path36.join)(dir, entry, "SKILL.md");
|
|
14743
|
+
if (!(0, import_node_fs40.existsSync)(skillMd)) continue;
|
|
14361
14744
|
try {
|
|
14362
|
-
if (!(0,
|
|
14745
|
+
if (!(0, import_node_fs40.statSync)(skillMd).isFile()) continue;
|
|
14363
14746
|
} catch {
|
|
14364
14747
|
continue;
|
|
14365
14748
|
}
|
|
@@ -14368,24 +14751,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
14368
14751
|
}
|
|
14369
14752
|
}
|
|
14370
14753
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
14371
|
-
if (!(0,
|
|
14754
|
+
if (!(0, import_node_fs40.existsSync)(pluginsRoot)) return;
|
|
14372
14755
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
14373
14756
|
if (depth > 7) return;
|
|
14374
14757
|
let entries;
|
|
14375
14758
|
try {
|
|
14376
|
-
entries = (0,
|
|
14759
|
+
entries = (0, import_node_fs40.readdirSync)(dir);
|
|
14377
14760
|
} catch {
|
|
14378
14761
|
return;
|
|
14379
14762
|
}
|
|
14380
14763
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
14381
|
-
const skill = readSkill((0,
|
|
14764
|
+
const skill = readSkill((0, import_node_path36.join)(dir, "SKILL.md"), "cli");
|
|
14382
14765
|
if (skill) out.push(skill);
|
|
14383
14766
|
}
|
|
14384
14767
|
for (const entry of entries) {
|
|
14385
14768
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
14386
|
-
const full = (0,
|
|
14769
|
+
const full = (0, import_node_path36.join)(dir, entry);
|
|
14387
14770
|
try {
|
|
14388
|
-
if (!(0,
|
|
14771
|
+
if (!(0, import_node_fs40.statSync)(full).isDirectory()) continue;
|
|
14389
14772
|
} catch {
|
|
14390
14773
|
continue;
|
|
14391
14774
|
}
|
|
@@ -14403,17 +14786,17 @@ function discoverSkills(worktreePath) {
|
|
|
14403
14786
|
const home = (0, import_node_os11.homedir)();
|
|
14404
14787
|
const collected = [];
|
|
14405
14788
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
14406
|
-
scanSkillsDir((0,
|
|
14789
|
+
scanSkillsDir((0, import_node_path36.join)(worktreePath, rel), "workspace", collected);
|
|
14407
14790
|
}
|
|
14408
14791
|
for (const abs of [
|
|
14409
|
-
(0,
|
|
14410
|
-
(0,
|
|
14411
|
-
(0,
|
|
14412
|
-
(0,
|
|
14792
|
+
(0, import_node_path36.join)(home, ".claude/skills"),
|
|
14793
|
+
(0, import_node_path36.join)(home, ".cursor/skills"),
|
|
14794
|
+
(0, import_node_path36.join)(home, ".sideboard/skills"),
|
|
14795
|
+
(0, import_node_path36.join)(home, ".brightsy/skills")
|
|
14413
14796
|
]) {
|
|
14414
14797
|
scanSkillsDir(abs, "user", collected);
|
|
14415
14798
|
}
|
|
14416
|
-
scanClaudePluginSkills((0,
|
|
14799
|
+
scanClaudePluginSkills((0, import_node_path36.join)(home, ".claude/plugins"), collected);
|
|
14417
14800
|
const rank = { workspace: 0, user: 1, cli: 2 };
|
|
14418
14801
|
const byCommand = /* @__PURE__ */ new Map();
|
|
14419
14802
|
for (const skill of collected) {
|
|
@@ -14425,7 +14808,7 @@ function discoverSkills(worktreePath) {
|
|
|
14425
14808
|
return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
|
|
14426
14809
|
}
|
|
14427
14810
|
function readSkillBody(skillPath, maxChars = 12e3) {
|
|
14428
|
-
const raw = (0,
|
|
14811
|
+
const raw = (0, import_node_fs40.readFileSync)(skillPath, "utf8");
|
|
14429
14812
|
if (raw.startsWith("---")) {
|
|
14430
14813
|
const end = raw.indexOf("\n---", 3);
|
|
14431
14814
|
if (end >= 0) {
|
|
@@ -14439,13 +14822,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
14439
14822
|
|
|
14440
14823
|
\u2026(truncated)` : raw;
|
|
14441
14824
|
}
|
|
14442
|
-
var
|
|
14825
|
+
var import_node_fs40, import_node_os11, import_node_path36;
|
|
14443
14826
|
var init_discover = __esm({
|
|
14444
14827
|
"src/skills/discover.ts"() {
|
|
14445
14828
|
"use strict";
|
|
14446
|
-
|
|
14829
|
+
import_node_fs40 = require("fs");
|
|
14447
14830
|
import_node_os11 = require("os");
|
|
14448
|
-
|
|
14831
|
+
import_node_path36 = require("path");
|
|
14449
14832
|
}
|
|
14450
14833
|
});
|
|
14451
14834
|
|
|
@@ -14536,7 +14919,7 @@ var init_expand = __esm({
|
|
|
14536
14919
|
|
|
14537
14920
|
// src/composer/stage-files.ts
|
|
14538
14921
|
function fileExtension(filePath) {
|
|
14539
|
-
const base = (0,
|
|
14922
|
+
const base = (0, import_node_path37.basename)(filePath).toLowerCase();
|
|
14540
14923
|
return base.includes(".") ? base.split(".").pop() || "" : "";
|
|
14541
14924
|
}
|
|
14542
14925
|
function isImageFilePath(filePath) {
|
|
@@ -14546,22 +14929,22 @@ function imageMimeType(filePath) {
|
|
|
14546
14929
|
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
14547
14930
|
}
|
|
14548
14931
|
function ensureAttachmentsDir(worktreePath) {
|
|
14549
|
-
const dir = (0,
|
|
14550
|
-
(0,
|
|
14551
|
-
const gi = (0,
|
|
14552
|
-
if (!(0,
|
|
14553
|
-
(0,
|
|
14932
|
+
const dir = (0, import_node_path37.join)(worktreePath, ATTACHMENTS_DIR);
|
|
14933
|
+
(0, import_node_fs41.mkdirSync)(dir, { recursive: true });
|
|
14934
|
+
const gi = (0, import_node_path37.join)(dir, ".gitignore");
|
|
14935
|
+
if (!(0, import_node_fs41.existsSync)(gi)) {
|
|
14936
|
+
(0, import_node_fs41.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
|
|
14554
14937
|
}
|
|
14555
14938
|
return dir;
|
|
14556
14939
|
}
|
|
14557
14940
|
function uniqueAttachmentName(dir, originalName) {
|
|
14558
14941
|
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
14559
|
-
if (!(0,
|
|
14560
|
-
const ext = (0,
|
|
14942
|
+
if (!(0, import_node_fs41.existsSync)((0, import_node_path37.join)(dir, safe))) return safe;
|
|
14943
|
+
const ext = (0, import_node_path37.extname)(safe);
|
|
14561
14944
|
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
14562
14945
|
for (let i = 1; i < 1e4; i++) {
|
|
14563
14946
|
const candidate = `${stem}-${i}${ext}`;
|
|
14564
|
-
if (!(0,
|
|
14947
|
+
if (!(0, import_node_fs41.existsSync)((0, import_node_path37.join)(dir, candidate))) return candidate;
|
|
14565
14948
|
}
|
|
14566
14949
|
return `${stem}-${(0, import_node_crypto8.randomUUID)()}${ext}`;
|
|
14567
14950
|
}
|
|
@@ -14613,9 +14996,9 @@ function attachmentFromBuffer(name, buf, opts) {
|
|
|
14613
14996
|
};
|
|
14614
14997
|
}
|
|
14615
14998
|
function attachmentFromAbsolutePath(absolutePath) {
|
|
14616
|
-
const name = (0,
|
|
14999
|
+
const name = (0, import_node_path37.basename)(absolutePath);
|
|
14617
15000
|
try {
|
|
14618
|
-
const st = (0,
|
|
15001
|
+
const st = (0, import_node_fs41.statSync)(absolutePath);
|
|
14619
15002
|
if (!st.isFile()) {
|
|
14620
15003
|
return {
|
|
14621
15004
|
id: (0, import_node_crypto8.randomUUID)(),
|
|
@@ -14624,7 +15007,7 @@ function attachmentFromAbsolutePath(absolutePath) {
|
|
|
14624
15007
|
content: `(not a file: ${absolutePath})`
|
|
14625
15008
|
};
|
|
14626
15009
|
}
|
|
14627
|
-
const buf = (0,
|
|
15010
|
+
const buf = (0, import_node_fs41.readFileSync)(absolutePath);
|
|
14628
15011
|
return attachmentFromBuffer(name, buf, { sourceLabel: absolutePath });
|
|
14629
15012
|
} catch (err) {
|
|
14630
15013
|
return {
|
|
@@ -14640,15 +15023,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
|
14640
15023
|
const dir = ensureAttachmentsDir(worktreePath);
|
|
14641
15024
|
const out = [];
|
|
14642
15025
|
for (const abs of absolutePaths) {
|
|
14643
|
-
const originalName = (0,
|
|
15026
|
+
const originalName = (0, import_node_path37.basename)(abs);
|
|
14644
15027
|
try {
|
|
14645
|
-
const st = (0,
|
|
15028
|
+
const st = (0, import_node_fs41.statSync)(abs);
|
|
14646
15029
|
if (!st.isFile()) continue;
|
|
14647
15030
|
const name = uniqueAttachmentName(dir, originalName);
|
|
14648
|
-
const destAbs = (0,
|
|
14649
|
-
(0,
|
|
15031
|
+
const destAbs = (0, import_node_path37.join)(dir, name);
|
|
15032
|
+
(0, import_node_fs41.copyFileSync)(abs, destAbs);
|
|
14650
15033
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
14651
|
-
const buf = (0,
|
|
15034
|
+
const buf = (0, import_node_fs41.readFileSync)(destAbs);
|
|
14652
15035
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
14653
15036
|
} catch (err) {
|
|
14654
15037
|
out.push({
|
|
@@ -14670,8 +15053,8 @@ function stageBuffersAsAttachments(worktreePath, buffers2) {
|
|
|
14670
15053
|
try {
|
|
14671
15054
|
const buf = Buffer.from(item.dataBase64, "base64");
|
|
14672
15055
|
const name = uniqueAttachmentName(dir, originalName);
|
|
14673
|
-
const destAbs = (0,
|
|
14674
|
-
(0,
|
|
15056
|
+
const destAbs = (0, import_node_path37.join)(dir, name);
|
|
15057
|
+
(0, import_node_fs41.writeFileSync)(destAbs, buf);
|
|
14675
15058
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
14676
15059
|
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
14677
15060
|
} catch (err) {
|
|
@@ -14707,18 +15090,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
14707
15090
|
if (!rel || rel.includes("..") || rel.startsWith("/")) {
|
|
14708
15091
|
out.push({
|
|
14709
15092
|
id: (0, import_node_crypto8.randomUUID)(),
|
|
14710
|
-
name: (0,
|
|
15093
|
+
name: (0, import_node_path37.basename)(rel) || "file",
|
|
14711
15094
|
kind: "file",
|
|
14712
15095
|
content: `(invalid path: ${rel})`
|
|
14713
15096
|
});
|
|
14714
15097
|
continue;
|
|
14715
15098
|
}
|
|
14716
|
-
const name = (0,
|
|
15099
|
+
const name = (0, import_node_path37.basename)(rel);
|
|
14717
15100
|
try {
|
|
14718
|
-
const abs = (0,
|
|
14719
|
-
const st = (0,
|
|
15101
|
+
const abs = (0, import_node_path37.join)(worktreePath, rel);
|
|
15102
|
+
const st = (0, import_node_fs41.statSync)(abs);
|
|
14720
15103
|
if (!st.isFile()) continue;
|
|
14721
|
-
const buf = (0,
|
|
15104
|
+
const buf = (0, import_node_fs41.readFileSync)(abs);
|
|
14722
15105
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
14723
15106
|
} catch (err) {
|
|
14724
15107
|
out.push({
|
|
@@ -14731,12 +15114,12 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
14731
15114
|
}
|
|
14732
15115
|
return out;
|
|
14733
15116
|
}
|
|
14734
|
-
var
|
|
15117
|
+
var import_node_fs41, import_node_path37, import_node_crypto8, IMAGE_EXTENSIONS2, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES;
|
|
14735
15118
|
var init_stage_files = __esm({
|
|
14736
15119
|
"src/composer/stage-files.ts"() {
|
|
14737
15120
|
"use strict";
|
|
14738
|
-
|
|
14739
|
-
|
|
15121
|
+
import_node_fs41 = require("fs");
|
|
15122
|
+
import_node_path37 = require("path");
|
|
14740
15123
|
import_node_crypto8 = require("crypto");
|
|
14741
15124
|
init_workspace_scratch();
|
|
14742
15125
|
IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
@@ -14883,14 +15266,15 @@ function formatArtifactDirective() {
|
|
|
14883
15266
|
return [
|
|
14884
15267
|
"Sideboard side column (desktop UI):",
|
|
14885
15268
|
"claude.ai\u2019s \u201CArtifact\u201D tool does NOT exist in Claude Code. That is expected.",
|
|
15269
|
+
"Do not unprompted-duplicate a payload. Chat markdown (including tables) already renders in the transcript \u2014 do not also call present_schema with those same rows just to display them. If the user asks for an editable / interactive table, call present_schema even if markdown already showed the data. Do not also call present_artifact for a document you already fenced in chat.",
|
|
14886
15270
|
"Documents (HTML/SVG/markdown):",
|
|
14887
15271
|
"1) Emit a fenced code block tagged `html` (preferred), `svg`, or `markdown` with the FULL document \u2014 Sideboard opens a side column. Example:",
|
|
14888
15272
|
"```html",
|
|
14889
15273
|
"<!DOCTYPE html><html><head><title>Demo</title></head><body><h1>Hi</h1></body></html>",
|
|
14890
15274
|
"```",
|
|
14891
|
-
"2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content.",
|
|
15275
|
+
"2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content \u2014 not both a fence and this tool for the same body.",
|
|
14892
15276
|
"CMS / JSON Schema forms & tables (Brightsy or any schema+schemaUi source):",
|
|
14893
|
-
"3) Call Sideboard MCP `present_schema`
|
|
15277
|
+
"3) Call Sideboard MCP `present_schema` when the user needs to filter, edit, publish, or persist rows \u2014 including after you already showed a markdown table, if they then ask for an editable table. If they only need to read the data, a markdown table is enough. When you do call it, pass title, mode (table|form), and either:",
|
|
14894
15278
|
" - datasource=brightsy + resource_id (record type UUID) after fetching types via Brightsy MCP, or",
|
|
14895
15279
|
" - datasource=inline + resource: { id, title, schema, schemaUi } and optional records/record.",
|
|
14896
15280
|
"Files / media browser (CMS file manager column):",
|
|
@@ -14899,11 +15283,11 @@ function formatArtifactDirective() {
|
|
|
14899
15283
|
"Multiple-choice questions:",
|
|
14900
15284
|
"5) Call Sideboard MCP `ask_user` only when work is blocked on choosing among a few concrete options (approach forks, which API, auth vs cookies). First write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it). Include a description on every option. After calling, stop and wait for their next message with answers. If you are asking a real multiple-choice, use ask_user rather than chat bullets so Sideboard shows the composer picker.",
|
|
14901
15285
|
"Do not call ask_user for greetings, check-ins, \u201Chello\u201D, open-ended how-can-I-help, or to invent a menu of possible next tasks \u2014 reply in chat. If one option is the obvious default, proceed without asking.",
|
|
14902
|
-
"Never say artifacts, CMS UI, or the Files column are unavailable.
|
|
15286
|
+
"Never say artifacts, CMS UI, or the Files column are unavailable. present_schema is for interactive list/edit/publish (use it when they ask to edit, even if chat already had a markdown table); present_files for storage UI; html fences for standalone pages; ask_user only for those blocked predefined-option questions."
|
|
14903
15287
|
].join("\n");
|
|
14904
15288
|
}
|
|
14905
15289
|
function formatUiReminder() {
|
|
14906
|
-
return "Sideboard UI: html fence or present_artifact
|
|
15290
|
+
return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. ask_user only for a real multiple-choice (not hellos or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
|
|
14907
15291
|
}
|
|
14908
15292
|
function loadAgentInstructions(worktreePath, agent) {
|
|
14909
15293
|
const candidates = FILES_BY_AGENT[agent] ?? FILES_BY_AGENT.claude;
|
|
@@ -14912,11 +15296,11 @@ function loadAgentInstructions(worktreePath, agent) {
|
|
|
14912
15296
|
const out = [];
|
|
14913
15297
|
for (const rel of candidates) {
|
|
14914
15298
|
if (seenPaths.has(rel)) continue;
|
|
14915
|
-
const abs = (0,
|
|
14916
|
-
if (!(0,
|
|
15299
|
+
const abs = (0, import_node_path38.join)(worktreePath, rel);
|
|
15300
|
+
if (!(0, import_node_fs42.existsSync)(abs)) continue;
|
|
14917
15301
|
try {
|
|
14918
|
-
if (!(0,
|
|
14919
|
-
let content = (0,
|
|
15302
|
+
if (!(0, import_node_fs42.statSync)(abs).isFile()) continue;
|
|
15303
|
+
let content = (0, import_node_fs42.readFileSync)(abs, "utf8");
|
|
14920
15304
|
if (!content.trim()) continue;
|
|
14921
15305
|
if (content.length > MAX_CHARS_PER_FILE) {
|
|
14922
15306
|
content = `${content.slice(0, MAX_CHARS_PER_FILE)}
|
|
@@ -14956,12 +15340,12 @@ function withAgentInstructions(prompt, files) {
|
|
|
14956
15340
|
|
|
14957
15341
|
${prompt}`;
|
|
14958
15342
|
}
|
|
14959
|
-
var
|
|
15343
|
+
var import_node_fs42, import_node_path38, FILES_BY_AGENT, MAX_CHARS_PER_FILE;
|
|
14960
15344
|
var init_instructions = __esm({
|
|
14961
15345
|
"src/agents/instructions.ts"() {
|
|
14962
15346
|
"use strict";
|
|
14963
|
-
|
|
14964
|
-
|
|
15347
|
+
import_node_fs42 = require("fs");
|
|
15348
|
+
import_node_path38 = require("path");
|
|
14965
15349
|
init_git_auth_mode();
|
|
14966
15350
|
init_worktree_labels();
|
|
14967
15351
|
FILES_BY_AGENT = {
|
|
@@ -15051,40 +15435,40 @@ __export(plan_file_exports, {
|
|
|
15051
15435
|
writePlanFile: () => writePlanFile
|
|
15052
15436
|
});
|
|
15053
15437
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
15054
|
-
const gitignoreAbs = (0,
|
|
15055
|
-
if ((0,
|
|
15056
|
-
(0,
|
|
15057
|
-
(0,
|
|
15438
|
+
const gitignoreAbs = (0, import_node_path39.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
15439
|
+
if ((0, import_node_fs43.existsSync)(gitignoreAbs)) return;
|
|
15440
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path39.dirname)(gitignoreAbs), { recursive: true });
|
|
15441
|
+
(0, import_node_fs43.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
15058
15442
|
}
|
|
15059
15443
|
function planFileAbs(worktreePath) {
|
|
15060
|
-
return (0,
|
|
15444
|
+
return (0, import_node_path39.join)(worktreePath, PLAN_FILE_REL);
|
|
15061
15445
|
}
|
|
15062
15446
|
function readTextIfPresent2(abs) {
|
|
15063
|
-
if (!(0,
|
|
15447
|
+
if (!(0, import_node_fs43.existsSync)(abs)) return null;
|
|
15064
15448
|
try {
|
|
15065
|
-
const content = (0,
|
|
15449
|
+
const content = (0, import_node_fs43.readFileSync)(abs, "utf8");
|
|
15066
15450
|
return content.trim() ? content : null;
|
|
15067
15451
|
} catch {
|
|
15068
15452
|
return null;
|
|
15069
15453
|
}
|
|
15070
15454
|
}
|
|
15071
15455
|
function readPlanFile(worktreePath) {
|
|
15072
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
15456
|
+
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
15457
|
}
|
|
15074
15458
|
function writePlanFile(worktreePath, content) {
|
|
15075
15459
|
ensureAttachmentsGitignore(worktreePath);
|
|
15076
15460
|
const abs = planFileAbs(worktreePath);
|
|
15077
|
-
(0,
|
|
15461
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path39.dirname)(abs), { recursive: true });
|
|
15078
15462
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
15079
|
-
(0,
|
|
15463
|
+
(0, import_node_fs43.writeFileSync)(abs, body, "utf8");
|
|
15080
15464
|
return PLAN_FILE_REL;
|
|
15081
15465
|
}
|
|
15082
|
-
var
|
|
15466
|
+
var import_node_fs43, import_node_path39;
|
|
15083
15467
|
var init_plan_file = __esm({
|
|
15084
15468
|
"src/plan/plan-file.ts"() {
|
|
15085
15469
|
"use strict";
|
|
15086
|
-
|
|
15087
|
-
|
|
15470
|
+
import_node_fs43 = require("fs");
|
|
15471
|
+
import_node_path39 = require("path");
|
|
15088
15472
|
init_workspace_scratch();
|
|
15089
15473
|
init_plan_present();
|
|
15090
15474
|
init_plan_present();
|
|
@@ -15138,10 +15522,10 @@ __export(cursor_recover_exports, {
|
|
|
15138
15522
|
function recoverFinishedCursorRun(opts) {
|
|
15139
15523
|
const agentId = opts.agentId.trim();
|
|
15140
15524
|
if (!agentId) return null;
|
|
15141
|
-
const runsPath = (0,
|
|
15142
|
-
if (!(0,
|
|
15525
|
+
const runsPath = (0, import_node_path40.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
|
|
15526
|
+
if (!(0, import_node_fs44.existsSync)(runsPath)) return null;
|
|
15143
15527
|
try {
|
|
15144
|
-
const lines = (0,
|
|
15528
|
+
const lines = (0, import_node_fs44.readFileSync)(runsPath, "utf8").split("\n");
|
|
15145
15529
|
let best = null;
|
|
15146
15530
|
for (const line of lines) {
|
|
15147
15531
|
const trimmed = line.trim();
|
|
@@ -15167,12 +15551,12 @@ function recoverFinishedCursorRun(opts) {
|
|
|
15167
15551
|
return null;
|
|
15168
15552
|
}
|
|
15169
15553
|
}
|
|
15170
|
-
var
|
|
15554
|
+
var import_node_fs44, import_node_path40;
|
|
15171
15555
|
var init_cursor_recover = __esm({
|
|
15172
15556
|
"src/agents/cursor-recover.ts"() {
|
|
15173
15557
|
"use strict";
|
|
15174
|
-
|
|
15175
|
-
|
|
15558
|
+
import_node_fs44 = require("fs");
|
|
15559
|
+
import_node_path40 = require("path");
|
|
15176
15560
|
init_paths();
|
|
15177
15561
|
}
|
|
15178
15562
|
});
|
|
@@ -15303,14 +15687,16 @@ async function startOrchestration(opts) {
|
|
|
15303
15687
|
}
|
|
15304
15688
|
return updated;
|
|
15305
15689
|
}
|
|
15306
|
-
var import_node_events,
|
|
15690
|
+
var import_node_events, import_node_fs45, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
|
|
15307
15691
|
var init_orchestrator = __esm({
|
|
15308
15692
|
"src/orchestrator/orchestrator.ts"() {
|
|
15309
15693
|
"use strict";
|
|
15310
15694
|
import_node_events = require("events");
|
|
15311
15695
|
init_outbound_watch();
|
|
15312
|
-
|
|
15696
|
+
import_node_fs45 = require("fs");
|
|
15313
15697
|
init_error_detail();
|
|
15698
|
+
init_run();
|
|
15699
|
+
init_stale_lock();
|
|
15314
15700
|
init_spawn();
|
|
15315
15701
|
init_agents();
|
|
15316
15702
|
init_worktree();
|
|
@@ -15426,7 +15812,7 @@ var init_orchestrator = __esm({
|
|
|
15426
15812
|
}
|
|
15427
15813
|
continue;
|
|
15428
15814
|
}
|
|
15429
|
-
if (!(0,
|
|
15815
|
+
if (!(0, import_node_fs45.existsSync)(thread.worktreePath)) {
|
|
15430
15816
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
15431
15817
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
15432
15818
|
continue;
|
|
@@ -16019,7 +16405,15 @@ var init_orchestrator = __esm({
|
|
|
16019
16405
|
hasSession: Boolean(this.requireThread(threadId).sessionId)
|
|
16020
16406
|
})) {
|
|
16021
16407
|
updateThread(threadId, { sessionId: null });
|
|
16022
|
-
|
|
16408
|
+
try {
|
|
16409
|
+
const gitDirs = await resolveGitDirsForLockRecovery(thread.worktreePath);
|
|
16410
|
+
const clearedLocks = clearStaleIndexLocks(gitDirs, 2e3);
|
|
16411
|
+
if (clearedLocks.length > 0) {
|
|
16412
|
+
pushTurnStderr(stderrTail, "Cleared a stale git lock left by the crashed agent process");
|
|
16413
|
+
}
|
|
16414
|
+
} catch {
|
|
16415
|
+
}
|
|
16416
|
+
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
16417
|
pushTurnStderr(stderrTail, retryNote);
|
|
16024
16418
|
this.emit({
|
|
16025
16419
|
type: "turn_output",
|
|
@@ -16491,13 +16885,14 @@ var init_orchestrator = __esm({
|
|
|
16491
16885
|
const text4 = (lastAgent?.text ?? "").trim() || (thread.status === "error" ? lastError ?? "" : "");
|
|
16492
16886
|
const stillRunning = thread.status === "running" || thread.status === "queued";
|
|
16493
16887
|
const live = stillRunning ? readTurnLive(thread.id) : null;
|
|
16888
|
+
const queuedHint = thread.status === "queued" && !live?.summary ? "Queued \u2014 waiting for a concurrency slot" : null;
|
|
16494
16889
|
return {
|
|
16495
16890
|
text: text4,
|
|
16496
16891
|
status: thread.status,
|
|
16497
16892
|
sessionId: thread.sessionId,
|
|
16498
16893
|
lastError,
|
|
16499
16894
|
stillRunning,
|
|
16500
|
-
progress: live?.summary ??
|
|
16895
|
+
progress: live?.summary ?? queuedHint,
|
|
16501
16896
|
lastActivityAt: live?.updatedAt ?? null
|
|
16502
16897
|
};
|
|
16503
16898
|
}
|
|
@@ -17014,7 +17409,7 @@ var init_orchestrator = __esm({
|
|
|
17014
17409
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
17015
17410
|
return restored2;
|
|
17016
17411
|
}
|
|
17017
|
-
if (!(0,
|
|
17412
|
+
if (!(0, import_node_fs45.existsSync)(thread.worktreePath)) {
|
|
17018
17413
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
17019
17414
|
throw new Error(
|
|
17020
17415
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -17216,6 +17611,7 @@ var init_schedule_runner = __esm({
|
|
|
17216
17611
|
var index_exports = {};
|
|
17217
17612
|
__export(index_exports, {
|
|
17218
17613
|
AGENT_GIT_ACTIONS: () => AGENT_GIT_ACTIONS,
|
|
17614
|
+
AGENT_RUNNER_MAX_OLD_SPACE_MB: () => AGENT_RUNNER_MAX_OLD_SPACE_MB,
|
|
17219
17615
|
ATTACHMENTS_DIR: () => ATTACHMENTS_DIR,
|
|
17220
17616
|
BAKED_SLACK_RELAY_URL: () => BAKED_SLACK_RELAY_URL,
|
|
17221
17617
|
BRIGHTSY_MCP_ALLOWED_TOOLS: () => BRIGHTSY_MCP_ALLOWED_TOOLS,
|
|
@@ -17291,6 +17687,7 @@ __export(index_exports, {
|
|
|
17291
17687
|
appendIndexedGitConfig: () => appendIndexedGitConfig,
|
|
17292
17688
|
appendMessage: () => appendMessage,
|
|
17293
17689
|
applyAgentEvent: () => applyAgentEvent,
|
|
17690
|
+
applyAgentRunnerHeapEnv: () => applyAgentRunnerHeapEnv,
|
|
17294
17691
|
applyAppEnvironment: () => applyAppEnvironment,
|
|
17295
17692
|
applyCompaction: () => applyCompaction,
|
|
17296
17693
|
applyGithubGitAuthEnv: () => applyGithubGitAuthEnv,
|
|
@@ -17524,10 +17921,12 @@ __export(index_exports, {
|
|
|
17524
17921
|
isOrchestratorThread: () => isOrchestratorThread,
|
|
17525
17922
|
isPidAlive: () => isPidAlive,
|
|
17526
17923
|
isPlaceholderBranch: () => isPlaceholderBranch,
|
|
17924
|
+
isPollWrapperToolName: () => isPollWrapperToolName,
|
|
17527
17925
|
isPrNotMergeableError: () => isPrNotMergeableError,
|
|
17528
17926
|
isPresentPlanToolName: () => isPresentPlanToolName,
|
|
17529
17927
|
isPrimaryCheckoutThread: () => isPrimaryCheckoutThread,
|
|
17530
17928
|
isSessionQuotaLimit: () => isSessionQuotaLimit,
|
|
17929
|
+
isShellToolName: () => isShellToolName,
|
|
17531
17930
|
isSideboardScratchPath: () => isSideboardScratchPath,
|
|
17532
17931
|
isSlackCoordinatorThread: () => isSlackCoordinatorThread,
|
|
17533
17932
|
isSlackExternalReplyPrompt: () => isSlackExternalReplyPrompt,
|
|
@@ -17569,6 +17968,7 @@ __export(index_exports, {
|
|
|
17569
17968
|
listWorkspaces: () => listWorkspaces,
|
|
17570
17969
|
listWorktreeFiles: () => listWorktreeFiles,
|
|
17571
17970
|
listWorktrees: () => listWorktrees,
|
|
17971
|
+
liveActivitySummary: () => liveActivitySummary,
|
|
17572
17972
|
loadAgentInstructions: () => loadAgentInstructions,
|
|
17573
17973
|
loadAppSettings: () => loadAppSettings,
|
|
17574
17974
|
loadBrightsyConfig: () => loadBrightsyConfig,
|
|
@@ -17662,6 +18062,7 @@ __export(index_exports, {
|
|
|
17662
18062
|
resolveEffectiveIssueSource: () => resolveEffectiveIssueSource,
|
|
17663
18063
|
resolveFilesToCopy: () => resolveFilesToCopy,
|
|
17664
18064
|
resolveGhAuthToken: () => resolveGhAuthToken,
|
|
18065
|
+
resolveGitDirsForLockRecovery: () => resolveGitDirsForLockRecovery,
|
|
17665
18066
|
resolveGithubAgentToken: () => resolveGithubAgentToken,
|
|
17666
18067
|
resolveGithubRepoSlug: () => resolveGithubRepoSlug,
|
|
17667
18068
|
resolveLinearState: () => resolveLinearState,
|
|
@@ -17755,6 +18156,7 @@ __export(index_exports, {
|
|
|
17755
18156
|
threadsDir: () => threadsDir,
|
|
17756
18157
|
threadsSharingWorktree: () => threadsSharingWorktree,
|
|
17757
18158
|
toPublicAppSettings: () => toPublicAppSettings,
|
|
18159
|
+
toolActivityLine: () => toolActivityLine,
|
|
17758
18160
|
toolDescription: () => toolDescription,
|
|
17759
18161
|
toolDetail: () => toolDetail,
|
|
17760
18162
|
toolFilePath: () => toolFilePath,
|
|
@@ -17780,6 +18182,7 @@ __export(index_exports, {
|
|
|
17780
18182
|
withEventParentId: () => withEventParentId,
|
|
17781
18183
|
withEventsParentId: () => withEventsParentId,
|
|
17782
18184
|
withExportedPath: () => withExportedPath,
|
|
18185
|
+
withMaxOldSpaceSize: () => withMaxOldSpaceSize,
|
|
17783
18186
|
withThreadLock: () => withThreadLock,
|
|
17784
18187
|
workspaceSettingsSourceLabel: () => workspaceSettingsSourceLabel,
|
|
17785
18188
|
worktreeCleanupSettings: () => worktreeCleanupSettings,
|
|
@@ -18751,7 +19154,7 @@ init_orphan_cleanup();
|
|
|
18751
19154
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
18752
19155
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
18753
19156
|
var import_zod4 = require("zod");
|
|
18754
|
-
var
|
|
19157
|
+
var import_node_path41 = require("path");
|
|
18755
19158
|
init_orchestrator();
|
|
18756
19159
|
init_worktree();
|
|
18757
19160
|
init_create();
|
|
@@ -18778,6 +19181,10 @@ function mcpWaitForTurnTimeoutMs(requested) {
|
|
|
18778
19181
|
return Math.min(Math.max(1e3, Math.floor(n)), MCP_WAIT_FOR_TURN_MAX_MS);
|
|
18779
19182
|
}
|
|
18780
19183
|
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.";
|
|
19184
|
+
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.";
|
|
19185
|
+
function mcpWaitStillRunningHint(status) {
|
|
19186
|
+
return status === "queued" ? MCP_WAIT_QUEUED_HINT : MCP_WAIT_STILL_RUNNING_HINT;
|
|
19187
|
+
}
|
|
18781
19188
|
|
|
18782
19189
|
// src/mcp/server.ts
|
|
18783
19190
|
init_turn_live();
|
|
@@ -19624,7 +20031,7 @@ async function startMcpServer() {
|
|
|
19624
20031
|
async () => {
|
|
19625
20032
|
const threads = orch.getThreads(true);
|
|
19626
20033
|
const lines = threads.map((t) => {
|
|
19627
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
20034
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path41.basename)(t.repoPath) || t.repoPath;
|
|
19628
20035
|
const live = t.status === "running" || t.status === "queued" ? readTurnLive(t.id) : null;
|
|
19629
20036
|
const progress = live?.summary ? ` ${live.summary}` : "";
|
|
19630
20037
|
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 +20067,7 @@ async function startMcpServer() {
|
|
|
19660
20067
|
prUrl: t.prUrl,
|
|
19661
20068
|
lastError: t.lastError ?? null,
|
|
19662
20069
|
stillRunning: t.status === "running" || t.status === "queued",
|
|
19663
|
-
progress: live?.summary ?? null,
|
|
20070
|
+
progress: live?.summary ?? (t.status === "queued" ? "Queued \u2014 waiting for a concurrency slot" : null),
|
|
19664
20071
|
lastActivityAt: live?.updatedAt ?? null
|
|
19665
20072
|
};
|
|
19666
20073
|
return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
|
|
@@ -19669,7 +20076,7 @@ async function startMcpServer() {
|
|
|
19669
20076
|
}
|
|
19670
20077
|
server.tool(
|
|
19671
20078
|
"present_artifact",
|
|
19672
|
-
"Show an HTML, SVG, markdown, or React document in Sideboard\u2019s Claude-style side column (desktop). Use instead of claude.ai\u2019s artifact tool \u2014 pass the full document content. Prefer type=html for interactive pages. For type=react, pass a single component module that `export default`s a component (JSX/TSX ok) \u2014 Sideboard bootstraps React/ReactDOM/Babel and renders it; only `react`/`react-dom` imports are available, no other npm packages.",
|
|
20079
|
+
"Show an HTML, SVG, markdown, or React document in Sideboard\u2019s Claude-style side column (desktop). Use instead of claude.ai\u2019s artifact tool \u2014 pass the full document content. Do not also emit the same document as a chat html/markdown fence. Prefer type=html for interactive pages. For type=react, pass a single component module that `export default`s a component (JSX/TSX ok) \u2014 Sideboard bootstraps React/ReactDOM/Babel and renders it; only `react`/`react-dom` imports are available, no other npm packages.",
|
|
19673
20080
|
{
|
|
19674
20081
|
title: import_zod4.z.string().describe("Short title shown in the artifact pane header"),
|
|
19675
20082
|
type: import_zod4.z.enum(["html", "svg", "markdown", "react"]).describe(
|
|
@@ -19746,7 +20153,7 @@ async function startMcpServer() {
|
|
|
19746
20153
|
);
|
|
19747
20154
|
server.tool(
|
|
19748
20155
|
"present_schema",
|
|
19749
|
-
"Open Sideboard\u2019s schema-driven side column (filterable table and/or form). Pass JSON Schema + optional schemaUi. Prefer datasource=inline with embedded resource/records. Use datasource=brightsy with resource_id only when the user is logged into Brightsy.",
|
|
20156
|
+
"Open Sideboard\u2019s schema-driven side column (filterable table and/or form) when the user needs to filter, edit, publish, or persist records. Do not call this just to re-display rows you already wrote as a markdown table. If the user asks for an editable / interactive table, call this even if chat already showed those rows. Pass JSON Schema + optional schemaUi. Prefer datasource=inline with embedded resource/records. Use datasource=brightsy with resource_id only when the user is logged into Brightsy.",
|
|
19750
20157
|
{
|
|
19751
20158
|
title: import_zod4.z.string().describe("Pane title"),
|
|
19752
20159
|
mode: import_zod4.z.enum(["table", "form"]).optional().describe("table = list/filter records; form = edit one record"),
|
|
@@ -19994,7 +20401,7 @@ async function startMcpServer() {
|
|
|
19994
20401
|
);
|
|
19995
20402
|
server.tool(
|
|
19996
20403
|
"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 \
|
|
20404
|
+
"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
20405
|
{
|
|
19999
20406
|
ref: import_zod4.z.string(),
|
|
20000
20407
|
timeoutMs: import_zod4.z.number().optional()
|
|
@@ -20016,7 +20423,7 @@ async function startMcpServer() {
|
|
|
20016
20423
|
stillRunning: result.stillRunning,
|
|
20017
20424
|
progress: result.progress,
|
|
20018
20425
|
lastActivityAt: result.lastActivityAt,
|
|
20019
|
-
hint: result.stillRunning ?
|
|
20426
|
+
hint: result.stillRunning ? mcpWaitStillRunningHint(result.status) : void 0
|
|
20020
20427
|
})
|
|
20021
20428
|
}
|
|
20022
20429
|
]
|
|
@@ -20035,7 +20442,7 @@ async function startMcpServer() {
|
|
|
20035
20442
|
type: "text",
|
|
20036
20443
|
text: JSON.stringify({
|
|
20037
20444
|
...result,
|
|
20038
|
-
hint: result.stillRunning ?
|
|
20445
|
+
hint: result.stillRunning ? mcpWaitStillRunningHint(result.status) : void 0
|
|
20039
20446
|
})
|
|
20040
20447
|
}
|
|
20041
20448
|
]
|
|
@@ -20964,16 +21371,16 @@ init_connected_teams();
|
|
|
20964
21371
|
init_injected_mcp();
|
|
20965
21372
|
|
|
20966
21373
|
// src/agents/user-mcp-config.ts
|
|
20967
|
-
var
|
|
21374
|
+
var import_node_fs46 = require("fs");
|
|
20968
21375
|
var import_node_os12 = require("os");
|
|
20969
|
-
var
|
|
21376
|
+
var import_node_path42 = require("path");
|
|
20970
21377
|
init_paths();
|
|
20971
21378
|
init_injected_mcp();
|
|
20972
21379
|
function userCursorMcpConfigPath() {
|
|
20973
|
-
return (0,
|
|
21380
|
+
return (0, import_node_path42.join)((0, import_node_os12.homedir)(), ".cursor", "mcp.json");
|
|
20974
21381
|
}
|
|
20975
21382
|
function userClaudeMcpConfigPath() {
|
|
20976
|
-
return (0,
|
|
21383
|
+
return (0, import_node_path42.join)((0, import_node_os12.homedir)(), ".claude.json");
|
|
20977
21384
|
}
|
|
20978
21385
|
function asObject(value) {
|
|
20979
21386
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
@@ -21000,16 +21407,16 @@ function mergeSideboardIntoMcpServersJson(existing, sideboard) {
|
|
|
21000
21407
|
}
|
|
21001
21408
|
function writeMergedMcpServersJson(configPath, sideboard) {
|
|
21002
21409
|
let existing = {};
|
|
21003
|
-
if ((0,
|
|
21410
|
+
if ((0, import_node_fs46.existsSync)(configPath)) {
|
|
21004
21411
|
try {
|
|
21005
|
-
existing = JSON.parse((0,
|
|
21412
|
+
existing = JSON.parse((0, import_node_fs46.readFileSync)(configPath, "utf8"));
|
|
21006
21413
|
} catch {
|
|
21007
21414
|
existing = {};
|
|
21008
21415
|
}
|
|
21009
21416
|
}
|
|
21010
21417
|
const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
|
|
21011
|
-
(0,
|
|
21012
|
-
(0,
|
|
21418
|
+
(0, import_node_fs46.mkdirSync)((0, import_node_path42.dirname)(configPath), { recursive: true });
|
|
21419
|
+
(0, import_node_fs46.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
|
|
21013
21420
|
`);
|
|
21014
21421
|
}
|
|
21015
21422
|
function launchFromResolved(server) {
|
|
@@ -21027,7 +21434,7 @@ async function registerPackagedUserMcpClients() {
|
|
|
21027
21434
|
const cursor = userCursorMcpConfigPath();
|
|
21028
21435
|
writeMergedMcpServersJson(cursor, launch);
|
|
21029
21436
|
const claude = userClaudeMcpConfigPath();
|
|
21030
|
-
if ((0,
|
|
21437
|
+
if ((0, import_node_fs46.existsSync)(claude)) {
|
|
21031
21438
|
writeMergedMcpServersJson(claude, launch);
|
|
21032
21439
|
return { cursor, claude };
|
|
21033
21440
|
}
|
|
@@ -22657,9 +23064,9 @@ var import_node_http3 = require("http");
|
|
|
22657
23064
|
var import_ws3 = require("ws");
|
|
22658
23065
|
|
|
22659
23066
|
// src/slack/relay-static.ts
|
|
22660
|
-
var
|
|
23067
|
+
var import_node_fs47 = require("fs");
|
|
22661
23068
|
var import_promises = require("fs/promises");
|
|
22662
|
-
var
|
|
23069
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
22663
23070
|
var TYPES = {
|
|
22664
23071
|
".css": "text/css; charset=utf-8",
|
|
22665
23072
|
".html": "text/html; charset=utf-8",
|
|
@@ -22690,9 +23097,9 @@ function resolveStaticPath(root, requestUrl) {
|
|
|
22690
23097
|
return null;
|
|
22691
23098
|
}
|
|
22692
23099
|
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
22693
|
-
const rootResolved =
|
|
22694
|
-
const candidate =
|
|
22695
|
-
if (candidate !== rootResolved && !candidate.startsWith(rootResolved +
|
|
23100
|
+
const rootResolved = import_node_path43.default.resolve(root);
|
|
23101
|
+
const candidate = import_node_path43.default.resolve(rootResolved, `.${pathname}`);
|
|
23102
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path43.default.sep)) {
|
|
22696
23103
|
return null;
|
|
22697
23104
|
}
|
|
22698
23105
|
return candidate;
|
|
@@ -22706,7 +23113,7 @@ async function fileSize(file) {
|
|
|
22706
23113
|
}
|
|
22707
23114
|
}
|
|
22708
23115
|
function sendFile(req, res, file, size) {
|
|
22709
|
-
const ext =
|
|
23116
|
+
const ext = import_node_path43.default.extname(file).toLowerCase();
|
|
22710
23117
|
res.writeHead(200, {
|
|
22711
23118
|
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
22712
23119
|
"Content-Length": size,
|
|
@@ -22716,7 +23123,7 @@ function sendFile(req, res, file, size) {
|
|
|
22716
23123
|
res.end();
|
|
22717
23124
|
return true;
|
|
22718
23125
|
}
|
|
22719
|
-
(0,
|
|
23126
|
+
(0, import_node_fs47.createReadStream)(file).pipe(res);
|
|
22720
23127
|
return true;
|
|
22721
23128
|
}
|
|
22722
23129
|
async function tryServeStatic(req, res, root) {
|
|
@@ -22725,7 +23132,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
22725
23132
|
if (!candidate) return false;
|
|
22726
23133
|
const direct = await fileSize(candidate);
|
|
22727
23134
|
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
22728
|
-
const asIndex =
|
|
23135
|
+
const asIndex = import_node_path43.default.join(candidate, "index.html");
|
|
22729
23136
|
const indexSize = await fileSize(asIndex);
|
|
22730
23137
|
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
22731
23138
|
return false;
|
|
@@ -22961,6 +23368,7 @@ init_outbound_watch();
|
|
|
22961
23368
|
// Annotate the CommonJS export names for ESM import in node:
|
|
22962
23369
|
0 && (module.exports = {
|
|
22963
23370
|
AGENT_GIT_ACTIONS,
|
|
23371
|
+
AGENT_RUNNER_MAX_OLD_SPACE_MB,
|
|
22964
23372
|
ATTACHMENTS_DIR,
|
|
22965
23373
|
BAKED_SLACK_RELAY_URL,
|
|
22966
23374
|
BRIGHTSY_MCP_ALLOWED_TOOLS,
|
|
@@ -23036,6 +23444,7 @@ init_outbound_watch();
|
|
|
23036
23444
|
appendIndexedGitConfig,
|
|
23037
23445
|
appendMessage,
|
|
23038
23446
|
applyAgentEvent,
|
|
23447
|
+
applyAgentRunnerHeapEnv,
|
|
23039
23448
|
applyAppEnvironment,
|
|
23040
23449
|
applyCompaction,
|
|
23041
23450
|
applyGithubGitAuthEnv,
|
|
@@ -23269,10 +23678,12 @@ init_outbound_watch();
|
|
|
23269
23678
|
isOrchestratorThread,
|
|
23270
23679
|
isPidAlive,
|
|
23271
23680
|
isPlaceholderBranch,
|
|
23681
|
+
isPollWrapperToolName,
|
|
23272
23682
|
isPrNotMergeableError,
|
|
23273
23683
|
isPresentPlanToolName,
|
|
23274
23684
|
isPrimaryCheckoutThread,
|
|
23275
23685
|
isSessionQuotaLimit,
|
|
23686
|
+
isShellToolName,
|
|
23276
23687
|
isSideboardScratchPath,
|
|
23277
23688
|
isSlackCoordinatorThread,
|
|
23278
23689
|
isSlackExternalReplyPrompt,
|
|
@@ -23314,6 +23725,7 @@ init_outbound_watch();
|
|
|
23314
23725
|
listWorkspaces,
|
|
23315
23726
|
listWorktreeFiles,
|
|
23316
23727
|
listWorktrees,
|
|
23728
|
+
liveActivitySummary,
|
|
23317
23729
|
loadAgentInstructions,
|
|
23318
23730
|
loadAppSettings,
|
|
23319
23731
|
loadBrightsyConfig,
|
|
@@ -23407,6 +23819,7 @@ init_outbound_watch();
|
|
|
23407
23819
|
resolveEffectiveIssueSource,
|
|
23408
23820
|
resolveFilesToCopy,
|
|
23409
23821
|
resolveGhAuthToken,
|
|
23822
|
+
resolveGitDirsForLockRecovery,
|
|
23410
23823
|
resolveGithubAgentToken,
|
|
23411
23824
|
resolveGithubRepoSlug,
|
|
23412
23825
|
resolveLinearState,
|
|
@@ -23500,6 +23913,7 @@ init_outbound_watch();
|
|
|
23500
23913
|
threadsDir,
|
|
23501
23914
|
threadsSharingWorktree,
|
|
23502
23915
|
toPublicAppSettings,
|
|
23916
|
+
toolActivityLine,
|
|
23503
23917
|
toolDescription,
|
|
23504
23918
|
toolDetail,
|
|
23505
23919
|
toolFilePath,
|
|
@@ -23525,6 +23939,7 @@ init_outbound_watch();
|
|
|
23525
23939
|
withEventParentId,
|
|
23526
23940
|
withEventsParentId,
|
|
23527
23941
|
withExportedPath,
|
|
23942
|
+
withMaxOldSpaceSize,
|
|
23528
23943
|
withThreadLock,
|
|
23529
23944
|
workspaceSettingsSourceLabel,
|
|
23530
23945
|
worktreeCleanupSettings,
|