@sideboard-ai/core 0.1.109 → 0.1.111
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 +90 -15
- package/dist/agents/cursor-runner.js +37 -11
- package/dist/{agents-XB332VUJ.js → agents-GH3FWDW2.js} +6 -6
- package/dist/{agents-YIMHDI46.js → agents-NN22A4G5.js} +7 -7
- package/dist/{app-settings-EBCVMFF6.js → app-settings-5XAGNDX7.js} +3 -1
- package/dist/{app-settings-IYSSVZHH.js → app-settings-J4LUWIRN.js} +3 -1
- package/dist/{chunk-WD2TARQS.js → chunk-363Z34PY.js} +72 -12
- package/dist/{chunk-756EO4GK.js → chunk-4EWPKYOU.js} +4 -4
- package/dist/{chunk-4LKD3PGO.js → chunk-4NR5FL46.js} +10 -0
- package/dist/{chunk-FBV6NK62.js → chunk-7KWYXGIU.js} +2 -2
- package/dist/{chunk-KGSVLZV6.js → chunk-A4VZXJEJ.js} +2 -0
- package/dist/{chunk-VRTKGKUW.js → chunk-AROMOP3C.js} +2 -2
- package/dist/{chunk-EW7COXYE.js → chunk-C4KHDW3U.js} +2 -2
- package/dist/{chunk-Q6B3NRCT.js → chunk-DMJKOFTO.js} +159 -288
- package/dist/{chunk-LTPX5N6K.js → chunk-JTQQPJAU.js} +167 -277
- package/dist/{chunk-I2OJ2YSP.js → chunk-KQBI5HNT.js} +2 -2
- package/dist/{chunk-AY2EQI2P.js → chunk-KVFNTWFG.js} +506 -60
- package/dist/{chunk-P3BQ5DOL.js → chunk-KYOTBZ6S.js} +2 -0
- package/dist/{chunk-KKHDPV45.js → chunk-NC3U42ZP.js} +473 -37
- package/dist/{chunk-NE4TOOKS.js → chunk-SGEVS5SY.js} +10 -0
- package/dist/{chunk-TROJ3PVH.js → chunk-VOD3HFLP.js} +4 -4
- package/dist/{chunk-MMI4RJ5I.js → chunk-WIHKHR5R.js} +14 -3
- package/dist/{chunk-OQDIYVDD.js → chunk-YFAXVUY2.js} +2 -2
- package/dist/{chunk-JVIW55KT.js → chunk-YXDR43ZC.js} +2 -2
- package/dist/{coordinator-prompt-JKOU6BWV.js → coordinator-prompt-AR66L3N4.js} +4 -4
- package/dist/{coordinator-prompt-V66BYTUV.js → coordinator-prompt-BHMLWL64.js} +4 -4
- package/dist/{global-workspace-WBQWQQQY.js → global-workspace-SKFODUQQ.js} +5 -5
- package/dist/{global-workspace-NCTBE7G7.js → global-workspace-XSUFEIAQ.js} +5 -5
- package/dist/index.cjs +880 -512
- package/dist/index.d.cts +51 -3
- package/dist/index.d.ts +51 -3
- package/dist/index.js +44 -23
- package/dist/mcp/run-stdio.cjs +858 -511
- package/dist/mcp/run-stdio.js +17 -12
- package/dist/{orchestrator-JVGVPKLI.js → orchestrator-4T2SXDZ7.js} +8 -8
- package/dist/{orchestrator-6W7EKSPO.js → orchestrator-EP57AB5W.js} +10 -10
- package/dist/{thread-store-DQJGDKIJ.js → thread-store-LPTBVW5C.js} +1 -1
- package/dist/{thread-store-4OUEQ2DB.js → thread-store-OEALWU7Y.js} +1 -1
- package/dist/{workspaces-SUBEDSGB.js → workspaces-HV3J4TTW.js} +6 -6
- package/dist/{workspaces-I3554R3F.js → workspaces-XAQVKTLO.js} +6 -6
- package/dist/{worktree-7H6HB6GW.js → worktree-N2EV24EE.js} +3 -3
- package/dist/{worktree-2UWO7VEK.js → worktree-XFJED3VU.js} +3 -3
- package/package.json +1 -1
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -702,6 +702,7 @@ function normalizeThread(raw) {
|
|
|
702
702
|
prTitle: raw.prTitle ?? null,
|
|
703
703
|
prState: raw.prState ?? null,
|
|
704
704
|
skipAutoArchiveOnMerge: Boolean(raw.skipAutoArchiveOnMerge),
|
|
705
|
+
cowboy: Boolean(raw.cowboy),
|
|
705
706
|
stackId: raw.stackId ?? null,
|
|
706
707
|
stackLayer: raw.stackLayer ?? null,
|
|
707
708
|
userSetTitle: Boolean(raw.userSetTitle),
|
|
@@ -730,6 +731,7 @@ function createEmptyThread(partial) {
|
|
|
730
731
|
prTitle: partial.prTitle ?? null,
|
|
731
732
|
prState: partial.prState ?? null,
|
|
732
733
|
skipAutoArchiveOnMerge: partial.skipAutoArchiveOnMerge ?? false,
|
|
734
|
+
cowboy: Boolean(partial.cowboy),
|
|
733
735
|
stackId: partial.stackId ?? null,
|
|
734
736
|
stackLayer: partial.stackLayer ?? null,
|
|
735
737
|
userSetTitle: partial.userSetTitle ?? false,
|
|
@@ -1417,7 +1419,7 @@ function extractJsonErrorMessage(obj) {
|
|
|
1417
1419
|
}
|
|
1418
1420
|
function isPinnedStderrLine(line) {
|
|
1419
1421
|
if (/^\s*at\s/.test(line)) return false;
|
|
1420
|
-
return /cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|cursor startup failed
|
|
1422
|
+
return /cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|cursor startup failed:|FATAL ERROR|heap out of memory|javascript heap|OOMErrorHandler|FatalProcessOutOfMemory/i.test(
|
|
1421
1423
|
line
|
|
1422
1424
|
);
|
|
1423
1425
|
}
|
|
@@ -1440,12 +1442,17 @@ function looksLikeMinifiedJsDump(line) {
|
|
|
1440
1442
|
function looksLikeNestedElectronCrash(line) {
|
|
1441
1443
|
return /HasCustomHostObject|ElectronInitializeICUandStartNode/i.test(line);
|
|
1442
1444
|
}
|
|
1443
|
-
function
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1445
|
+
function looksLikeNativeEventLoopCrash(text4) {
|
|
1446
|
+
return /uv_run|uv__io_poll|SpinEventLoopInternal/i.test(text4);
|
|
1447
|
+
}
|
|
1448
|
+
function looksLikeV8Oom(text4) {
|
|
1449
|
+
return /javascript heap|reached heap limit|OOMErrorHandler|FatalProcessOutOfMemory|Allocation failed - JavaScript heap/i.test(
|
|
1450
|
+
text4
|
|
1451
|
+
);
|
|
1452
|
+
}
|
|
1453
|
+
function looksLikeHomebrewLibuvCrash(text4) {
|
|
1454
|
+
if (!looksLikeNativeEventLoopCrash(text4)) return false;
|
|
1455
|
+
return /Cellar\/(?:libuv|node)|libuv\.\d+\.dylib/i.test(text4);
|
|
1449
1456
|
}
|
|
1450
1457
|
function clipStderr(text4, maxChars) {
|
|
1451
1458
|
const trimmed = text4.trim();
|
|
@@ -1459,7 +1466,12 @@ function summarizeTurnStderr(tail, maxChars = 500) {
|
|
|
1459
1466
|
const cursorRunFailed = [...tail].reverse().find((line) => /^cursor run failed\b/i.test(line.trim()));
|
|
1460
1467
|
if (cursorRunFailed) return clipStderr(cursorRunFailed, maxChars);
|
|
1461
1468
|
if (tail.some(looksLikeNestedElectronCrash)) return NESTED_ELECTRON_SUMMARY;
|
|
1462
|
-
|
|
1469
|
+
const blob = tail.join("\n");
|
|
1470
|
+
if (looksLikeV8Oom(blob)) return V8_OOM_SUMMARY;
|
|
1471
|
+
if (looksLikeHomebrewLibuvCrash(blob)) return HOMEBREW_LIBUV_SUMMARY;
|
|
1472
|
+
if (looksLikeNativeEventLoopCrash(blob)) {
|
|
1473
|
+
return BUNDLED_NODE_CRASH_SUMMARY;
|
|
1474
|
+
}
|
|
1463
1475
|
if (tail.some(
|
|
1464
1476
|
(line) => /\[resource_exhausted\]|resource_exhausted/i.test(line) || /findFilesWithRipgrep/.test(line)
|
|
1465
1477
|
)) {
|
|
@@ -1485,10 +1497,11 @@ function looksLikeInvalidAgentSession(text4) {
|
|
|
1485
1497
|
function looksLikeRetryableRunnerCrash(text4) {
|
|
1486
1498
|
if (looksLikeAgentFailureMessage(text4)) return false;
|
|
1487
1499
|
if (looksLikeInvalidAgentSession(text4)) return false;
|
|
1500
|
+
if (looksLikeV8Oom(text4)) return false;
|
|
1488
1501
|
const lower = text4.trim().toLowerCase();
|
|
1489
1502
|
if (/cannot find (?:package|module)|err_module_not_found/.test(lower)) return false;
|
|
1490
1503
|
if (!lower) return true;
|
|
1491
|
-
return /uv_run|spineventloopinternal|libuv|homebrew node \+ shared libuv|hascustomhostobject|electroninitializeicuandstartnode|nested chromium|truncated crash dump|connection stalled|sig(?:segv|abrt|ill)|segmentation fault|illegal instruction|fatal error/.test(
|
|
1504
|
+
return /uv_run|spineventloopinternal|libuv|homebrew node \+ shared libuv|cursor runner crashed in node|hascustomhostobject|electroninitializeicuandstartnode|nested chromium|truncated crash dump|connection stalled|sig(?:segv|abrt|ill)|segmentation fault|illegal instruction|fatal error/.test(
|
|
1492
1505
|
lower
|
|
1493
1506
|
);
|
|
1494
1507
|
}
|
|
@@ -1540,9 +1553,15 @@ function humanizeAgentFailDetail(detail) {
|
|
|
1540
1553
|
if (/hascustomhostobject|electroninitializeicuandstartnode|nested chromium/i.test(lower)) {
|
|
1541
1554
|
return `${raw} \u2014 retry the turn; if it keeps failing, pick another agent.`;
|
|
1542
1555
|
}
|
|
1543
|
-
if (/
|
|
1556
|
+
if (looksLikeV8Oom(raw) || /javascript heap out of memory/i.test(lower)) {
|
|
1557
|
+
return /ran out of memory/i.test(raw) ? raw : V8_OOM_SUMMARY;
|
|
1558
|
+
}
|
|
1559
|
+
if (/homebrew node \+ shared libuv|Cellar\/(?:libuv|node)|libuv\.\d+\.dylib/i.test(raw)) {
|
|
1544
1560
|
return /brew install node@22/i.test(raw) ? raw : `${raw} \u2014 install Node 22 LTS (\`brew install node@22\`) and retry.`;
|
|
1545
1561
|
}
|
|
1562
|
+
if (/uv_run|spineventloopinternal|uv__io_poll|cursor runner crashed in node/i.test(lower)) {
|
|
1563
|
+
return /retry the turn/i.test(raw) ? raw : BUNDLED_NODE_CRASH_SUMMARY;
|
|
1564
|
+
}
|
|
1546
1565
|
if (/corrupt local agent checkpoint|missing root blob|truncated crash dump/.test(lower)) {
|
|
1547
1566
|
return `${raw} \u2014 retry the turn (Sideboard will start a fresh Cursor session).`;
|
|
1548
1567
|
}
|
|
@@ -1572,13 +1591,15 @@ function formatTurnExitError(exitCode, stderrSummary) {
|
|
|
1572
1591
|
if (looksLikeAgentFailureMessage(raw)) return detail;
|
|
1573
1592
|
return `exit ${code}: ${detail}`;
|
|
1574
1593
|
}
|
|
1575
|
-
var NODE_VERSION_FOOTER, NESTED_ELECTRON_SUMMARY, HOMEBREW_LIBUV_SUMMARY, MINIFIED_DUMP_SUMMARY;
|
|
1594
|
+
var NODE_VERSION_FOOTER, NESTED_ELECTRON_SUMMARY, HOMEBREW_LIBUV_SUMMARY, BUNDLED_NODE_CRASH_SUMMARY, V8_OOM_SUMMARY, MINIFIED_DUMP_SUMMARY;
|
|
1576
1595
|
var init_error_detail = __esm({
|
|
1577
1596
|
"src/agents/error-detail.ts"() {
|
|
1578
1597
|
"use strict";
|
|
1579
1598
|
NODE_VERSION_FOOTER = /^Node\.js v\d+/i;
|
|
1580
1599
|
NESTED_ELECTRON_SUMMARY = "Cursor local agent crashed at Electron startup (nested Chromium / HasCustomHostObject)";
|
|
1581
1600
|
HOMEBREW_LIBUV_SUMMARY = "Cursor runner crashed in Node (Homebrew Node + shared libuv). Install Node 22 LTS (`brew install node@22`) and retry.";
|
|
1601
|
+
BUNDLED_NODE_CRASH_SUMMARY = "Cursor runner crashed in Node. Retry the turn.";
|
|
1602
|
+
V8_OOM_SUMMARY = "Cursor runner ran out of memory (JavaScript heap). Retry; if it keeps happening, exclude large files from the project folder or start a new chat.";
|
|
1582
1603
|
MINIFIED_DUMP_SUMMARY = "Cursor local agent crashed during startup (truncated crash dump)";
|
|
1583
1604
|
}
|
|
1584
1605
|
});
|
|
@@ -2559,6 +2580,7 @@ __export(app_settings_exports, {
|
|
|
2559
2580
|
childEnvWithAppSettings: () => childEnvWithAppSettings,
|
|
2560
2581
|
claudeChromeEnabled: () => claudeChromeEnabled,
|
|
2561
2582
|
claudeUserSettingsPath: () => claudeUserSettingsPath,
|
|
2583
|
+
cowboyModeEnabled: () => cowboyModeEnabled,
|
|
2562
2584
|
deleteBranchOnPurgeEnabled: () => deleteBranchOnPurgeEnabled,
|
|
2563
2585
|
disconnectLinearConnection: () => disconnectLinearConnection,
|
|
2564
2586
|
ensureSlackDeviceIdentity: () => ensureSlackDeviceIdentity,
|
|
@@ -2797,6 +2819,9 @@ function normalizeAdvanced(raw) {
|
|
|
2797
2819
|
if (typeof source.deleteBranchOnPurge === "boolean") {
|
|
2798
2820
|
out.deleteBranchOnPurge = source.deleteBranchOnPurge;
|
|
2799
2821
|
}
|
|
2822
|
+
if (typeof source.cowboyMode === "boolean") {
|
|
2823
|
+
out.cowboyMode = source.cowboyMode;
|
|
2824
|
+
}
|
|
2800
2825
|
if (typeof source.autoArchiveOnMerge === "boolean") {
|
|
2801
2826
|
out.autoArchiveOnMerge = source.autoArchiveOnMerge;
|
|
2802
2827
|
}
|
|
@@ -3321,6 +3346,9 @@ function updateAdvancedSettings(patch) {
|
|
|
3321
3346
|
if (typeof patch.deleteBranchOnPurge === "boolean") {
|
|
3322
3347
|
advanced.deleteBranchOnPurge = patch.deleteBranchOnPurge;
|
|
3323
3348
|
}
|
|
3349
|
+
if (typeof patch.cowboyMode === "boolean") {
|
|
3350
|
+
advanced.cowboyMode = patch.cowboyMode;
|
|
3351
|
+
}
|
|
3324
3352
|
if (typeof patch.autoArchiveOnMerge === "boolean") {
|
|
3325
3353
|
advanced.autoArchiveOnMerge = patch.autoArchiveOnMerge;
|
|
3326
3354
|
}
|
|
@@ -3371,6 +3399,9 @@ function caffeinateWhileCloudConnectEnabled(settings = loadAppSettings()) {
|
|
|
3371
3399
|
function deleteBranchOnPurgeEnabled(settings = loadAppSettings()) {
|
|
3372
3400
|
return Boolean(settings.advanced.deleteBranchOnPurge);
|
|
3373
3401
|
}
|
|
3402
|
+
function cowboyModeEnabled(settings = loadAppSettings()) {
|
|
3403
|
+
return Boolean(settings.advanced.cowboyMode);
|
|
3404
|
+
}
|
|
3374
3405
|
function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
|
|
3375
3406
|
return Boolean(settings.advanced.autoArchiveOnMerge);
|
|
3376
3407
|
}
|
|
@@ -6675,6 +6706,296 @@ var init_claude_mcp = __esm({
|
|
|
6675
6706
|
}
|
|
6676
6707
|
});
|
|
6677
6708
|
|
|
6709
|
+
// src/agents/message-parts.ts
|
|
6710
|
+
function asRecord(input) {
|
|
6711
|
+
if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
6712
|
+
return input;
|
|
6713
|
+
}
|
|
6714
|
+
return void 0;
|
|
6715
|
+
}
|
|
6716
|
+
function str2(v) {
|
|
6717
|
+
return typeof v === "string" && v.trim() ? v : void 0;
|
|
6718
|
+
}
|
|
6719
|
+
function toolDetail(name, input) {
|
|
6720
|
+
if (!input) return void 0;
|
|
6721
|
+
const command = str2(input.command) ?? str2(input.cmd);
|
|
6722
|
+
if (command) return command;
|
|
6723
|
+
const path = str2(input.file_path) ?? str2(input.path) ?? str2(input.filePath) ?? str2(input.filename);
|
|
6724
|
+
if (path) return path;
|
|
6725
|
+
const pattern = str2(input.pattern) ?? str2(input.glob) ?? str2(input.glob_pattern);
|
|
6726
|
+
if (pattern) return pattern;
|
|
6727
|
+
const query = str2(input.query) ?? str2(input.prompt);
|
|
6728
|
+
if (query) return query.length > 80 ? `${query.slice(0, 77)}\u2026` : query;
|
|
6729
|
+
try {
|
|
6730
|
+
const raw = JSON.stringify(input);
|
|
6731
|
+
return raw.length > 80 ? `${raw.slice(0, 77)}\u2026` : raw;
|
|
6732
|
+
} catch {
|
|
6733
|
+
return name;
|
|
6734
|
+
}
|
|
6735
|
+
}
|
|
6736
|
+
function toolDescription(name, input) {
|
|
6737
|
+
const n = name.replace(/^mcp__/, "").replace(/__/g, " \xB7 ");
|
|
6738
|
+
if (/^get_record_types$|recordTypes/i.test(name)) return "List record types";
|
|
6739
|
+
if (/connectedAgentRequest/i.test(name)) {
|
|
6740
|
+
return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
|
|
6741
|
+
}
|
|
6742
|
+
if (/present_artifact$/i.test(name)) {
|
|
6743
|
+
return str2(input?.title) ? `Present ${str2(input?.title)}` : "Present artifact";
|
|
6744
|
+
}
|
|
6745
|
+
if (/present_plan$/i.test(name)) {
|
|
6746
|
+
return str2(input?.title) ? `Plan ${str2(input?.title)}` : "Present plan";
|
|
6747
|
+
}
|
|
6748
|
+
if (/present_schema$/i.test(name)) {
|
|
6749
|
+
return str2(input?.title) ? `Schema ${str2(input?.title)}` : "Present schema";
|
|
6750
|
+
}
|
|
6751
|
+
if (/present_files$/i.test(name)) {
|
|
6752
|
+
return str2(input?.title) ? `Files ${str2(input?.title)}` : "Present files";
|
|
6753
|
+
}
|
|
6754
|
+
if (isSubagentToolName(name)) {
|
|
6755
|
+
const desc = str2(input?.description);
|
|
6756
|
+
const sub = asRecord(input?.subagentType);
|
|
6757
|
+
const kind = str2(sub?.name) ?? str2(sub?.kind) ?? str2(input?.subagent_type) ?? str2(input?.subagentType);
|
|
6758
|
+
if (/^spawn_agent$/i.test(name)) {
|
|
6759
|
+
return str2(input?.prompt) ?? desc ?? "Subagent";
|
|
6760
|
+
}
|
|
6761
|
+
if (/connectedAgentRequest/i.test(name)) {
|
|
6762
|
+
return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
|
|
6763
|
+
}
|
|
6764
|
+
if (desc && kind) return `${kind}: ${desc}`;
|
|
6765
|
+
if (desc) return desc;
|
|
6766
|
+
return "Subagent";
|
|
6767
|
+
}
|
|
6768
|
+
if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
|
|
6769
|
+
return str2(input?.title) ? `Artifact ${str2(input?.title)}` : "Artifact";
|
|
6770
|
+
}
|
|
6771
|
+
if (!input) return n;
|
|
6772
|
+
if (/bash|shell|terminal/i.test(name) && str2(input.command)) {
|
|
6773
|
+
const cmd = str2(input.command);
|
|
6774
|
+
if (/git\s+fetch/i.test(cmd)) return "Fetch latest from origin and check status";
|
|
6775
|
+
if (/git\s+status/i.test(cmd)) return "Check git status";
|
|
6776
|
+
if (/git\s+log/i.test(cmd)) return "Inspect recent commits";
|
|
6777
|
+
if (/git\s+branch/i.test(cmd)) return "List branches";
|
|
6778
|
+
if (/grep|rg\b/i.test(cmd)) return "Search repository";
|
|
6779
|
+
return "Run shell command";
|
|
6780
|
+
}
|
|
6781
|
+
if (/edit|write|apply/i.test(name)) {
|
|
6782
|
+
const path = str2(input.file_path) ?? str2(input.path);
|
|
6783
|
+
return path ? `Edit ${path.split("/").pop()}` : "Edit file";
|
|
6784
|
+
}
|
|
6785
|
+
if (/read/i.test(name)) {
|
|
6786
|
+
const path = str2(input.file_path) ?? str2(input.path);
|
|
6787
|
+
return path ? `Read ${path.split("/").pop()}` : "Read file";
|
|
6788
|
+
}
|
|
6789
|
+
if (/grep/i.test(name)) return "Search files";
|
|
6790
|
+
if (/glob/i.test(name)) return "Find files";
|
|
6791
|
+
return n;
|
|
6792
|
+
}
|
|
6793
|
+
function isSubagentToolName(name) {
|
|
6794
|
+
const n = (name ?? "").trim();
|
|
6795
|
+
if (/^(task|agent|spawn_agent)$/i.test(n)) return true;
|
|
6796
|
+
return /connectedAgentRequest/i.test(n);
|
|
6797
|
+
}
|
|
6798
|
+
function messagePartParentId(part) {
|
|
6799
|
+
if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
|
|
6800
|
+
return part.parentId;
|
|
6801
|
+
}
|
|
6802
|
+
return void 0;
|
|
6803
|
+
}
|
|
6804
|
+
function sameParentId(a, b) {
|
|
6805
|
+
return (a ?? "") === (b ?? "");
|
|
6806
|
+
}
|
|
6807
|
+
function withEventParentId(event, parentId) {
|
|
6808
|
+
if (!parentId) return event;
|
|
6809
|
+
if (event.type === "stdout" || event.type === "thinking" || event.type === "tool_use" || event.type === "tool_result") {
|
|
6810
|
+
return { ...event, parentId: event.parentId ?? parentId };
|
|
6811
|
+
}
|
|
6812
|
+
return event;
|
|
6813
|
+
}
|
|
6814
|
+
function toolFilePath(input) {
|
|
6815
|
+
if (!input) return void 0;
|
|
6816
|
+
return str2(input.file_path) ?? str2(input.path) ?? str2(input.filePath) ?? str2(input.filename);
|
|
6817
|
+
}
|
|
6818
|
+
function countLines(text4) {
|
|
6819
|
+
if (!text4) return 0;
|
|
6820
|
+
return text4.split("\n").length;
|
|
6821
|
+
}
|
|
6822
|
+
function diffFromInput(input) {
|
|
6823
|
+
if (!input) return {};
|
|
6824
|
+
const oldS = str2(input.old_string) ?? str2(input.oldString);
|
|
6825
|
+
const newS = str2(input.new_string) ?? str2(input.newString) ?? str2(input.content);
|
|
6826
|
+
if (oldS != null || newS != null) {
|
|
6827
|
+
return {
|
|
6828
|
+
additions: countLines(newS),
|
|
6829
|
+
deletions: countLines(oldS)
|
|
6830
|
+
};
|
|
6831
|
+
}
|
|
6832
|
+
return {};
|
|
6833
|
+
}
|
|
6834
|
+
function parseDiffStat(result) {
|
|
6835
|
+
if (!result) return {};
|
|
6836
|
+
const paired = result.match(/\+(\d+)\s+-(\d+)/);
|
|
6837
|
+
if (paired) {
|
|
6838
|
+
return {
|
|
6839
|
+
additions: Number(paired[1]),
|
|
6840
|
+
deletions: Number(paired[2])
|
|
6841
|
+
};
|
|
6842
|
+
}
|
|
6843
|
+
const verbose = result.match(
|
|
6844
|
+
/(\d+)\s+insertions?(?:,\s*(\d+)\s+deletions?)?/i
|
|
6845
|
+
);
|
|
6846
|
+
if (verbose) {
|
|
6847
|
+
return {
|
|
6848
|
+
additions: Number(verbose[1]),
|
|
6849
|
+
deletions: verbose[2] != null ? Number(verbose[2]) : void 0
|
|
6850
|
+
};
|
|
6851
|
+
}
|
|
6852
|
+
return {};
|
|
6853
|
+
}
|
|
6854
|
+
function applyAgentEvent(parts, event) {
|
|
6855
|
+
if (event.type === "stdout") {
|
|
6856
|
+
const data = event.data;
|
|
6857
|
+
if (!data) return parts;
|
|
6858
|
+
const next = [...parts];
|
|
6859
|
+
const last = next[next.length - 1];
|
|
6860
|
+
if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
|
|
6861
|
+
next[next.length - 1] = {
|
|
6862
|
+
type: "text",
|
|
6863
|
+
text: last.text + data,
|
|
6864
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
6865
|
+
};
|
|
6866
|
+
} else {
|
|
6867
|
+
next.push({
|
|
6868
|
+
type: "text",
|
|
6869
|
+
text: data,
|
|
6870
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
6871
|
+
});
|
|
6872
|
+
}
|
|
6873
|
+
return next;
|
|
6874
|
+
}
|
|
6875
|
+
if (event.type === "thinking") {
|
|
6876
|
+
const data = event.data;
|
|
6877
|
+
if (!data) return parts;
|
|
6878
|
+
const next = [...parts];
|
|
6879
|
+
const last = next[next.length - 1];
|
|
6880
|
+
if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
|
|
6881
|
+
next[next.length - 1] = {
|
|
6882
|
+
type: "thinking",
|
|
6883
|
+
text: last.text + data,
|
|
6884
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
6885
|
+
};
|
|
6886
|
+
} else {
|
|
6887
|
+
next.push({
|
|
6888
|
+
type: "thinking",
|
|
6889
|
+
text: data,
|
|
6890
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
6891
|
+
});
|
|
6892
|
+
}
|
|
6893
|
+
return next;
|
|
6894
|
+
}
|
|
6895
|
+
if (event.type === "tool_use") {
|
|
6896
|
+
const input = asRecord(event.input);
|
|
6897
|
+
const diff = diffFromInput(input);
|
|
6898
|
+
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
6899
|
+
if (existing >= 0) {
|
|
6900
|
+
const prev = parts[existing];
|
|
6901
|
+
const next = [...parts];
|
|
6902
|
+
const mergedInput = input && Object.keys(input).length > 0 ? input : prev.input ?? input;
|
|
6903
|
+
next[existing] = {
|
|
6904
|
+
...prev,
|
|
6905
|
+
name: event.name || prev.name,
|
|
6906
|
+
input: mergedInput,
|
|
6907
|
+
description: toolDescription(event.name || prev.name, mergedInput),
|
|
6908
|
+
detail: toolDetail(event.name || prev.name, mergedInput) ?? prev.detail,
|
|
6909
|
+
filePath: toolFilePath(mergedInput) ?? prev.filePath,
|
|
6910
|
+
additions: diff.additions ?? prev.additions,
|
|
6911
|
+
deletions: diff.deletions ?? prev.deletions,
|
|
6912
|
+
parentId: event.parentId ?? prev.parentId
|
|
6913
|
+
};
|
|
6914
|
+
return next;
|
|
6915
|
+
}
|
|
6916
|
+
return [
|
|
6917
|
+
...parts,
|
|
6918
|
+
{
|
|
6919
|
+
type: "tool",
|
|
6920
|
+
id: event.id,
|
|
6921
|
+
name: event.name,
|
|
6922
|
+
input,
|
|
6923
|
+
description: toolDescription(event.name, input),
|
|
6924
|
+
detail: toolDetail(event.name, input),
|
|
6925
|
+
status: "running",
|
|
6926
|
+
filePath: toolFilePath(input),
|
|
6927
|
+
...event.parentId ? { parentId: event.parentId } : {},
|
|
6928
|
+
...diff
|
|
6929
|
+
}
|
|
6930
|
+
];
|
|
6931
|
+
}
|
|
6932
|
+
if (event.type === "tool_result") {
|
|
6933
|
+
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
6934
|
+
const fromResult = parseDiffStat(event.content);
|
|
6935
|
+
if (existing < 0) {
|
|
6936
|
+
return [
|
|
6937
|
+
...parts,
|
|
6938
|
+
{
|
|
6939
|
+
type: "tool",
|
|
6940
|
+
id: event.id,
|
|
6941
|
+
name: "tool",
|
|
6942
|
+
description: "tool",
|
|
6943
|
+
status: event.isError ? "error" : "done",
|
|
6944
|
+
result: event.content,
|
|
6945
|
+
...event.parentId ? { parentId: event.parentId } : {},
|
|
6946
|
+
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
6947
|
+
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
6948
|
+
}
|
|
6949
|
+
];
|
|
6950
|
+
}
|
|
6951
|
+
return parts.map((p, i) => {
|
|
6952
|
+
if (i !== existing || p.type !== "tool") return p;
|
|
6953
|
+
return {
|
|
6954
|
+
...p,
|
|
6955
|
+
status: event.isError ? "error" : "done",
|
|
6956
|
+
result: event.content,
|
|
6957
|
+
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
6958
|
+
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
6959
|
+
};
|
|
6960
|
+
});
|
|
6961
|
+
}
|
|
6962
|
+
return parts;
|
|
6963
|
+
}
|
|
6964
|
+
function partsToAssistantText(parts) {
|
|
6965
|
+
return parts.filter(
|
|
6966
|
+
(p) => p.type === "text" && !messagePartParentId(p)
|
|
6967
|
+
).map((p) => p.text).join("").trim();
|
|
6968
|
+
}
|
|
6969
|
+
function stripBrightsyNdjsonNoise(text4) {
|
|
6970
|
+
if (!text4 || !text4.includes('"type"')) return text4;
|
|
6971
|
+
let out = text4;
|
|
6972
|
+
out = out.replace(
|
|
6973
|
+
/\{"type":"(?:tool_use|tool_result|tool|thinking|usage|done|error)"[\s\S]*?\}\s*(?=\{"type":"|$|(?=[A-Za-z*#]))/g,
|
|
6974
|
+
""
|
|
6975
|
+
);
|
|
6976
|
+
out = out.replace(/\{"type":"(?:tool_use|tool_result|tool)"[\s\S]*$/g, "");
|
|
6977
|
+
return out.trim();
|
|
6978
|
+
}
|
|
6979
|
+
function isBrightsyNdjsonLine(line) {
|
|
6980
|
+
const t = line.trim();
|
|
6981
|
+
if (!t.startsWith("{")) return false;
|
|
6982
|
+
return /"type"\s*:\s*"(tool_use|tool_result|tool|thinking|usage|done|error|text)"/.test(t);
|
|
6983
|
+
}
|
|
6984
|
+
function finalizeParts(parts) {
|
|
6985
|
+
return parts.map(
|
|
6986
|
+
(p) => p.type === "tool" && p.status === "running" ? { ...p, status: "done" } : p
|
|
6987
|
+
);
|
|
6988
|
+
}
|
|
6989
|
+
function normalizeParseResult(parsed) {
|
|
6990
|
+
if (!parsed) return [];
|
|
6991
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
6992
|
+
}
|
|
6993
|
+
var init_message_parts = __esm({
|
|
6994
|
+
"src/agents/message-parts.ts"() {
|
|
6995
|
+
"use strict";
|
|
6996
|
+
}
|
|
6997
|
+
});
|
|
6998
|
+
|
|
6678
6999
|
// src/mcp/profile.ts
|
|
6679
7000
|
function sideboardMcpProfile(env = process.env) {
|
|
6680
7001
|
return env[SIDEBOARD_MCP_PROFILE_ENV]?.trim().toLowerCase() === "worktree" ? "worktree" : "orchestration";
|
|
@@ -7300,41 +7621,58 @@ function claudeResultErrorDetail(obj) {
|
|
|
7300
7621
|
}
|
|
7301
7622
|
return "Claude turn failed";
|
|
7302
7623
|
}
|
|
7303
|
-
function eventsFromContentBlocks(blocks) {
|
|
7624
|
+
function eventsFromContentBlocks(blocks, parentId) {
|
|
7304
7625
|
if (!blocks?.length) return [];
|
|
7305
7626
|
const out = [];
|
|
7306
7627
|
for (const block of blocks) {
|
|
7307
7628
|
if (!block?.type) continue;
|
|
7308
7629
|
if (block.type === "text" && block.text) {
|
|
7309
|
-
out.push({ type: "stdout", data: block.text });
|
|
7630
|
+
out.push(withEventParentId({ type: "stdout", data: block.text }, parentId));
|
|
7310
7631
|
continue;
|
|
7311
7632
|
}
|
|
7312
7633
|
if ((block.type === "thinking" || block.type === "redacted_thinking") && block.thinking) {
|
|
7313
|
-
out.push({ type: "thinking", data: block.thinking });
|
|
7634
|
+
out.push(withEventParentId({ type: "thinking", data: block.thinking }, parentId));
|
|
7314
7635
|
continue;
|
|
7315
7636
|
}
|
|
7316
7637
|
if (block.type === "tool_use" && block.id && block.name) {
|
|
7317
|
-
out.push(
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7638
|
+
out.push(
|
|
7639
|
+
withEventParentId(
|
|
7640
|
+
{
|
|
7641
|
+
type: "tool_use",
|
|
7642
|
+
id: block.id,
|
|
7643
|
+
name: block.name,
|
|
7644
|
+
input: block.input
|
|
7645
|
+
},
|
|
7646
|
+
parentId
|
|
7647
|
+
)
|
|
7648
|
+
);
|
|
7323
7649
|
continue;
|
|
7324
7650
|
}
|
|
7325
7651
|
if (block.type === "tool_result" && block.tool_use_id) {
|
|
7326
7652
|
const content = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map(
|
|
7327
7653
|
(c) => typeof c === "string" ? c : c && typeof c === "object" && "text" in c ? String(c.text ?? "") : ""
|
|
7328
7654
|
).join("") : block.content != null ? JSON.stringify(block.content) : void 0;
|
|
7329
|
-
out.push(
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7655
|
+
out.push(
|
|
7656
|
+
withEventParentId(
|
|
7657
|
+
{
|
|
7658
|
+
type: "tool_result",
|
|
7659
|
+
id: block.tool_use_id,
|
|
7660
|
+
content,
|
|
7661
|
+
isError: Boolean(block.is_error)
|
|
7662
|
+
},
|
|
7663
|
+
parentId
|
|
7664
|
+
)
|
|
7665
|
+
);
|
|
7666
|
+
}
|
|
7667
|
+
}
|
|
7668
|
+
return out;
|
|
7669
|
+
}
|
|
7670
|
+
function claudeParentToolUseId(obj) {
|
|
7671
|
+
const nested = obj.event && typeof obj.event === "object" && !Array.isArray(obj.event) ? obj.event : void 0;
|
|
7672
|
+
for (const id of [obj.parent_tool_use_id, nested?.parent_tool_use_id]) {
|
|
7673
|
+
if (typeof id === "string" && id.trim()) return id.trim();
|
|
7674
|
+
}
|
|
7675
|
+
return void 0;
|
|
7338
7676
|
}
|
|
7339
7677
|
function parseIssuesJson(raw) {
|
|
7340
7678
|
const text4 = raw.trim();
|
|
@@ -7370,6 +7708,7 @@ var init_claude = __esm({
|
|
|
7370
7708
|
init_app_settings();
|
|
7371
7709
|
init_claude_mcp();
|
|
7372
7710
|
init_error_detail();
|
|
7711
|
+
init_message_parts();
|
|
7373
7712
|
init_injected_mcp();
|
|
7374
7713
|
init_turn_input();
|
|
7375
7714
|
init_types();
|
|
@@ -7381,7 +7720,10 @@ var init_claude = __esm({
|
|
|
7381
7720
|
"Glob",
|
|
7382
7721
|
"Grep",
|
|
7383
7722
|
"WebFetch",
|
|
7384
|
-
"WebSearch"
|
|
7723
|
+
"WebSearch",
|
|
7724
|
+
// Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
|
|
7725
|
+
"Task",
|
|
7726
|
+
"Agent"
|
|
7385
7727
|
];
|
|
7386
7728
|
CLAUDE_CHROME_ALLOWED_TOOLS = [
|
|
7387
7729
|
"mcp__claude-in-chrome",
|
|
@@ -7509,7 +7851,9 @@ var init_claude = __esm({
|
|
|
7509
7851
|
args,
|
|
7510
7852
|
cwd: thread.worktreePath,
|
|
7511
7853
|
stdin: useStdin ? `${promptText}
|
|
7512
|
-
` : void 0
|
|
7854
|
+
` : void 0,
|
|
7855
|
+
// Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
|
|
7856
|
+
env: { CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1" }
|
|
7513
7857
|
};
|
|
7514
7858
|
},
|
|
7515
7859
|
parseEvent(line) {
|
|
@@ -7526,8 +7870,9 @@ var init_claude = __esm({
|
|
|
7526
7870
|
return { type: "session_id", data: obj.session_id };
|
|
7527
7871
|
}
|
|
7528
7872
|
if (obj.type === "assistant" || obj.type === "user") {
|
|
7873
|
+
const parentId = claudeParentToolUseId(obj);
|
|
7529
7874
|
const message = obj.message;
|
|
7530
|
-
const events = eventsFromContentBlocks(message?.content);
|
|
7875
|
+
const events = eventsFromContentBlocks(message?.content, parentId);
|
|
7531
7876
|
if (obj.type === "assistant") {
|
|
7532
7877
|
const usage = usageFromClaude(message?.usage);
|
|
7533
7878
|
if (usage) events.push({ type: "usage", data: usage, scope: "request" });
|
|
@@ -7536,34 +7881,45 @@ var init_claude = __esm({
|
|
|
7536
7881
|
return events.length === 1 ? events[0] : events;
|
|
7537
7882
|
}
|
|
7538
7883
|
if (obj.type === "stream_event") {
|
|
7884
|
+
const parentId = claudeParentToolUseId(obj);
|
|
7539
7885
|
const event = obj.event;
|
|
7540
7886
|
if (!event) return null;
|
|
7541
7887
|
if (event.type === "content_block_start" && event.content_block) {
|
|
7542
7888
|
const block = event.content_block;
|
|
7543
7889
|
if (block.type === "tool_use" && block.id && block.name) {
|
|
7544
|
-
return
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7890
|
+
return withEventParentId(
|
|
7891
|
+
{
|
|
7892
|
+
type: "tool_use",
|
|
7893
|
+
id: block.id,
|
|
7894
|
+
name: block.name,
|
|
7895
|
+
input: block.input
|
|
7896
|
+
},
|
|
7897
|
+
parentId
|
|
7898
|
+
);
|
|
7550
7899
|
}
|
|
7551
7900
|
if (block.type === "thinking" && block.thinking) {
|
|
7552
|
-
return { type: "thinking", data: block.thinking };
|
|
7901
|
+
return withEventParentId({ type: "thinking", data: block.thinking }, parentId);
|
|
7553
7902
|
}
|
|
7554
7903
|
return null;
|
|
7555
7904
|
}
|
|
7556
7905
|
if (event.type === "content_block_delta" && event.delta) {
|
|
7557
|
-
if (event.delta.text)
|
|
7558
|
-
|
|
7906
|
+
if (event.delta.text) {
|
|
7907
|
+
return withEventParentId({ type: "stdout", data: event.delta.text }, parentId);
|
|
7908
|
+
}
|
|
7909
|
+
if (event.delta.thinking) {
|
|
7910
|
+
return withEventParentId({ type: "thinking", data: event.delta.thinking }, parentId);
|
|
7911
|
+
}
|
|
7559
7912
|
return null;
|
|
7560
7913
|
}
|
|
7561
7914
|
return null;
|
|
7562
7915
|
}
|
|
7563
7916
|
if (obj.type === "content_block_delta") {
|
|
7917
|
+
const parentId = claudeParentToolUseId(obj);
|
|
7564
7918
|
const delta = obj.delta;
|
|
7565
|
-
if (delta?.text) return { type: "stdout", data: delta.text };
|
|
7566
|
-
if (delta?.thinking)
|
|
7919
|
+
if (delta?.text) return withEventParentId({ type: "stdout", data: delta.text }, parentId);
|
|
7920
|
+
if (delta?.thinking) {
|
|
7921
|
+
return withEventParentId({ type: "thinking", data: delta.thinking }, parentId);
|
|
7922
|
+
}
|
|
7567
7923
|
return null;
|
|
7568
7924
|
}
|
|
7569
7925
|
if (obj.type === "result") {
|
|
@@ -7696,7 +8052,7 @@ function unwrapCodexMcpResult(result) {
|
|
|
7696
8052
|
return String(result);
|
|
7697
8053
|
}
|
|
7698
8054
|
}
|
|
7699
|
-
function
|
|
8055
|
+
function asRecord2(value) {
|
|
7700
8056
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
7701
8057
|
return value;
|
|
7702
8058
|
}
|
|
@@ -7861,7 +8217,7 @@ var init_codex = __esm({
|
|
|
7861
8217
|
}
|
|
7862
8218
|
if (itemType === "mcp_tool_call" && item.id && item.server && item.tool) {
|
|
7863
8219
|
const name = `mcp__${item.server}__${item.tool}`;
|
|
7864
|
-
const input =
|
|
8220
|
+
const input = asRecord2(item.arguments);
|
|
7865
8221
|
const events = [
|
|
7866
8222
|
{ type: "tool_use", id: item.id, name, input }
|
|
7867
8223
|
];
|
|
@@ -7892,6 +8248,36 @@ var init_codex = __esm({
|
|
|
7892
8248
|
}
|
|
7893
8249
|
return events.length === 1 ? events[0] : events;
|
|
7894
8250
|
}
|
|
8251
|
+
if (itemType === "collab_tool_call" && item.id) {
|
|
8252
|
+
const rawTool = typeof item.tool === "string" ? item.tool : "spawn_agent";
|
|
8253
|
+
const name = /spawn/i.test(rawTool) ? "spawn_agent" : rawTool;
|
|
8254
|
+
const input = {};
|
|
8255
|
+
if (item.prompt) input.prompt = item.prompt;
|
|
8256
|
+
if (Array.isArray(item.receiver_thread_ids)) {
|
|
8257
|
+
input.receiver_thread_ids = item.receiver_thread_ids;
|
|
8258
|
+
}
|
|
8259
|
+
const events = [{ type: "tool_use", id: item.id, name, input }];
|
|
8260
|
+
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
8261
|
+
if (finished) {
|
|
8262
|
+
const nested = [];
|
|
8263
|
+
if (item.agents_states && typeof item.agents_states === "object") {
|
|
8264
|
+
for (const value of Object.values(item.agents_states)) {
|
|
8265
|
+
const msg = value && typeof value === "object" && typeof value.message === "string" ? value.message.trim() : "";
|
|
8266
|
+
if (msg) nested.push(msg);
|
|
8267
|
+
}
|
|
8268
|
+
}
|
|
8269
|
+
for (const text4 of nested) {
|
|
8270
|
+
events.push({ type: "stdout", data: text4, parentId: item.id });
|
|
8271
|
+
}
|
|
8272
|
+
events.push({
|
|
8273
|
+
type: "tool_result",
|
|
8274
|
+
id: item.id,
|
|
8275
|
+
content: nested.join("\n") || void 0,
|
|
8276
|
+
isError: item.status === "failed"
|
|
8277
|
+
});
|
|
8278
|
+
}
|
|
8279
|
+
return events.length === 1 ? events[0] : events;
|
|
8280
|
+
}
|
|
7895
8281
|
if (item.status === "failed") {
|
|
7896
8282
|
const detail = item.message?.trim() || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
|
|
7897
8283
|
return { type: "stderr", data: detail };
|
|
@@ -7980,20 +8366,20 @@ function usageFromCursor(usage) {
|
|
|
7980
8366
|
cacheWriteTokens: usage.cacheWriteTokens ? Number(usage.cacheWriteTokens) : void 0
|
|
7981
8367
|
};
|
|
7982
8368
|
}
|
|
7983
|
-
function
|
|
8369
|
+
function asRecord3(value) {
|
|
7984
8370
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
7985
8371
|
return value;
|
|
7986
8372
|
}
|
|
7987
8373
|
return void 0;
|
|
7988
8374
|
}
|
|
7989
8375
|
function normalizeCursorToolCall(name, args) {
|
|
7990
|
-
const raw =
|
|
8376
|
+
const raw = asRecord3(args);
|
|
7991
8377
|
const toolName = typeof raw?.toolName === "string" && raw.toolName.trim() ? raw.toolName.trim() : null;
|
|
7992
|
-
const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" ||
|
|
8378
|
+
const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord3(raw?.args) != null);
|
|
7993
8379
|
if (looksLikeMcp && toolName) {
|
|
7994
8380
|
const providerRaw = typeof raw.providerIdentifier === "string" && raw.providerIdentifier.trim() ? raw.providerIdentifier.trim() : "sideboard";
|
|
7995
8381
|
const provider = providerRaw.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
7996
|
-
const nested =
|
|
8382
|
+
const nested = asRecord3(raw.args);
|
|
7997
8383
|
return {
|
|
7998
8384
|
name: `mcp__${provider}__${toolName}`,
|
|
7999
8385
|
input: nested ?? { toolName }
|
|
@@ -8004,7 +8390,7 @@ function normalizeCursorToolCall(name, args) {
|
|
|
8004
8390
|
function unwrapCursorToolResult(result) {
|
|
8005
8391
|
if (result == null) return void 0;
|
|
8006
8392
|
if (typeof result === "string") return result;
|
|
8007
|
-
const rec =
|
|
8393
|
+
const rec = asRecord3(result);
|
|
8008
8394
|
if (!rec) {
|
|
8009
8395
|
try {
|
|
8010
8396
|
return JSON.stringify(result);
|
|
@@ -8015,18 +8401,18 @@ function unwrapCursorToolResult(result) {
|
|
|
8015
8401
|
const collectTexts = (items) => {
|
|
8016
8402
|
const texts = [];
|
|
8017
8403
|
for (const item of items) {
|
|
8018
|
-
const row =
|
|
8404
|
+
const row = asRecord3(item);
|
|
8019
8405
|
if (!row) continue;
|
|
8020
8406
|
if (typeof row.text === "string") {
|
|
8021
8407
|
texts.push(row.text);
|
|
8022
8408
|
continue;
|
|
8023
8409
|
}
|
|
8024
|
-
const nested =
|
|
8410
|
+
const nested = asRecord3(row.text);
|
|
8025
8411
|
if (typeof nested?.text === "string") texts.push(nested.text);
|
|
8026
8412
|
}
|
|
8027
8413
|
return texts;
|
|
8028
8414
|
};
|
|
8029
|
-
const value =
|
|
8415
|
+
const value = asRecord3(rec.value);
|
|
8030
8416
|
if (value && Array.isArray(value.content)) {
|
|
8031
8417
|
const texts = collectTexts(value.content);
|
|
8032
8418
|
if (texts.length) return texts.join("\n");
|
|
@@ -8043,10 +8429,10 @@ function unwrapCursorToolResult(result) {
|
|
|
8043
8429
|
}
|
|
8044
8430
|
function cursorToolResultIsError(status, result) {
|
|
8045
8431
|
if (status === "error") return true;
|
|
8046
|
-
const rec =
|
|
8432
|
+
const rec = asRecord3(result);
|
|
8047
8433
|
if (!rec) return false;
|
|
8048
8434
|
if (rec.status === "error") return true;
|
|
8049
|
-
const value =
|
|
8435
|
+
const value = asRecord3(rec.value);
|
|
8050
8436
|
return value?.isError === true;
|
|
8051
8437
|
}
|
|
8052
8438
|
function cursorSdkMessageToEvents(msg) {
|
|
@@ -8188,24 +8574,24 @@ function resolveCursorRipgrepPath(opts) {
|
|
|
8188
8574
|
packagedCursorRipgrepCandidate(platformRipgrepPackage(), rgBinaryName())
|
|
8189
8575
|
);
|
|
8190
8576
|
if (fromPackaged) return fromPackaged;
|
|
8191
|
-
const start = opts?.startFile?.trim() || process.argv[1] ||
|
|
8577
|
+
const start = opts?.startFile?.trim() || process.argv[1] || // CJS bundle only — ESM has no __filename; argv[1] is the running script.
|
|
8578
|
+
// eslint-disable-next-line camelcase
|
|
8579
|
+
(typeof __filename !== "undefined" ? __filename : "");
|
|
8192
8580
|
return walkForBundledRipgrep(start) ?? requireResolveBundledRipgrep(start);
|
|
8193
8581
|
}
|
|
8194
8582
|
function cursorRipgrepEnv(opts) {
|
|
8195
8583
|
const path = resolveCursorRipgrepPath(opts);
|
|
8196
8584
|
return path ? { [RIPGREP_ENV]: path } : {};
|
|
8197
8585
|
}
|
|
8198
|
-
var import_node_fs23, import_node_module2, import_node_path23,
|
|
8586
|
+
var import_node_fs23, import_node_module2, import_node_path23, RIPGREP_ENV;
|
|
8199
8587
|
var init_cursor_ripgrep = __esm({
|
|
8200
8588
|
"src/agents/cursor-ripgrep.ts"() {
|
|
8201
8589
|
"use strict";
|
|
8202
8590
|
import_node_fs23 = require("fs");
|
|
8203
8591
|
import_node_module2 = require("module");
|
|
8204
8592
|
import_node_path23 = require("path");
|
|
8205
|
-
import_node_url2 = require("url");
|
|
8206
8593
|
init_node_launch();
|
|
8207
8594
|
init_packaged_runtime();
|
|
8208
|
-
import_meta2 = {};
|
|
8209
8595
|
RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
8210
8596
|
}
|
|
8211
8597
|
});
|
|
@@ -8249,7 +8635,7 @@ function entryDir() {
|
|
|
8249
8635
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
8250
8636
|
if (cjsDir) return cjsDir;
|
|
8251
8637
|
try {
|
|
8252
|
-
return (0, import_node_path24.dirname)((0,
|
|
8638
|
+
return (0, import_node_path24.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
8253
8639
|
} catch {
|
|
8254
8640
|
try {
|
|
8255
8641
|
const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
|
|
@@ -8278,14 +8664,14 @@ function cursorRunnerPath() {
|
|
|
8278
8664
|
}
|
|
8279
8665
|
return candidates[0];
|
|
8280
8666
|
}
|
|
8281
|
-
var import_node_fs24, import_node_module3, import_node_path24,
|
|
8667
|
+
var import_node_fs24, import_node_module3, import_node_path24, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
|
|
8282
8668
|
var init_cursor = __esm({
|
|
8283
8669
|
"src/agents/cursor.ts"() {
|
|
8284
8670
|
"use strict";
|
|
8285
8671
|
import_node_fs24 = require("fs");
|
|
8286
8672
|
import_node_module3 = require("module");
|
|
8287
8673
|
import_node_path24 = require("path");
|
|
8288
|
-
|
|
8674
|
+
import_node_url2 = require("url");
|
|
8289
8675
|
import_sdk = require("@cursor/sdk");
|
|
8290
8676
|
init_run();
|
|
8291
8677
|
init_app_settings();
|
|
@@ -8297,7 +8683,7 @@ var init_cursor = __esm({
|
|
|
8297
8683
|
init_packaged_runtime();
|
|
8298
8684
|
init_turn_input();
|
|
8299
8685
|
init_cursor_events();
|
|
8300
|
-
|
|
8686
|
+
import_meta2 = {};
|
|
8301
8687
|
FALLBACK_CURSOR_MODELS = [
|
|
8302
8688
|
{ id: "default", displayName: "Auto" },
|
|
8303
8689
|
{ id: "composer-2.5", displayName: "Composer 2.5" },
|
|
@@ -8389,6 +8775,24 @@ var init_cursor = __esm({
|
|
|
8389
8775
|
});
|
|
8390
8776
|
|
|
8391
8777
|
// src/agents/opencode.ts
|
|
8778
|
+
function asRecord4(value) {
|
|
8779
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
8780
|
+
return value;
|
|
8781
|
+
}
|
|
8782
|
+
return void 0;
|
|
8783
|
+
}
|
|
8784
|
+
function str3(v) {
|
|
8785
|
+
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
8786
|
+
}
|
|
8787
|
+
function opencodeToolId(name, callId, metadata) {
|
|
8788
|
+
const sessionId = str3(metadata?.sessionId) ?? str3(metadata?.sessionID);
|
|
8789
|
+
if (name === "task" && sessionId) return sessionId;
|
|
8790
|
+
return callId || `tool-${Date.now()}`;
|
|
8791
|
+
}
|
|
8792
|
+
function withTaskParent(parentId, nested) {
|
|
8793
|
+
const events = Array.isArray(nested) ? nested : [nested];
|
|
8794
|
+
return [{ type: "tool_use", id: parentId, name: "task" }, ...events];
|
|
8795
|
+
}
|
|
8392
8796
|
function displayNameFromOpencodeId(id) {
|
|
8393
8797
|
const slash = id.indexOf("/");
|
|
8394
8798
|
if (slash <= 0) return id;
|
|
@@ -8455,6 +8859,7 @@ var init_opencode = __esm({
|
|
|
8455
8859
|
init_app_settings();
|
|
8456
8860
|
init_global_workspace();
|
|
8457
8861
|
init_error_detail();
|
|
8862
|
+
init_message_parts();
|
|
8458
8863
|
init_injected_mcp();
|
|
8459
8864
|
init_turn_input();
|
|
8460
8865
|
init_types();
|
|
@@ -8571,10 +8976,15 @@ var init_opencode = __esm({
|
|
|
8571
8976
|
}
|
|
8572
8977
|
if (obj.type === "tool_use") {
|
|
8573
8978
|
const part = obj.part;
|
|
8574
|
-
const id = part?.callID ?? part?.id ?? obj.id ?? `tool-${Date.now()}`;
|
|
8575
8979
|
const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
|
|
8576
8980
|
const state = part?.state;
|
|
8577
8981
|
const input = (state?.input && typeof state.input === "object" ? state.input : void 0) ?? part?.input ?? obj.input;
|
|
8982
|
+
const metadata = asRecord4(state?.metadata);
|
|
8983
|
+
const id = opencodeToolId(
|
|
8984
|
+
name,
|
|
8985
|
+
part?.callID ?? part?.id ?? obj.id,
|
|
8986
|
+
metadata
|
|
8987
|
+
);
|
|
8578
8988
|
const events = [{ type: "tool_use", id, name, input }];
|
|
8579
8989
|
const output = state?.output;
|
|
8580
8990
|
if (output != null || state?.status === "completed" || state?.status === "error") {
|
|
@@ -8588,6 +8998,53 @@ var init_opencode = __esm({
|
|
|
8588
8998
|
}
|
|
8589
8999
|
return events.length === 1 ? events[0] : events;
|
|
8590
9000
|
}
|
|
9001
|
+
if (obj.type === "subtask_delta") {
|
|
9002
|
+
const parentId = str3(obj.childSessionID) ?? str3(obj.childSessionId);
|
|
9003
|
+
const delta = str3(obj.delta);
|
|
9004
|
+
if (parentId && delta) {
|
|
9005
|
+
return withTaskParent(
|
|
9006
|
+
parentId,
|
|
9007
|
+
withEventParentId({ type: "thinking", data: delta }, parentId)
|
|
9008
|
+
);
|
|
9009
|
+
}
|
|
9010
|
+
return null;
|
|
9011
|
+
}
|
|
9012
|
+
if (obj.type === "subtask_event") {
|
|
9013
|
+
const parentId = str3(obj.childSessionID) ?? str3(obj.childSessionId);
|
|
9014
|
+
const part = asRecord4(obj.part);
|
|
9015
|
+
if (!parentId || !part) return null;
|
|
9016
|
+
if (part.type === "text" && str3(part.text)) {
|
|
9017
|
+
return withTaskParent(
|
|
9018
|
+
parentId,
|
|
9019
|
+
withEventParentId({ type: "stdout", data: str3(part.text) }, parentId)
|
|
9020
|
+
);
|
|
9021
|
+
}
|
|
9022
|
+
if (part.type === "tool" || str3(part.tool)) {
|
|
9023
|
+
const name = str3(part.tool) ?? str3(part.name) ?? "tool";
|
|
9024
|
+
const id = str3(part.callID) ?? str3(part.id) ?? `${parentId}-${name}`;
|
|
9025
|
+
const state = asRecord4(part.state);
|
|
9026
|
+
const input = asRecord4(state?.input) ?? asRecord4(part.input);
|
|
9027
|
+
const nested = [
|
|
9028
|
+
withEventParentId({ type: "tool_use", id, name, input }, parentId)
|
|
9029
|
+
];
|
|
9030
|
+
const output = state?.output ?? part.output;
|
|
9031
|
+
if (output != null || state?.status === "completed" || state?.status === "error") {
|
|
9032
|
+
nested.push(
|
|
9033
|
+
withEventParentId(
|
|
9034
|
+
{
|
|
9035
|
+
type: "tool_result",
|
|
9036
|
+
id,
|
|
9037
|
+
content: typeof output === "string" ? output : output != null ? JSON.stringify(output) : void 0,
|
|
9038
|
+
isError: state?.status === "error" || state?.status === "failed"
|
|
9039
|
+
},
|
|
9040
|
+
parentId
|
|
9041
|
+
)
|
|
9042
|
+
);
|
|
9043
|
+
}
|
|
9044
|
+
return withTaskParent(parentId, nested);
|
|
9045
|
+
}
|
|
9046
|
+
return null;
|
|
9047
|
+
}
|
|
8591
9048
|
if (obj.type === "tool_result") {
|
|
8592
9049
|
const part = obj.part;
|
|
8593
9050
|
const id = part?.tool_use_id ?? part?.id ?? obj.tool_use_id ?? obj.id;
|
|
@@ -9015,424 +9472,191 @@ async function installAgent(agent) {
|
|
|
9015
9472
|
stderr: result.stderr,
|
|
9016
9473
|
message: result.stderr.trim() || result.stdout.trim() || `npm install failed (exit ${result.exitCode})`
|
|
9017
9474
|
};
|
|
9018
|
-
}
|
|
9019
|
-
}
|
|
9020
|
-
enrichPathWithNpmGlobalBin();
|
|
9021
|
-
let binPath = null;
|
|
9022
|
-
if (cliBin) {
|
|
9023
|
-
binPath = await whichCli(cliBin);
|
|
9024
|
-
}
|
|
9025
|
-
return {
|
|
9026
|
-
ok: true,
|
|
9027
|
-
command: info.installCommand,
|
|
9028
|
-
exitCode: 0,
|
|
9029
|
-
stdout: result.stdout,
|
|
9030
|
-
stderr: result.stderr,
|
|
9031
|
-
message: binPath ? `Installed ${info.npmPackage} \u2192 ${binPath}` : `Installed ${info.npmPackage} (CLI not yet on PATH \u2014 Log in still exports Electron\u2019s PATH into Terminal)`
|
|
9032
|
-
};
|
|
9033
|
-
}
|
|
9034
|
-
async function loginAgent(agent) {
|
|
9035
|
-
const info = getAgentSetupInfo(agent);
|
|
9036
|
-
const loginCommand = resolveLoginCommand(agent);
|
|
9037
|
-
if (!loginCommand) {
|
|
9038
|
-
return {
|
|
9039
|
-
ok: true,
|
|
9040
|
-
message: info.kind === "bundled-sdk" || info.kind === "api-key" ? info.summary : `No login command for ${agent}`
|
|
9041
|
-
};
|
|
9042
|
-
}
|
|
9043
|
-
const prepared = await prepareTerminalCommand(loginCommand);
|
|
9044
|
-
await openInSystemTerminal(prepared);
|
|
9045
|
-
return {
|
|
9046
|
-
ok: true,
|
|
9047
|
-
openedTerminal: true,
|
|
9048
|
-
command: prepared,
|
|
9049
|
-
message: `Opened Terminal to run: ${prepared}`
|
|
9050
|
-
};
|
|
9051
|
-
}
|
|
9052
|
-
var SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
|
|
9053
|
-
var init_install = __esm({
|
|
9054
|
-
"src/agents/install.ts"() {
|
|
9055
|
-
"use strict";
|
|
9056
|
-
init_run();
|
|
9057
|
-
init_app_settings();
|
|
9058
|
-
init_path();
|
|
9059
|
-
SETUP = {
|
|
9060
|
-
claude: {
|
|
9061
|
-
agent: "claude",
|
|
9062
|
-
kind: "cli",
|
|
9063
|
-
summary: "Install the Claude Code CLI, then complete login in a terminal.",
|
|
9064
|
-
docsUrl: "https://code.claude.com/docs/en/install",
|
|
9065
|
-
installCommand: "npm install -g @anthropic-ai/claude-code",
|
|
9066
|
-
loginCommand: "claude auth login",
|
|
9067
|
-
npmPackage: "@anthropic-ai/claude-code"
|
|
9068
|
-
},
|
|
9069
|
-
codex: {
|
|
9070
|
-
agent: "codex",
|
|
9071
|
-
kind: "cli",
|
|
9072
|
-
summary: "Install the Codex CLI, then run login in a terminal.",
|
|
9073
|
-
docsUrl: "https://github.com/openai/codex",
|
|
9074
|
-
installCommand: "npm install -g @openai/codex",
|
|
9075
|
-
loginCommand: "codex login",
|
|
9076
|
-
npmPackage: "@openai/codex"
|
|
9077
|
-
},
|
|
9078
|
-
opencode: {
|
|
9079
|
-
agent: "opencode",
|
|
9080
|
-
kind: "cli",
|
|
9081
|
-
summary: "Install OpenCode (curl installer or npm), then authenticate providers.",
|
|
9082
|
-
docsUrl: "https://opencode.ai/docs",
|
|
9083
|
-
// Prefer the official installer; npm package name is opencode-ai.
|
|
9084
|
-
installCommand: "curl -fsSL https://opencode.ai/install | bash",
|
|
9085
|
-
loginCommand: "opencode auth login",
|
|
9086
|
-
npmPackage: "opencode-ai@latest"
|
|
9087
|
-
},
|
|
9088
|
-
cursor: {
|
|
9089
|
-
agent: "cursor",
|
|
9090
|
-
kind: "bundled-sdk",
|
|
9091
|
-
summary: "No CLI install \u2014 Sideboard ships the Cursor SDK. Add a CURSOR_API_KEY from the Cursor dashboard.",
|
|
9092
|
-
docsUrl: "https://cursor.com/dashboard/integrations",
|
|
9093
|
-
installCommand: null,
|
|
9094
|
-
loginCommand: null
|
|
9095
|
-
},
|
|
9096
|
-
brightsy: {
|
|
9097
|
-
agent: "brightsy",
|
|
9098
|
-
kind: "cli",
|
|
9099
|
-
summary: "Install the Brightsy CLI, then run `brightsy login`.",
|
|
9100
|
-
docsUrl: "https://www.npmjs.com/package/@brightsy/cli",
|
|
9101
|
-
installCommand: "npm install -g @brightsy/cli",
|
|
9102
|
-
loginCommand: "brightsy login",
|
|
9103
|
-
npmPackage: "@brightsy/cli"
|
|
9104
|
-
}
|
|
9105
|
-
};
|
|
9106
|
-
CLI_BIN = {
|
|
9107
|
-
claude: "claude",
|
|
9108
|
-
codex: "codex",
|
|
9109
|
-
opencode: "opencode",
|
|
9110
|
-
brightsy: "brightsy"
|
|
9111
|
-
};
|
|
9112
|
-
CLI_LOGIN_AGENTS = /* @__PURE__ */ new Set([
|
|
9113
|
-
"claude",
|
|
9114
|
-
"codex",
|
|
9115
|
-
"opencode",
|
|
9116
|
-
"brightsy"
|
|
9117
|
-
]);
|
|
9118
|
-
}
|
|
9119
|
-
});
|
|
9120
|
-
|
|
9121
|
-
// src/agents/index.ts
|
|
9122
|
-
var agents_exports = {};
|
|
9123
|
-
__export(agents_exports, {
|
|
9124
|
-
CLAUDE_MODEL_CATALOG: () => CLAUDE_MODEL_CATALOG,
|
|
9125
|
-
ORCHESTRATOR_AGENT_KINDS: () => ORCHESTRATOR_AGENT_KINDS,
|
|
9126
|
-
PLAN_MODE_INSTRUCTION: () => PLAN_MODE_INSTRUCTION,
|
|
9127
|
-
allAdapters: () => allAdapters,
|
|
9128
|
-
assertOrchestratorCapableAgent: () => assertOrchestratorCapableAgent,
|
|
9129
|
-
brightsyAdapter: () => brightsyAdapter,
|
|
9130
|
-
claudeAdapter: () => claudeAdapter,
|
|
9131
|
-
codexAdapter: () => codexAdapter,
|
|
9132
|
-
coerceOrchestratorAgent: () => coerceOrchestratorAgent,
|
|
9133
|
-
conductorBundledBinDir: () => conductorBundledBinDir,
|
|
9134
|
-
cursorAdapter: () => cursorAdapter,
|
|
9135
|
-
cursorSdkMessageToEvents: () => cursorSdkMessageToEvents,
|
|
9136
|
-
decodeBrightsyTarget: () => decodeBrightsyTarget,
|
|
9137
|
-
encodeBrightsyTarget: () => encodeBrightsyTarget,
|
|
9138
|
-
enrichPathWithNpmGlobalBin: () => enrichPathWithNpmGlobalBin,
|
|
9139
|
-
ensureAgentPath: () => ensureAgentPath,
|
|
9140
|
-
getAdapter: () => getAdapter,
|
|
9141
|
-
getAgentSetupInfo: () => getAgentSetupInfo,
|
|
9142
|
-
installAgent: () => installAgent,
|
|
9143
|
-
isConductorBundledCli: () => isConductorBundledCli,
|
|
9144
|
-
isCursorAutoModel: () => isCursorAutoModel,
|
|
9145
|
-
isOrchestratorCapableAgent: () => isOrchestratorCapableAgent,
|
|
9146
|
-
isSessionQuotaLimit: () => isSessionQuotaLimit,
|
|
9147
|
-
listAgentSetupInfo: () => listAgentSetupInfo,
|
|
9148
|
-
listBrightsyChatTargets: () => listBrightsyChatTargets,
|
|
9149
|
-
listCodexModels: () => listCodexModels,
|
|
9150
|
-
listCursorModels: () => listCursorModels,
|
|
9151
|
-
listModelsForAgent: () => listModelsForAgent,
|
|
9152
|
-
listOpencodeModels: () => listOpencodeModels,
|
|
9153
|
-
loginAgent: () => loginAgent,
|
|
9154
|
-
openInSystemTerminal: () => openInSystemTerminal,
|
|
9155
|
-
opencodeAdapter: () => opencodeAdapter,
|
|
9156
|
-
parseCursorRunnerLine: () => parseCursorRunnerLine,
|
|
9157
|
-
parseSessionQuotaResetAt: () => parseSessionQuotaResetAt,
|
|
9158
|
-
permissionMode: () => permissionMode,
|
|
9159
|
-
posixShellSingleQuote: () => posixShellSingleQuote,
|
|
9160
|
-
prepareTerminalCommand: () => prepareTerminalCommand,
|
|
9161
|
-
resolveCommandBinarySync: () => resolveCommandBinarySync,
|
|
9162
|
-
resolveCursorModelId: () => resolveCursorModelId,
|
|
9163
|
-
resolveLoginCommand: () => resolveLoginCommand,
|
|
9164
|
-
resolveQuotaFallbackAgent: () => resolveQuotaFallbackAgent,
|
|
9165
|
-
withExportedPath: () => withExportedPath
|
|
9166
|
-
});
|
|
9167
|
-
function getAdapter(kind) {
|
|
9168
|
-
return adapters[kind];
|
|
9169
|
-
}
|
|
9170
|
-
function allAdapters() {
|
|
9171
|
-
return Object.values(adapters);
|
|
9172
|
-
}
|
|
9173
|
-
var adapters;
|
|
9174
|
-
var init_agents = __esm({
|
|
9175
|
-
"src/agents/index.ts"() {
|
|
9176
|
-
"use strict";
|
|
9177
|
-
init_brightsy();
|
|
9178
|
-
init_claude();
|
|
9179
|
-
init_codex();
|
|
9180
|
-
init_cursor();
|
|
9181
|
-
init_opencode();
|
|
9182
|
-
init_types();
|
|
9183
|
-
init_brightsy();
|
|
9184
|
-
init_brightsy_targets();
|
|
9185
|
-
init_claude();
|
|
9186
|
-
init_codex();
|
|
9187
|
-
init_cursor();
|
|
9188
|
-
init_cursor_events();
|
|
9189
|
-
init_cursor();
|
|
9190
|
-
init_opencode();
|
|
9191
|
-
init_list_models();
|
|
9192
|
-
init_session_quota();
|
|
9193
|
-
init_orchestrator_capable();
|
|
9194
|
-
init_path();
|
|
9195
|
-
init_install();
|
|
9196
|
-
adapters = {
|
|
9197
|
-
claude: claudeAdapter,
|
|
9198
|
-
codex: codexAdapter,
|
|
9199
|
-
opencode: opencodeAdapter,
|
|
9200
|
-
brightsy: brightsyAdapter,
|
|
9201
|
-
cursor: cursorAdapter
|
|
9202
|
-
};
|
|
9203
|
-
}
|
|
9204
|
-
});
|
|
9205
|
-
|
|
9206
|
-
// src/agents/message-parts.ts
|
|
9207
|
-
function asRecord3(input) {
|
|
9208
|
-
if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
9209
|
-
return input;
|
|
9210
|
-
}
|
|
9211
|
-
return void 0;
|
|
9212
|
-
}
|
|
9213
|
-
function str2(v) {
|
|
9214
|
-
return typeof v === "string" && v.trim() ? v : void 0;
|
|
9215
|
-
}
|
|
9216
|
-
function toolDetail(name, input) {
|
|
9217
|
-
if (!input) return void 0;
|
|
9218
|
-
const command = str2(input.command) ?? str2(input.cmd);
|
|
9219
|
-
if (command) return command;
|
|
9220
|
-
const path = str2(input.file_path) ?? str2(input.path) ?? str2(input.filePath) ?? str2(input.filename);
|
|
9221
|
-
if (path) return path;
|
|
9222
|
-
const pattern = str2(input.pattern) ?? str2(input.glob) ?? str2(input.glob_pattern);
|
|
9223
|
-
if (pattern) return pattern;
|
|
9224
|
-
const query = str2(input.query) ?? str2(input.prompt);
|
|
9225
|
-
if (query) return query.length > 80 ? `${query.slice(0, 77)}\u2026` : query;
|
|
9226
|
-
try {
|
|
9227
|
-
const raw = JSON.stringify(input);
|
|
9228
|
-
return raw.length > 80 ? `${raw.slice(0, 77)}\u2026` : raw;
|
|
9229
|
-
} catch {
|
|
9230
|
-
return name;
|
|
9231
|
-
}
|
|
9232
|
-
}
|
|
9233
|
-
function toolDescription(name, input) {
|
|
9234
|
-
const n = name.replace(/^mcp__/, "").replace(/__/g, " \xB7 ");
|
|
9235
|
-
if (/^get_record_types$|recordTypes/i.test(name)) return "List record types";
|
|
9236
|
-
if (/connectedAgentRequest/i.test(name)) {
|
|
9237
|
-
return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
|
|
9238
|
-
}
|
|
9239
|
-
if (/present_artifact$/i.test(name)) {
|
|
9240
|
-
return str2(input?.title) ? `Present ${str2(input?.title)}` : "Present artifact";
|
|
9241
|
-
}
|
|
9242
|
-
if (/present_plan$/i.test(name)) {
|
|
9243
|
-
return str2(input?.title) ? `Plan ${str2(input?.title)}` : "Present plan";
|
|
9244
|
-
}
|
|
9245
|
-
if (/present_schema$/i.test(name)) {
|
|
9246
|
-
return str2(input?.title) ? `Schema ${str2(input?.title)}` : "Present schema";
|
|
9247
|
-
}
|
|
9248
|
-
if (/present_files$/i.test(name)) {
|
|
9249
|
-
return str2(input?.title) ? `Files ${str2(input?.title)}` : "Present files";
|
|
9250
|
-
}
|
|
9251
|
-
if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
|
|
9252
|
-
return str2(input?.title) ? `Artifact ${str2(input?.title)}` : "Artifact";
|
|
9253
|
-
}
|
|
9254
|
-
if (!input) return n;
|
|
9255
|
-
if (/bash|shell|terminal/i.test(name) && str2(input.command)) {
|
|
9256
|
-
const cmd = str2(input.command);
|
|
9257
|
-
if (/git\s+fetch/i.test(cmd)) return "Fetch latest from origin and check status";
|
|
9258
|
-
if (/git\s+status/i.test(cmd)) return "Check git status";
|
|
9259
|
-
if (/git\s+log/i.test(cmd)) return "Inspect recent commits";
|
|
9260
|
-
if (/git\s+branch/i.test(cmd)) return "List branches";
|
|
9261
|
-
if (/grep|rg\b/i.test(cmd)) return "Search repository";
|
|
9262
|
-
return "Run shell command";
|
|
9263
|
-
}
|
|
9264
|
-
if (/edit|write|apply/i.test(name)) {
|
|
9265
|
-
const path = str2(input.file_path) ?? str2(input.path);
|
|
9266
|
-
return path ? `Edit ${path.split("/").pop()}` : "Edit file";
|
|
9267
|
-
}
|
|
9268
|
-
if (/read/i.test(name)) {
|
|
9269
|
-
const path = str2(input.file_path) ?? str2(input.path);
|
|
9270
|
-
return path ? `Read ${path.split("/").pop()}` : "Read file";
|
|
9271
|
-
}
|
|
9272
|
-
if (/grep/i.test(name)) return "Search files";
|
|
9273
|
-
if (/glob/i.test(name)) return "Find files";
|
|
9274
|
-
return n;
|
|
9275
|
-
}
|
|
9276
|
-
function toolFilePath(input) {
|
|
9277
|
-
if (!input) return void 0;
|
|
9278
|
-
return str2(input.file_path) ?? str2(input.path) ?? str2(input.filePath) ?? str2(input.filename);
|
|
9279
|
-
}
|
|
9280
|
-
function countLines(text4) {
|
|
9281
|
-
if (!text4) return 0;
|
|
9282
|
-
return text4.split("\n").length;
|
|
9283
|
-
}
|
|
9284
|
-
function diffFromInput(input) {
|
|
9285
|
-
if (!input) return {};
|
|
9286
|
-
const oldS = str2(input.old_string) ?? str2(input.oldString);
|
|
9287
|
-
const newS = str2(input.new_string) ?? str2(input.newString) ?? str2(input.content);
|
|
9288
|
-
if (oldS != null || newS != null) {
|
|
9289
|
-
return {
|
|
9290
|
-
additions: countLines(newS),
|
|
9291
|
-
deletions: countLines(oldS)
|
|
9292
|
-
};
|
|
9293
|
-
}
|
|
9294
|
-
return {};
|
|
9295
|
-
}
|
|
9296
|
-
function parseDiffStat(result) {
|
|
9297
|
-
if (!result) return {};
|
|
9298
|
-
const paired = result.match(/\+(\d+)\s+-(\d+)/);
|
|
9299
|
-
if (paired) {
|
|
9300
|
-
return {
|
|
9301
|
-
additions: Number(paired[1]),
|
|
9302
|
-
deletions: Number(paired[2])
|
|
9303
|
-
};
|
|
9304
|
-
}
|
|
9305
|
-
const verbose = result.match(
|
|
9306
|
-
/(\d+)\s+insertions?(?:,\s*(\d+)\s+deletions?)?/i
|
|
9307
|
-
);
|
|
9308
|
-
if (verbose) {
|
|
9309
|
-
return {
|
|
9310
|
-
additions: Number(verbose[1]),
|
|
9311
|
-
deletions: verbose[2] != null ? Number(verbose[2]) : void 0
|
|
9312
|
-
};
|
|
9313
|
-
}
|
|
9314
|
-
return {};
|
|
9315
|
-
}
|
|
9316
|
-
function applyAgentEvent(parts, event) {
|
|
9317
|
-
if (event.type === "stdout") {
|
|
9318
|
-
const data = event.data;
|
|
9319
|
-
if (!data) return parts;
|
|
9320
|
-
const next = [...parts];
|
|
9321
|
-
const last = next[next.length - 1];
|
|
9322
|
-
if (last?.type === "text") {
|
|
9323
|
-
next[next.length - 1] = { type: "text", text: last.text + data };
|
|
9324
|
-
} else {
|
|
9325
|
-
next.push({ type: "text", text: data });
|
|
9326
|
-
}
|
|
9327
|
-
return next;
|
|
9328
|
-
}
|
|
9329
|
-
if (event.type === "thinking") {
|
|
9330
|
-
const data = event.data;
|
|
9331
|
-
if (!data) return parts;
|
|
9332
|
-
const next = [...parts];
|
|
9333
|
-
const last = next[next.length - 1];
|
|
9334
|
-
if (last?.type === "thinking") {
|
|
9335
|
-
next[next.length - 1] = { type: "thinking", text: last.text + data };
|
|
9336
|
-
} else {
|
|
9337
|
-
next.push({ type: "thinking", text: data });
|
|
9338
|
-
}
|
|
9339
|
-
return next;
|
|
9340
|
-
}
|
|
9341
|
-
if (event.type === "tool_use") {
|
|
9342
|
-
const input = asRecord3(event.input);
|
|
9343
|
-
const diff = diffFromInput(input);
|
|
9344
|
-
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
9345
|
-
if (existing >= 0) {
|
|
9346
|
-
const prev = parts[existing];
|
|
9347
|
-
const next = [...parts];
|
|
9348
|
-
next[existing] = {
|
|
9349
|
-
...prev,
|
|
9350
|
-
name: event.name || prev.name,
|
|
9351
|
-
input: input ?? prev.input,
|
|
9352
|
-
description: toolDescription(event.name || prev.name, input ?? prev.input),
|
|
9353
|
-
detail: toolDetail(event.name || prev.name, input ?? prev.input) ?? prev.detail,
|
|
9354
|
-
filePath: toolFilePath(input) ?? prev.filePath,
|
|
9355
|
-
additions: diff.additions ?? prev.additions,
|
|
9356
|
-
deletions: diff.deletions ?? prev.deletions
|
|
9357
|
-
};
|
|
9358
|
-
return next;
|
|
9359
|
-
}
|
|
9360
|
-
return [
|
|
9361
|
-
...parts,
|
|
9362
|
-
{
|
|
9363
|
-
type: "tool",
|
|
9364
|
-
id: event.id,
|
|
9365
|
-
name: event.name,
|
|
9366
|
-
input,
|
|
9367
|
-
description: toolDescription(event.name, input),
|
|
9368
|
-
detail: toolDetail(event.name, input),
|
|
9369
|
-
status: "running",
|
|
9370
|
-
filePath: toolFilePath(input),
|
|
9371
|
-
...diff
|
|
9372
|
-
}
|
|
9373
|
-
];
|
|
9374
|
-
}
|
|
9375
|
-
if (event.type === "tool_result") {
|
|
9376
|
-
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
9377
|
-
const fromResult = parseDiffStat(event.content);
|
|
9378
|
-
if (existing < 0) {
|
|
9379
|
-
return [
|
|
9380
|
-
...parts,
|
|
9381
|
-
{
|
|
9382
|
-
type: "tool",
|
|
9383
|
-
id: event.id,
|
|
9384
|
-
name: "tool",
|
|
9385
|
-
description: "tool",
|
|
9386
|
-
status: event.isError ? "error" : "done",
|
|
9387
|
-
result: event.content,
|
|
9388
|
-
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
9389
|
-
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
9390
|
-
}
|
|
9391
|
-
];
|
|
9392
|
-
}
|
|
9393
|
-
return parts.map((p, i) => {
|
|
9394
|
-
if (i !== existing || p.type !== "tool") return p;
|
|
9395
|
-
return {
|
|
9396
|
-
...p,
|
|
9397
|
-
status: event.isError ? "error" : "done",
|
|
9398
|
-
result: event.content,
|
|
9399
|
-
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
9400
|
-
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
9401
|
-
};
|
|
9402
|
-
});
|
|
9475
|
+
}
|
|
9403
9476
|
}
|
|
9404
|
-
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
}
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
return out.trim();
|
|
9477
|
+
enrichPathWithNpmGlobalBin();
|
|
9478
|
+
let binPath = null;
|
|
9479
|
+
if (cliBin) {
|
|
9480
|
+
binPath = await whichCli(cliBin);
|
|
9481
|
+
}
|
|
9482
|
+
return {
|
|
9483
|
+
ok: true,
|
|
9484
|
+
command: info.installCommand,
|
|
9485
|
+
exitCode: 0,
|
|
9486
|
+
stdout: result.stdout,
|
|
9487
|
+
stderr: result.stderr,
|
|
9488
|
+
message: binPath ? `Installed ${info.npmPackage} \u2192 ${binPath}` : `Installed ${info.npmPackage} (CLI not yet on PATH \u2014 Log in still exports Electron\u2019s PATH into Terminal)`
|
|
9489
|
+
};
|
|
9418
9490
|
}
|
|
9419
|
-
function
|
|
9420
|
-
const
|
|
9421
|
-
|
|
9422
|
-
|
|
9491
|
+
async function loginAgent(agent) {
|
|
9492
|
+
const info = getAgentSetupInfo(agent);
|
|
9493
|
+
const loginCommand = resolveLoginCommand(agent);
|
|
9494
|
+
if (!loginCommand) {
|
|
9495
|
+
return {
|
|
9496
|
+
ok: true,
|
|
9497
|
+
message: info.kind === "bundled-sdk" || info.kind === "api-key" ? info.summary : `No login command for ${agent}`
|
|
9498
|
+
};
|
|
9499
|
+
}
|
|
9500
|
+
const prepared = await prepareTerminalCommand(loginCommand);
|
|
9501
|
+
await openInSystemTerminal(prepared);
|
|
9502
|
+
return {
|
|
9503
|
+
ok: true,
|
|
9504
|
+
openedTerminal: true,
|
|
9505
|
+
command: prepared,
|
|
9506
|
+
message: `Opened Terminal to run: ${prepared}`
|
|
9507
|
+
};
|
|
9423
9508
|
}
|
|
9424
|
-
|
|
9425
|
-
|
|
9426
|
-
|
|
9427
|
-
|
|
9509
|
+
var SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
|
|
9510
|
+
var init_install = __esm({
|
|
9511
|
+
"src/agents/install.ts"() {
|
|
9512
|
+
"use strict";
|
|
9513
|
+
init_run();
|
|
9514
|
+
init_app_settings();
|
|
9515
|
+
init_path();
|
|
9516
|
+
SETUP = {
|
|
9517
|
+
claude: {
|
|
9518
|
+
agent: "claude",
|
|
9519
|
+
kind: "cli",
|
|
9520
|
+
summary: "Install the Claude Code CLI, then complete login in a terminal.",
|
|
9521
|
+
docsUrl: "https://code.claude.com/docs/en/install",
|
|
9522
|
+
installCommand: "npm install -g @anthropic-ai/claude-code",
|
|
9523
|
+
loginCommand: "claude auth login",
|
|
9524
|
+
npmPackage: "@anthropic-ai/claude-code"
|
|
9525
|
+
},
|
|
9526
|
+
codex: {
|
|
9527
|
+
agent: "codex",
|
|
9528
|
+
kind: "cli",
|
|
9529
|
+
summary: "Install the Codex CLI, then run login in a terminal.",
|
|
9530
|
+
docsUrl: "https://github.com/openai/codex",
|
|
9531
|
+
installCommand: "npm install -g @openai/codex",
|
|
9532
|
+
loginCommand: "codex login",
|
|
9533
|
+
npmPackage: "@openai/codex"
|
|
9534
|
+
},
|
|
9535
|
+
opencode: {
|
|
9536
|
+
agent: "opencode",
|
|
9537
|
+
kind: "cli",
|
|
9538
|
+
summary: "Install OpenCode (curl installer or npm), then authenticate providers.",
|
|
9539
|
+
docsUrl: "https://opencode.ai/docs",
|
|
9540
|
+
// Prefer the official installer; npm package name is opencode-ai.
|
|
9541
|
+
installCommand: "curl -fsSL https://opencode.ai/install | bash",
|
|
9542
|
+
loginCommand: "opencode auth login",
|
|
9543
|
+
npmPackage: "opencode-ai@latest"
|
|
9544
|
+
},
|
|
9545
|
+
cursor: {
|
|
9546
|
+
agent: "cursor",
|
|
9547
|
+
kind: "bundled-sdk",
|
|
9548
|
+
summary: "No CLI install \u2014 Sideboard ships the Cursor SDK. Add a CURSOR_API_KEY from the Cursor dashboard.",
|
|
9549
|
+
docsUrl: "https://cursor.com/dashboard/integrations",
|
|
9550
|
+
installCommand: null,
|
|
9551
|
+
loginCommand: null
|
|
9552
|
+
},
|
|
9553
|
+
brightsy: {
|
|
9554
|
+
agent: "brightsy",
|
|
9555
|
+
kind: "cli",
|
|
9556
|
+
summary: "Install the Brightsy CLI, then run `brightsy login`.",
|
|
9557
|
+
docsUrl: "https://www.npmjs.com/package/@brightsy/cli",
|
|
9558
|
+
installCommand: "npm install -g @brightsy/cli",
|
|
9559
|
+
loginCommand: "brightsy login",
|
|
9560
|
+
npmPackage: "@brightsy/cli"
|
|
9561
|
+
}
|
|
9562
|
+
};
|
|
9563
|
+
CLI_BIN = {
|
|
9564
|
+
claude: "claude",
|
|
9565
|
+
codex: "codex",
|
|
9566
|
+
opencode: "opencode",
|
|
9567
|
+
brightsy: "brightsy"
|
|
9568
|
+
};
|
|
9569
|
+
CLI_LOGIN_AGENTS = /* @__PURE__ */ new Set([
|
|
9570
|
+
"claude",
|
|
9571
|
+
"codex",
|
|
9572
|
+
"opencode",
|
|
9573
|
+
"brightsy"
|
|
9574
|
+
]);
|
|
9575
|
+
}
|
|
9576
|
+
});
|
|
9577
|
+
|
|
9578
|
+
// src/agents/index.ts
|
|
9579
|
+
var agents_exports = {};
|
|
9580
|
+
__export(agents_exports, {
|
|
9581
|
+
CLAUDE_MODEL_CATALOG: () => CLAUDE_MODEL_CATALOG,
|
|
9582
|
+
ORCHESTRATOR_AGENT_KINDS: () => ORCHESTRATOR_AGENT_KINDS,
|
|
9583
|
+
PLAN_MODE_INSTRUCTION: () => PLAN_MODE_INSTRUCTION,
|
|
9584
|
+
allAdapters: () => allAdapters,
|
|
9585
|
+
assertOrchestratorCapableAgent: () => assertOrchestratorCapableAgent,
|
|
9586
|
+
brightsyAdapter: () => brightsyAdapter,
|
|
9587
|
+
claudeAdapter: () => claudeAdapter,
|
|
9588
|
+
codexAdapter: () => codexAdapter,
|
|
9589
|
+
coerceOrchestratorAgent: () => coerceOrchestratorAgent,
|
|
9590
|
+
conductorBundledBinDir: () => conductorBundledBinDir,
|
|
9591
|
+
cursorAdapter: () => cursorAdapter,
|
|
9592
|
+
cursorSdkMessageToEvents: () => cursorSdkMessageToEvents,
|
|
9593
|
+
decodeBrightsyTarget: () => decodeBrightsyTarget,
|
|
9594
|
+
encodeBrightsyTarget: () => encodeBrightsyTarget,
|
|
9595
|
+
enrichPathWithNpmGlobalBin: () => enrichPathWithNpmGlobalBin,
|
|
9596
|
+
ensureAgentPath: () => ensureAgentPath,
|
|
9597
|
+
getAdapter: () => getAdapter,
|
|
9598
|
+
getAgentSetupInfo: () => getAgentSetupInfo,
|
|
9599
|
+
installAgent: () => installAgent,
|
|
9600
|
+
isConductorBundledCli: () => isConductorBundledCli,
|
|
9601
|
+
isCursorAutoModel: () => isCursorAutoModel,
|
|
9602
|
+
isOrchestratorCapableAgent: () => isOrchestratorCapableAgent,
|
|
9603
|
+
isSessionQuotaLimit: () => isSessionQuotaLimit,
|
|
9604
|
+
listAgentSetupInfo: () => listAgentSetupInfo,
|
|
9605
|
+
listBrightsyChatTargets: () => listBrightsyChatTargets,
|
|
9606
|
+
listCodexModels: () => listCodexModels,
|
|
9607
|
+
listCursorModels: () => listCursorModels,
|
|
9608
|
+
listModelsForAgent: () => listModelsForAgent,
|
|
9609
|
+
listOpencodeModels: () => listOpencodeModels,
|
|
9610
|
+
loginAgent: () => loginAgent,
|
|
9611
|
+
openInSystemTerminal: () => openInSystemTerminal,
|
|
9612
|
+
opencodeAdapter: () => opencodeAdapter,
|
|
9613
|
+
parseCursorRunnerLine: () => parseCursorRunnerLine,
|
|
9614
|
+
parseSessionQuotaResetAt: () => parseSessionQuotaResetAt,
|
|
9615
|
+
permissionMode: () => permissionMode,
|
|
9616
|
+
posixShellSingleQuote: () => posixShellSingleQuote,
|
|
9617
|
+
prepareTerminalCommand: () => prepareTerminalCommand,
|
|
9618
|
+
resolveCommandBinarySync: () => resolveCommandBinarySync,
|
|
9619
|
+
resolveCursorModelId: () => resolveCursorModelId,
|
|
9620
|
+
resolveLoginCommand: () => resolveLoginCommand,
|
|
9621
|
+
resolveQuotaFallbackAgent: () => resolveQuotaFallbackAgent,
|
|
9622
|
+
withExportedPath: () => withExportedPath
|
|
9623
|
+
});
|
|
9624
|
+
function getAdapter(kind) {
|
|
9625
|
+
return adapters[kind];
|
|
9428
9626
|
}
|
|
9429
|
-
function
|
|
9430
|
-
|
|
9431
|
-
return Array.isArray(parsed) ? parsed : [parsed];
|
|
9627
|
+
function allAdapters() {
|
|
9628
|
+
return Object.values(adapters);
|
|
9432
9629
|
}
|
|
9433
|
-
var
|
|
9434
|
-
|
|
9630
|
+
var adapters;
|
|
9631
|
+
var init_agents = __esm({
|
|
9632
|
+
"src/agents/index.ts"() {
|
|
9435
9633
|
"use strict";
|
|
9634
|
+
init_brightsy();
|
|
9635
|
+
init_claude();
|
|
9636
|
+
init_codex();
|
|
9637
|
+
init_cursor();
|
|
9638
|
+
init_opencode();
|
|
9639
|
+
init_types();
|
|
9640
|
+
init_brightsy();
|
|
9641
|
+
init_brightsy_targets();
|
|
9642
|
+
init_claude();
|
|
9643
|
+
init_codex();
|
|
9644
|
+
init_cursor();
|
|
9645
|
+
init_cursor_events();
|
|
9646
|
+
init_cursor();
|
|
9647
|
+
init_opencode();
|
|
9648
|
+
init_list_models();
|
|
9649
|
+
init_session_quota();
|
|
9650
|
+
init_orchestrator_capable();
|
|
9651
|
+
init_path();
|
|
9652
|
+
init_install();
|
|
9653
|
+
adapters = {
|
|
9654
|
+
claude: claudeAdapter,
|
|
9655
|
+
codex: codexAdapter,
|
|
9656
|
+
opencode: opencodeAdapter,
|
|
9657
|
+
brightsy: brightsyAdapter,
|
|
9658
|
+
cursor: cursorAdapter
|
|
9659
|
+
};
|
|
9436
9660
|
}
|
|
9437
9661
|
});
|
|
9438
9662
|
|
|
@@ -9440,6 +9664,9 @@ var init_message_parts = __esm({
|
|
|
9440
9664
|
function isTextEvent(event) {
|
|
9441
9665
|
return event.type === "stdout" || event.type === "thinking";
|
|
9442
9666
|
}
|
|
9667
|
+
function parentKey(event) {
|
|
9668
|
+
return event.parentId ?? "";
|
|
9669
|
+
}
|
|
9443
9670
|
function createAgentStreamCoalescer(emit, opts) {
|
|
9444
9671
|
const intervalMs = opts?.intervalMs ?? 32;
|
|
9445
9672
|
let pending = null;
|
|
@@ -9452,7 +9679,11 @@ function createAgentStreamCoalescer(emit, opts) {
|
|
|
9452
9679
|
if (!pending) return;
|
|
9453
9680
|
const event = pending;
|
|
9454
9681
|
pending = null;
|
|
9455
|
-
emit({
|
|
9682
|
+
emit({
|
|
9683
|
+
type: event.type,
|
|
9684
|
+
data: event.data,
|
|
9685
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
9686
|
+
});
|
|
9456
9687
|
};
|
|
9457
9688
|
const schedule = () => {
|
|
9458
9689
|
if (timer) return;
|
|
@@ -9467,11 +9698,15 @@ function createAgentStreamCoalescer(emit, opts) {
|
|
|
9467
9698
|
return;
|
|
9468
9699
|
}
|
|
9469
9700
|
if (!event.data) return;
|
|
9470
|
-
if (pending && pending.type === event.type) {
|
|
9701
|
+
if (pending && pending.type === event.type && parentKey(pending) === parentKey(event)) {
|
|
9471
9702
|
pending.data += event.data;
|
|
9472
9703
|
} else {
|
|
9473
9704
|
flush2();
|
|
9474
|
-
pending = {
|
|
9705
|
+
pending = {
|
|
9706
|
+
type: event.type,
|
|
9707
|
+
data: event.data,
|
|
9708
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
9709
|
+
};
|
|
9475
9710
|
}
|
|
9476
9711
|
schedule();
|
|
9477
9712
|
},
|
|
@@ -10101,7 +10336,8 @@ function worktreeBindingFrom(from) {
|
|
|
10101
10336
|
prState: from.prState,
|
|
10102
10337
|
skipAutoArchiveOnMerge: from.skipAutoArchiveOnMerge,
|
|
10103
10338
|
stackId: from.stackId,
|
|
10104
|
-
stackLayer: from.stackLayer
|
|
10339
|
+
stackLayer: from.stackLayer,
|
|
10340
|
+
cowboy: from.cowboy
|
|
10105
10341
|
};
|
|
10106
10342
|
}
|
|
10107
10343
|
function threadsSharingWorktree(worktreePath) {
|
|
@@ -11294,6 +11530,55 @@ async function createThread(input, _onSetupLine) {
|
|
|
11294
11530
|
if (!(0, import_node_fs32.existsSync)(repoPath)) {
|
|
11295
11531
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
11296
11532
|
}
|
|
11533
|
+
if (input.cowboy) {
|
|
11534
|
+
const { cowboyModeEnabled: cowboyModeEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
11535
|
+
if (!cowboyModeEnabled2()) {
|
|
11536
|
+
throw new Error(
|
|
11537
|
+
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
11538
|
+
);
|
|
11539
|
+
}
|
|
11540
|
+
if (input.sourceType === "pr" || input.sourceType === "ticket" || input.sourceType === "adopt") {
|
|
11541
|
+
throw new Error(
|
|
11542
|
+
"Cowboy mode works on the project folder (default branch), not a PR, ticket, or adopt."
|
|
11543
|
+
);
|
|
11544
|
+
}
|
|
11545
|
+
const defaultBranch = await resolveDefaultBranch(repoPath, { network: false });
|
|
11546
|
+
const head = await currentBranch(repoPath);
|
|
11547
|
+
if (head === "HEAD") {
|
|
11548
|
+
throw new Error(
|
|
11549
|
+
"Cowboy mode needs a named branch in the project folder (not a detached HEAD)."
|
|
11550
|
+
);
|
|
11551
|
+
}
|
|
11552
|
+
if (head !== defaultBranch) {
|
|
11553
|
+
throw new Error(
|
|
11554
|
+
`Cowboy mode uses ${defaultBranch} in the project folder. Switch that checkout to ${defaultBranch} first (currently ${head}).`
|
|
11555
|
+
);
|
|
11556
|
+
}
|
|
11557
|
+
const explicitTitle2 = input.title?.trim();
|
|
11558
|
+
const thread2 = createEmptyThread({
|
|
11559
|
+
title: explicitTitle2 || `Cowboy \xB7 ${head}`,
|
|
11560
|
+
userSetTitle: Boolean(explicitTitle2),
|
|
11561
|
+
sourceType: "branch",
|
|
11562
|
+
sourceRef: head,
|
|
11563
|
+
branchName: head,
|
|
11564
|
+
worktreePath: repoPath,
|
|
11565
|
+
repoPath,
|
|
11566
|
+
agent: resolved.agent,
|
|
11567
|
+
autonomy: input.autonomy ?? "default",
|
|
11568
|
+
model: resolved.model,
|
|
11569
|
+
effort: resolved.effort,
|
|
11570
|
+
fast: resolved.fast,
|
|
11571
|
+
planMode: Boolean(input.planMode),
|
|
11572
|
+
attachments: input.attachments ?? [],
|
|
11573
|
+
sourceIsFork: false,
|
|
11574
|
+
parentThreadId: input.parentThreadId ?? null,
|
|
11575
|
+
status: "idle",
|
|
11576
|
+
cowboy: true
|
|
11577
|
+
});
|
|
11578
|
+
writeThread(thread2);
|
|
11579
|
+
await ensureWorkspace(repoPath);
|
|
11580
|
+
return readThread(thread2.id) ?? thread2;
|
|
11581
|
+
}
|
|
11297
11582
|
let sourceRef = input.sourceRef;
|
|
11298
11583
|
let sourceIsFork = false;
|
|
11299
11584
|
let prUrl = null;
|
|
@@ -11379,6 +11664,24 @@ var init_create = __esm({
|
|
|
11379
11664
|
}
|
|
11380
11665
|
});
|
|
11381
11666
|
|
|
11667
|
+
// src/threads/cowboy.ts
|
|
11668
|
+
function isCowboyThread(thread) {
|
|
11669
|
+
return Boolean(thread?.cowboy);
|
|
11670
|
+
}
|
|
11671
|
+
function isPrimaryCheckoutThread(thread) {
|
|
11672
|
+
if (!thread?.worktreePath || !thread.repoPath) return false;
|
|
11673
|
+
return normalizeWorktreePath(thread.worktreePath) === normalizeWorktreePath(thread.repoPath);
|
|
11674
|
+
}
|
|
11675
|
+
function shouldRemoveWorktreeOnTeardown(thread) {
|
|
11676
|
+
return !isCowboyThread(thread) && !isPrimaryCheckoutThread(thread);
|
|
11677
|
+
}
|
|
11678
|
+
var init_cowboy = __esm({
|
|
11679
|
+
"src/threads/cowboy.ts"() {
|
|
11680
|
+
"use strict";
|
|
11681
|
+
init_worktree_labels();
|
|
11682
|
+
}
|
|
11683
|
+
});
|
|
11684
|
+
|
|
11382
11685
|
// src/store/turn-live.ts
|
|
11383
11686
|
function trimParts(parts) {
|
|
11384
11687
|
if (parts.length <= MAX_PARTS) return parts;
|
|
@@ -11672,8 +11975,12 @@ var init_quota_failover = __esm({
|
|
|
11672
11975
|
});
|
|
11673
11976
|
|
|
11674
11977
|
// src/threads/adopt.ts
|
|
11978
|
+
function thisModuleFile() {
|
|
11979
|
+
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
11980
|
+
return cjsFile || process.argv[1] || (0, import_node_path31.join)(process.cwd(), "package.json");
|
|
11981
|
+
}
|
|
11675
11982
|
function openReadonlySqlite(file) {
|
|
11676
|
-
const req = (0, import_node_module4.createRequire)(
|
|
11983
|
+
const req = (0, import_node_module4.createRequire)(thisModuleFile());
|
|
11677
11984
|
const Database = req("better-sqlite3");
|
|
11678
11985
|
return new Database(file, { readonly: true, fileMustExist: true });
|
|
11679
11986
|
}
|
|
@@ -11939,7 +12246,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
11939
12246
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
11940
12247
|
return importConductorWorkspace(workspaceId);
|
|
11941
12248
|
}
|
|
11942
|
-
var import_node_child_process3, import_node_fs34, import_node_os10, import_node_path31, import_node_module4,
|
|
12249
|
+
var import_node_child_process3, import_node_fs34, import_node_os10, import_node_path31, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
|
|
11943
12250
|
var init_adopt = __esm({
|
|
11944
12251
|
"src/threads/adopt.ts"() {
|
|
11945
12252
|
"use strict";
|
|
@@ -11950,7 +12257,6 @@ var init_adopt = __esm({
|
|
|
11950
12257
|
import_node_module4 = require("module");
|
|
11951
12258
|
init_worktree();
|
|
11952
12259
|
init_thread_store();
|
|
11953
|
-
import_meta4 = {};
|
|
11954
12260
|
CONDUCTOR_APP_SUPPORT = (0, import_node_path31.join)(
|
|
11955
12261
|
process.env.HOME ?? "",
|
|
11956
12262
|
"Library",
|
|
@@ -13021,13 +13327,22 @@ async function previewLand(thread) {
|
|
|
13021
13327
|
isFork: true
|
|
13022
13328
|
};
|
|
13023
13329
|
}
|
|
13024
|
-
|
|
13025
|
-
|
|
13330
|
+
if (isCowboyThread(thread)) {
|
|
13331
|
+
const current2 = await currentBranch(thread.worktreePath);
|
|
13332
|
+
const dirty = await isDirty(thread.worktreePath);
|
|
13333
|
+
const diff2 = await getDiff(thread.worktreePath, thread.repoPath, { base: current2 });
|
|
13334
|
+
return {
|
|
13335
|
+
branch: current2,
|
|
13336
|
+
target: current2,
|
|
13337
|
+
diffStat: diff2.stat,
|
|
13338
|
+
dirty,
|
|
13339
|
+
blocked: false,
|
|
13340
|
+
isFork: false,
|
|
13341
|
+
cowboy: true
|
|
13342
|
+
};
|
|
13026
13343
|
}
|
|
13027
|
-
const
|
|
13028
|
-
|
|
13029
|
-
);
|
|
13030
|
-
const current = head.trim();
|
|
13344
|
+
const target = await resolveDefaultBranch(thread.repoPath);
|
|
13345
|
+
const current = await currentBranch(thread.worktreePath);
|
|
13031
13346
|
if (current === target) {
|
|
13032
13347
|
return {
|
|
13033
13348
|
branch: current,
|
|
@@ -13054,6 +13369,19 @@ async function confirmLand(thread, opts) {
|
|
|
13054
13369
|
if (preview.blocked) {
|
|
13055
13370
|
throw new Error(preview.blockReason ?? "Land blocked");
|
|
13056
13371
|
}
|
|
13372
|
+
if (preview.cowboy) {
|
|
13373
|
+
const meta2 = await suggestPrMetadata(thread.worktreePath, {
|
|
13374
|
+
base: preview.branch,
|
|
13375
|
+
fallbackTitle: thread.title,
|
|
13376
|
+
sourceLabel: `${thread.sourceType}:${thread.sourceRef}`
|
|
13377
|
+
});
|
|
13378
|
+
let committed2 = false;
|
|
13379
|
+
if (preview.dirty) {
|
|
13380
|
+
committed2 = await commitAll(thread.worktreePath, meta2.commitMessage);
|
|
13381
|
+
}
|
|
13382
|
+
await pushBranch(thread.worktreePath, preview.branch);
|
|
13383
|
+
return { prUrl: null, pushed: true, committed: committed2 };
|
|
13384
|
+
}
|
|
13057
13385
|
const meta = await suggestPrMetadata(thread.worktreePath, {
|
|
13058
13386
|
base: preview.target,
|
|
13059
13387
|
fallbackTitle: thread.title,
|
|
@@ -13098,6 +13426,7 @@ var init_land = __esm({
|
|
|
13098
13426
|
init_diff();
|
|
13099
13427
|
init_pr_metadata();
|
|
13100
13428
|
init_gh_errors();
|
|
13429
|
+
init_cowboy();
|
|
13101
13430
|
}
|
|
13102
13431
|
});
|
|
13103
13432
|
|
|
@@ -13683,7 +14012,7 @@ var init_instructions = __esm({
|
|
|
13683
14012
|
});
|
|
13684
14013
|
|
|
13685
14014
|
// src/plan/plan-present.ts
|
|
13686
|
-
function
|
|
14015
|
+
function asRecord5(v) {
|
|
13687
14016
|
return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
13688
14017
|
}
|
|
13689
14018
|
function isPresentPlanToolName(name) {
|
|
@@ -13695,7 +14024,7 @@ function extractPresentedPlan(parts) {
|
|
|
13695
14024
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
13696
14025
|
const p = parts[i];
|
|
13697
14026
|
if (p.type !== "tool" || !isPresentPlanToolName(p.name)) continue;
|
|
13698
|
-
const input =
|
|
14027
|
+
const input = asRecord5(p.input) ?? {};
|
|
13699
14028
|
const content = typeof input.content === "string" ? input.content : typeof input.plan === "string" ? input.plan : typeof input.markdown === "string" ? input.markdown : "";
|
|
13700
14029
|
if (!content.trim()) continue;
|
|
13701
14030
|
const title = typeof input.title === "string" && input.title.trim() ? input.title.trim() : "Plan";
|
|
@@ -14558,6 +14887,7 @@ var init_orchestrator = __esm({
|
|
|
14558
14887
|
init_thread_store();
|
|
14559
14888
|
init_desktop_host();
|
|
14560
14889
|
init_create();
|
|
14890
|
+
init_cowboy();
|
|
14561
14891
|
init_orchestrator_capable();
|
|
14562
14892
|
init_chat_tabs();
|
|
14563
14893
|
init_enqueue_by_key();
|
|
@@ -14834,7 +15164,9 @@ var init_orchestrator = __esm({
|
|
|
14834
15164
|
return thread;
|
|
14835
15165
|
}
|
|
14836
15166
|
async finishCreateThread(threadId, prompt) {
|
|
14837
|
-
const
|
|
15167
|
+
const created = this.getThread(threadId);
|
|
15168
|
+
const skipSetup = isCowboyThread(created);
|
|
15169
|
+
const setup = skipSetup ? Promise.resolve() : this.runSetupAfterCreate(threadId);
|
|
14838
15170
|
if (prompt) {
|
|
14839
15171
|
try {
|
|
14840
15172
|
await this.send(threadId, prompt);
|
|
@@ -14846,6 +15178,7 @@ var init_orchestrator = __esm({
|
|
|
14846
15178
|
}
|
|
14847
15179
|
}
|
|
14848
15180
|
await setup;
|
|
15181
|
+
if (skipSetup) return;
|
|
14849
15182
|
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
14850
15183
|
if (autoRunAfterSetupEnabled2()) {
|
|
14851
15184
|
try {
|
|
@@ -16177,17 +16510,19 @@ var init_orchestrator = __esm({
|
|
|
16177
16510
|
const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
|
|
16178
16511
|
if (siblings.length === 0) {
|
|
16179
16512
|
this.stopDev(thread.id);
|
|
16180
|
-
|
|
16181
|
-
|
|
16182
|
-
|
|
16183
|
-
|
|
16184
|
-
|
|
16185
|
-
|
|
16513
|
+
if (shouldRemoveWorktreeOnTeardown(thread)) {
|
|
16514
|
+
try {
|
|
16515
|
+
await runArchiveScript(thread.repoPath, thread.worktreePath, (line) => {
|
|
16516
|
+
this.emit({
|
|
16517
|
+
type: "turn_output",
|
|
16518
|
+
threadId: thread.id,
|
|
16519
|
+
event: { type: "stdout", data: `[archive] ${line}` }
|
|
16520
|
+
});
|
|
16186
16521
|
});
|
|
16187
|
-
}
|
|
16188
|
-
|
|
16522
|
+
} catch {
|
|
16523
|
+
}
|
|
16524
|
+
await removeWorktree(thread.repoPath, thread.worktreePath);
|
|
16189
16525
|
}
|
|
16190
|
-
await removeWorktree(thread.repoPath, thread.worktreePath);
|
|
16191
16526
|
}
|
|
16192
16527
|
const archived = setStatus(thread.id, "archived");
|
|
16193
16528
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
@@ -16215,15 +16550,17 @@ var init_orchestrator = __esm({
|
|
|
16215
16550
|
const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
|
|
16216
16551
|
if (siblings.length === 0) {
|
|
16217
16552
|
this.stopDev(thread.id);
|
|
16218
|
-
|
|
16219
|
-
|
|
16220
|
-
|
|
16553
|
+
if (shouldRemoveWorktreeOnTeardown(thread)) {
|
|
16554
|
+
try {
|
|
16555
|
+
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
16556
|
+
} catch {
|
|
16557
|
+
}
|
|
16558
|
+
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
16559
|
+
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled2();
|
|
16560
|
+
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
16561
|
+
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
16562
|
+
});
|
|
16221
16563
|
}
|
|
16222
|
-
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
16223
|
-
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled2();
|
|
16224
|
-
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
16225
|
-
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
16226
|
-
});
|
|
16227
16564
|
}
|
|
16228
16565
|
deleteThreadRecord(thread.id);
|
|
16229
16566
|
}
|
|
@@ -16240,6 +16577,11 @@ var init_orchestrator = __esm({
|
|
|
16240
16577
|
return restored2;
|
|
16241
16578
|
}
|
|
16242
16579
|
if (!(0, import_node_fs44.existsSync)(thread.worktreePath)) {
|
|
16580
|
+
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
16581
|
+
throw new Error(
|
|
16582
|
+
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
16583
|
+
);
|
|
16584
|
+
}
|
|
16243
16585
|
const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
|
|
16244
16586
|
const slug = thread.worktreePath.split("/").pop();
|
|
16245
16587
|
const dest = thread.worktreePath;
|
|
@@ -17886,7 +18228,7 @@ async function startMcpServer() {
|
|
|
17886
18228
|
);
|
|
17887
18229
|
server.tool(
|
|
17888
18230
|
"create_thread",
|
|
17889
|
-
`Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces. From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Setup (settings.toml, .cursor/worktrees.json, or script/setup) runs in the background in parallel with the first turn. Then use send_to_thread to chat.`,
|
|
18231
|
+
`Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces. cowboy=true uses the project folder on the default branch (no isolated worktree; land is commit+push). From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Setup (settings.toml, .cursor/worktrees.json, or script/setup) runs in the background in parallel with the first turn (skipped for cowboy). Then use send_to_thread to chat.`,
|
|
17890
18232
|
{
|
|
17891
18233
|
sourceType: import_zod4.z.enum(["branch", "pr", "ticket"]),
|
|
17892
18234
|
sourceRef: import_zod4.z.string(),
|
|
@@ -17896,6 +18238,9 @@ async function startMcpServer() {
|
|
|
17896
18238
|
),
|
|
17897
18239
|
repoPath: import_zod4.z.string(),
|
|
17898
18240
|
title: import_zod4.z.string().optional(),
|
|
18241
|
+
cowboy: import_zod4.z.boolean().optional().describe(
|
|
18242
|
+
"If true, work in the project folder on the default branch (no thread/* worktree). Requires Settings \u2192 Advanced \u2192 Cowboy mode. Land is commit+push to that branch. Archive does not delete the folder."
|
|
18243
|
+
),
|
|
17899
18244
|
parentThreadId: import_zod4.z.string().optional().describe(
|
|
17900
18245
|
"Orchestration: omit (preferred) or pass YOUR chat id from the turn reminder / AGENTS.md. Do not invent uuids."
|
|
17901
18246
|
)
|
|
@@ -17956,7 +18301,8 @@ async function startMcpServer() {
|
|
|
17956
18301
|
fast: opts.fast,
|
|
17957
18302
|
repoPath: args.repoPath,
|
|
17958
18303
|
title: args.title,
|
|
17959
|
-
parentThreadId: parentId || null
|
|
18304
|
+
parentThreadId: parentId || null,
|
|
18305
|
+
cowboy: args.cowboy || void 0
|
|
17960
18306
|
}),
|
|
17961
18307
|
CREATE_THREAD_TIMEOUT_MS,
|
|
17962
18308
|
"create_thread"
|
|
@@ -17974,6 +18320,7 @@ async function startMcpServer() {
|
|
|
17974
18320
|
agent: thread.agent,
|
|
17975
18321
|
model: thread.model,
|
|
17976
18322
|
status: thread.status,
|
|
18323
|
+
cowboy: Boolean(thread.cowboy),
|
|
17977
18324
|
link: `sideboard://thread/${thread.id}`,
|
|
17978
18325
|
parentThreadId: thread.parentThreadId,
|
|
17979
18326
|
...agentCoercedFrom ? {
|