@sideboard-ai/core 0.1.109 → 0.1.110
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 +87 -12
- package/dist/agents/cursor-runner.js +37 -11
- package/dist/{agents-XB332VUJ.js → agents-MQDW3YXL.js} +6 -6
- package/dist/{agents-YIMHDI46.js → agents-WK54VP7J.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-3UOKB6VQ.js} +40 -0
- 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-EAAB4EK5.js} +154 -287
- package/dist/{chunk-I2OJ2YSP.js → chunk-KQBI5HNT.js} +2 -2
- package/dist/{chunk-P3BQ5DOL.js → chunk-KYOTBZ6S.js} +2 -0
- package/dist/{chunk-KKHDPV45.js → chunk-RSIWPLRG.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-AY2EQI2P.js → chunk-VOJSO3RM.js} +472 -46
- package/dist/{chunk-MMI4RJ5I.js → chunk-WIHKHR5R.js} +14 -3
- package/dist/{chunk-LTPX5N6K.js → chunk-XOZDAVOP.js} +162 -276
- 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 +835 -489
- 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 +812 -487
- package/dist/mcp/run-stdio.js +17 -12
- package/dist/{orchestrator-6W7EKSPO.js → orchestrator-FCZVCKBK.js} +10 -10
- package/dist/{orchestrator-JVGVPKLI.js → orchestrator-SCATSB3O.js} +8 -8
- 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/index.cjs
CHANGED
|
@@ -820,6 +820,7 @@ __export(app_settings_exports, {
|
|
|
820
820
|
childEnvWithAppSettings: () => childEnvWithAppSettings,
|
|
821
821
|
claudeChromeEnabled: () => claudeChromeEnabled,
|
|
822
822
|
claudeUserSettingsPath: () => claudeUserSettingsPath,
|
|
823
|
+
cowboyModeEnabled: () => cowboyModeEnabled,
|
|
823
824
|
deleteBranchOnPurgeEnabled: () => deleteBranchOnPurgeEnabled,
|
|
824
825
|
disconnectLinearConnection: () => disconnectLinearConnection,
|
|
825
826
|
ensureSlackDeviceIdentity: () => ensureSlackDeviceIdentity,
|
|
@@ -1058,6 +1059,9 @@ function normalizeAdvanced(raw) {
|
|
|
1058
1059
|
if (typeof source.deleteBranchOnPurge === "boolean") {
|
|
1059
1060
|
out.deleteBranchOnPurge = source.deleteBranchOnPurge;
|
|
1060
1061
|
}
|
|
1062
|
+
if (typeof source.cowboyMode === "boolean") {
|
|
1063
|
+
out.cowboyMode = source.cowboyMode;
|
|
1064
|
+
}
|
|
1061
1065
|
if (typeof source.autoArchiveOnMerge === "boolean") {
|
|
1062
1066
|
out.autoArchiveOnMerge = source.autoArchiveOnMerge;
|
|
1063
1067
|
}
|
|
@@ -1582,6 +1586,9 @@ function updateAdvancedSettings(patch) {
|
|
|
1582
1586
|
if (typeof patch.deleteBranchOnPurge === "boolean") {
|
|
1583
1587
|
advanced.deleteBranchOnPurge = patch.deleteBranchOnPurge;
|
|
1584
1588
|
}
|
|
1589
|
+
if (typeof patch.cowboyMode === "boolean") {
|
|
1590
|
+
advanced.cowboyMode = patch.cowboyMode;
|
|
1591
|
+
}
|
|
1585
1592
|
if (typeof patch.autoArchiveOnMerge === "boolean") {
|
|
1586
1593
|
advanced.autoArchiveOnMerge = patch.autoArchiveOnMerge;
|
|
1587
1594
|
}
|
|
@@ -1632,6 +1639,9 @@ function caffeinateWhileCloudConnectEnabled(settings = loadAppSettings()) {
|
|
|
1632
1639
|
function deleteBranchOnPurgeEnabled(settings = loadAppSettings()) {
|
|
1633
1640
|
return Boolean(settings.advanced.deleteBranchOnPurge);
|
|
1634
1641
|
}
|
|
1642
|
+
function cowboyModeEnabled(settings = loadAppSettings()) {
|
|
1643
|
+
return Boolean(settings.advanced.cowboyMode);
|
|
1644
|
+
}
|
|
1635
1645
|
function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
|
|
1636
1646
|
return Boolean(settings.advanced.autoArchiveOnMerge);
|
|
1637
1647
|
}
|
|
@@ -1977,6 +1987,7 @@ function normalizeThread(raw) {
|
|
|
1977
1987
|
prTitle: raw.prTitle ?? null,
|
|
1978
1988
|
prState: raw.prState ?? null,
|
|
1979
1989
|
skipAutoArchiveOnMerge: Boolean(raw.skipAutoArchiveOnMerge),
|
|
1990
|
+
cowboy: Boolean(raw.cowboy),
|
|
1980
1991
|
stackId: raw.stackId ?? null,
|
|
1981
1992
|
stackLayer: raw.stackLayer ?? null,
|
|
1982
1993
|
userSetTitle: Boolean(raw.userSetTitle),
|
|
@@ -2005,6 +2016,7 @@ function createEmptyThread(partial) {
|
|
|
2005
2016
|
prTitle: partial.prTitle ?? null,
|
|
2006
2017
|
prState: partial.prState ?? null,
|
|
2007
2018
|
skipAutoArchiveOnMerge: partial.skipAutoArchiveOnMerge ?? false,
|
|
2019
|
+
cowboy: Boolean(partial.cowboy),
|
|
2008
2020
|
stackId: partial.stackId ?? null,
|
|
2009
2021
|
stackLayer: partial.stackLayer ?? null,
|
|
2010
2022
|
userSetTitle: partial.userSetTitle ?? false,
|
|
@@ -7531,6 +7543,300 @@ var init_claude_mcp = __esm({
|
|
|
7531
7543
|
}
|
|
7532
7544
|
});
|
|
7533
7545
|
|
|
7546
|
+
// src/agents/message-parts.ts
|
|
7547
|
+
function asRecord(input) {
|
|
7548
|
+
if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
7549
|
+
return input;
|
|
7550
|
+
}
|
|
7551
|
+
return void 0;
|
|
7552
|
+
}
|
|
7553
|
+
function str2(v) {
|
|
7554
|
+
return typeof v === "string" && v.trim() ? v : void 0;
|
|
7555
|
+
}
|
|
7556
|
+
function toolDetail(name, input) {
|
|
7557
|
+
if (!input) return void 0;
|
|
7558
|
+
const command = str2(input.command) ?? str2(input.cmd);
|
|
7559
|
+
if (command) return command;
|
|
7560
|
+
const path2 = str2(input.file_path) ?? str2(input.path) ?? str2(input.filePath) ?? str2(input.filename);
|
|
7561
|
+
if (path2) return path2;
|
|
7562
|
+
const pattern = str2(input.pattern) ?? str2(input.glob) ?? str2(input.glob_pattern);
|
|
7563
|
+
if (pattern) return pattern;
|
|
7564
|
+
const query = str2(input.query) ?? str2(input.prompt);
|
|
7565
|
+
if (query) return query.length > 80 ? `${query.slice(0, 77)}\u2026` : query;
|
|
7566
|
+
try {
|
|
7567
|
+
const raw = JSON.stringify(input);
|
|
7568
|
+
return raw.length > 80 ? `${raw.slice(0, 77)}\u2026` : raw;
|
|
7569
|
+
} catch {
|
|
7570
|
+
return name;
|
|
7571
|
+
}
|
|
7572
|
+
}
|
|
7573
|
+
function toolDescription(name, input) {
|
|
7574
|
+
const n = name.replace(/^mcp__/, "").replace(/__/g, " \xB7 ");
|
|
7575
|
+
if (/^get_record_types$|recordTypes/i.test(name)) return "List record types";
|
|
7576
|
+
if (/connectedAgentRequest/i.test(name)) {
|
|
7577
|
+
return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
|
|
7578
|
+
}
|
|
7579
|
+
if (/present_artifact$/i.test(name)) {
|
|
7580
|
+
return str2(input?.title) ? `Present ${str2(input?.title)}` : "Present artifact";
|
|
7581
|
+
}
|
|
7582
|
+
if (/present_plan$/i.test(name)) {
|
|
7583
|
+
return str2(input?.title) ? `Plan ${str2(input?.title)}` : "Present plan";
|
|
7584
|
+
}
|
|
7585
|
+
if (/present_schema$/i.test(name)) {
|
|
7586
|
+
return str2(input?.title) ? `Schema ${str2(input?.title)}` : "Present schema";
|
|
7587
|
+
}
|
|
7588
|
+
if (/present_files$/i.test(name)) {
|
|
7589
|
+
return str2(input?.title) ? `Files ${str2(input?.title)}` : "Present files";
|
|
7590
|
+
}
|
|
7591
|
+
if (isSubagentToolName(name)) {
|
|
7592
|
+
const desc = str2(input?.description);
|
|
7593
|
+
const sub = asRecord(input?.subagentType);
|
|
7594
|
+
const kind = str2(sub?.name) ?? str2(sub?.kind) ?? str2(input?.subagent_type) ?? str2(input?.subagentType);
|
|
7595
|
+
if (/^spawn_agent$/i.test(name)) {
|
|
7596
|
+
return str2(input?.prompt) ?? desc ?? "Subagent";
|
|
7597
|
+
}
|
|
7598
|
+
if (/connectedAgentRequest/i.test(name)) {
|
|
7599
|
+
return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
|
|
7600
|
+
}
|
|
7601
|
+
if (desc && kind) return `${kind}: ${desc}`;
|
|
7602
|
+
if (desc) return desc;
|
|
7603
|
+
return "Subagent";
|
|
7604
|
+
}
|
|
7605
|
+
if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
|
|
7606
|
+
return str2(input?.title) ? `Artifact ${str2(input?.title)}` : "Artifact";
|
|
7607
|
+
}
|
|
7608
|
+
if (!input) return n;
|
|
7609
|
+
if (/bash|shell|terminal/i.test(name) && str2(input.command)) {
|
|
7610
|
+
const cmd = str2(input.command);
|
|
7611
|
+
if (/git\s+fetch/i.test(cmd)) return "Fetch latest from origin and check status";
|
|
7612
|
+
if (/git\s+status/i.test(cmd)) return "Check git status";
|
|
7613
|
+
if (/git\s+log/i.test(cmd)) return "Inspect recent commits";
|
|
7614
|
+
if (/git\s+branch/i.test(cmd)) return "List branches";
|
|
7615
|
+
if (/grep|rg\b/i.test(cmd)) return "Search repository";
|
|
7616
|
+
return "Run shell command";
|
|
7617
|
+
}
|
|
7618
|
+
if (/edit|write|apply/i.test(name)) {
|
|
7619
|
+
const path2 = str2(input.file_path) ?? str2(input.path);
|
|
7620
|
+
return path2 ? `Edit ${path2.split("/").pop()}` : "Edit file";
|
|
7621
|
+
}
|
|
7622
|
+
if (/read/i.test(name)) {
|
|
7623
|
+
const path2 = str2(input.file_path) ?? str2(input.path);
|
|
7624
|
+
return path2 ? `Read ${path2.split("/").pop()}` : "Read file";
|
|
7625
|
+
}
|
|
7626
|
+
if (/grep/i.test(name)) return "Search files";
|
|
7627
|
+
if (/glob/i.test(name)) return "Find files";
|
|
7628
|
+
return n;
|
|
7629
|
+
}
|
|
7630
|
+
function isSubagentToolName(name) {
|
|
7631
|
+
const n = (name ?? "").trim();
|
|
7632
|
+
if (/^(task|agent|spawn_agent)$/i.test(n)) return true;
|
|
7633
|
+
return /connectedAgentRequest/i.test(n);
|
|
7634
|
+
}
|
|
7635
|
+
function messagePartParentId(part) {
|
|
7636
|
+
if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
|
|
7637
|
+
return part.parentId;
|
|
7638
|
+
}
|
|
7639
|
+
return void 0;
|
|
7640
|
+
}
|
|
7641
|
+
function sameParentId(a, b) {
|
|
7642
|
+
return (a ?? "") === (b ?? "");
|
|
7643
|
+
}
|
|
7644
|
+
function withEventParentId(event, parentId) {
|
|
7645
|
+
if (!parentId) return event;
|
|
7646
|
+
if (event.type === "stdout" || event.type === "thinking" || event.type === "tool_use" || event.type === "tool_result") {
|
|
7647
|
+
return { ...event, parentId: event.parentId ?? parentId };
|
|
7648
|
+
}
|
|
7649
|
+
return event;
|
|
7650
|
+
}
|
|
7651
|
+
function withEventsParentId(events, parentId) {
|
|
7652
|
+
if (!parentId) return events;
|
|
7653
|
+
return events.map((event) => withEventParentId(event, parentId));
|
|
7654
|
+
}
|
|
7655
|
+
function toolFilePath(input) {
|
|
7656
|
+
if (!input) return void 0;
|
|
7657
|
+
return str2(input.file_path) ?? str2(input.path) ?? str2(input.filePath) ?? str2(input.filename);
|
|
7658
|
+
}
|
|
7659
|
+
function countLines(text4) {
|
|
7660
|
+
if (!text4) return 0;
|
|
7661
|
+
return text4.split("\n").length;
|
|
7662
|
+
}
|
|
7663
|
+
function diffFromInput(input) {
|
|
7664
|
+
if (!input) return {};
|
|
7665
|
+
const oldS = str2(input.old_string) ?? str2(input.oldString);
|
|
7666
|
+
const newS = str2(input.new_string) ?? str2(input.newString) ?? str2(input.content);
|
|
7667
|
+
if (oldS != null || newS != null) {
|
|
7668
|
+
return {
|
|
7669
|
+
additions: countLines(newS),
|
|
7670
|
+
deletions: countLines(oldS)
|
|
7671
|
+
};
|
|
7672
|
+
}
|
|
7673
|
+
return {};
|
|
7674
|
+
}
|
|
7675
|
+
function parseDiffStat(result) {
|
|
7676
|
+
if (!result) return {};
|
|
7677
|
+
const paired = result.match(/\+(\d+)\s+-(\d+)/);
|
|
7678
|
+
if (paired) {
|
|
7679
|
+
return {
|
|
7680
|
+
additions: Number(paired[1]),
|
|
7681
|
+
deletions: Number(paired[2])
|
|
7682
|
+
};
|
|
7683
|
+
}
|
|
7684
|
+
const verbose = result.match(
|
|
7685
|
+
/(\d+)\s+insertions?(?:,\s*(\d+)\s+deletions?)?/i
|
|
7686
|
+
);
|
|
7687
|
+
if (verbose) {
|
|
7688
|
+
return {
|
|
7689
|
+
additions: Number(verbose[1]),
|
|
7690
|
+
deletions: verbose[2] != null ? Number(verbose[2]) : void 0
|
|
7691
|
+
};
|
|
7692
|
+
}
|
|
7693
|
+
return {};
|
|
7694
|
+
}
|
|
7695
|
+
function applyAgentEvent(parts, event) {
|
|
7696
|
+
if (event.type === "stdout") {
|
|
7697
|
+
const data = event.data;
|
|
7698
|
+
if (!data) return parts;
|
|
7699
|
+
const next = [...parts];
|
|
7700
|
+
const last = next[next.length - 1];
|
|
7701
|
+
if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
|
|
7702
|
+
next[next.length - 1] = {
|
|
7703
|
+
type: "text",
|
|
7704
|
+
text: last.text + data,
|
|
7705
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
7706
|
+
};
|
|
7707
|
+
} else {
|
|
7708
|
+
next.push({
|
|
7709
|
+
type: "text",
|
|
7710
|
+
text: data,
|
|
7711
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
7712
|
+
});
|
|
7713
|
+
}
|
|
7714
|
+
return next;
|
|
7715
|
+
}
|
|
7716
|
+
if (event.type === "thinking") {
|
|
7717
|
+
const data = event.data;
|
|
7718
|
+
if (!data) return parts;
|
|
7719
|
+
const next = [...parts];
|
|
7720
|
+
const last = next[next.length - 1];
|
|
7721
|
+
if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
|
|
7722
|
+
next[next.length - 1] = {
|
|
7723
|
+
type: "thinking",
|
|
7724
|
+
text: last.text + data,
|
|
7725
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
7726
|
+
};
|
|
7727
|
+
} else {
|
|
7728
|
+
next.push({
|
|
7729
|
+
type: "thinking",
|
|
7730
|
+
text: data,
|
|
7731
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
7732
|
+
});
|
|
7733
|
+
}
|
|
7734
|
+
return next;
|
|
7735
|
+
}
|
|
7736
|
+
if (event.type === "tool_use") {
|
|
7737
|
+
const input = asRecord(event.input);
|
|
7738
|
+
const diff = diffFromInput(input);
|
|
7739
|
+
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
7740
|
+
if (existing >= 0) {
|
|
7741
|
+
const prev = parts[existing];
|
|
7742
|
+
const next = [...parts];
|
|
7743
|
+
const mergedInput = input && Object.keys(input).length > 0 ? input : prev.input ?? input;
|
|
7744
|
+
next[existing] = {
|
|
7745
|
+
...prev,
|
|
7746
|
+
name: event.name || prev.name,
|
|
7747
|
+
input: mergedInput,
|
|
7748
|
+
description: toolDescription(event.name || prev.name, mergedInput),
|
|
7749
|
+
detail: toolDetail(event.name || prev.name, mergedInput) ?? prev.detail,
|
|
7750
|
+
filePath: toolFilePath(mergedInput) ?? prev.filePath,
|
|
7751
|
+
additions: diff.additions ?? prev.additions,
|
|
7752
|
+
deletions: diff.deletions ?? prev.deletions,
|
|
7753
|
+
parentId: event.parentId ?? prev.parentId
|
|
7754
|
+
};
|
|
7755
|
+
return next;
|
|
7756
|
+
}
|
|
7757
|
+
return [
|
|
7758
|
+
...parts,
|
|
7759
|
+
{
|
|
7760
|
+
type: "tool",
|
|
7761
|
+
id: event.id,
|
|
7762
|
+
name: event.name,
|
|
7763
|
+
input,
|
|
7764
|
+
description: toolDescription(event.name, input),
|
|
7765
|
+
detail: toolDetail(event.name, input),
|
|
7766
|
+
status: "running",
|
|
7767
|
+
filePath: toolFilePath(input),
|
|
7768
|
+
...event.parentId ? { parentId: event.parentId } : {},
|
|
7769
|
+
...diff
|
|
7770
|
+
}
|
|
7771
|
+
];
|
|
7772
|
+
}
|
|
7773
|
+
if (event.type === "tool_result") {
|
|
7774
|
+
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
7775
|
+
const fromResult = parseDiffStat(event.content);
|
|
7776
|
+
if (existing < 0) {
|
|
7777
|
+
return [
|
|
7778
|
+
...parts,
|
|
7779
|
+
{
|
|
7780
|
+
type: "tool",
|
|
7781
|
+
id: event.id,
|
|
7782
|
+
name: "tool",
|
|
7783
|
+
description: "tool",
|
|
7784
|
+
status: event.isError ? "error" : "done",
|
|
7785
|
+
result: event.content,
|
|
7786
|
+
...event.parentId ? { parentId: event.parentId } : {},
|
|
7787
|
+
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
7788
|
+
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
7789
|
+
}
|
|
7790
|
+
];
|
|
7791
|
+
}
|
|
7792
|
+
return parts.map((p, i) => {
|
|
7793
|
+
if (i !== existing || p.type !== "tool") return p;
|
|
7794
|
+
return {
|
|
7795
|
+
...p,
|
|
7796
|
+
status: event.isError ? "error" : "done",
|
|
7797
|
+
result: event.content,
|
|
7798
|
+
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
7799
|
+
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
7800
|
+
};
|
|
7801
|
+
});
|
|
7802
|
+
}
|
|
7803
|
+
return parts;
|
|
7804
|
+
}
|
|
7805
|
+
function partsToAssistantText(parts) {
|
|
7806
|
+
return parts.filter(
|
|
7807
|
+
(p) => p.type === "text" && !messagePartParentId(p)
|
|
7808
|
+
).map((p) => p.text).join("").trim();
|
|
7809
|
+
}
|
|
7810
|
+
function stripBrightsyNdjsonNoise(text4) {
|
|
7811
|
+
if (!text4 || !text4.includes('"type"')) return text4;
|
|
7812
|
+
let out = text4;
|
|
7813
|
+
out = out.replace(
|
|
7814
|
+
/\{"type":"(?:tool_use|tool_result|tool|thinking|usage|done|error)"[\s\S]*?\}\s*(?=\{"type":"|$|(?=[A-Za-z*#]))/g,
|
|
7815
|
+
""
|
|
7816
|
+
);
|
|
7817
|
+
out = out.replace(/\{"type":"(?:tool_use|tool_result|tool)"[\s\S]*$/g, "");
|
|
7818
|
+
return out.trim();
|
|
7819
|
+
}
|
|
7820
|
+
function isBrightsyNdjsonLine(line) {
|
|
7821
|
+
const t = line.trim();
|
|
7822
|
+
if (!t.startsWith("{")) return false;
|
|
7823
|
+
return /"type"\s*:\s*"(tool_use|tool_result|tool|thinking|usage|done|error|text)"/.test(t);
|
|
7824
|
+
}
|
|
7825
|
+
function finalizeParts(parts) {
|
|
7826
|
+
return parts.map(
|
|
7827
|
+
(p) => p.type === "tool" && p.status === "running" ? { ...p, status: "done" } : p
|
|
7828
|
+
);
|
|
7829
|
+
}
|
|
7830
|
+
function normalizeParseResult(parsed) {
|
|
7831
|
+
if (!parsed) return [];
|
|
7832
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
7833
|
+
}
|
|
7834
|
+
var init_message_parts = __esm({
|
|
7835
|
+
"src/agents/message-parts.ts"() {
|
|
7836
|
+
"use strict";
|
|
7837
|
+
}
|
|
7838
|
+
});
|
|
7839
|
+
|
|
7534
7840
|
// src/mcp/profile.ts
|
|
7535
7841
|
function sideboardMcpProfile(env = process.env) {
|
|
7536
7842
|
return env[SIDEBOARD_MCP_PROFILE_ENV]?.trim().toLowerCase() === "worktree" ? "worktree" : "orchestration";
|
|
@@ -8170,42 +8476,59 @@ function claudeResultErrorDetail(obj) {
|
|
|
8170
8476
|
}
|
|
8171
8477
|
return "Claude turn failed";
|
|
8172
8478
|
}
|
|
8173
|
-
function eventsFromContentBlocks(blocks) {
|
|
8479
|
+
function eventsFromContentBlocks(blocks, parentId) {
|
|
8174
8480
|
if (!blocks?.length) return [];
|
|
8175
8481
|
const out = [];
|
|
8176
8482
|
for (const block of blocks) {
|
|
8177
8483
|
if (!block?.type) continue;
|
|
8178
8484
|
if (block.type === "text" && block.text) {
|
|
8179
|
-
out.push({ type: "stdout", data: block.text });
|
|
8485
|
+
out.push(withEventParentId({ type: "stdout", data: block.text }, parentId));
|
|
8180
8486
|
continue;
|
|
8181
8487
|
}
|
|
8182
8488
|
if ((block.type === "thinking" || block.type === "redacted_thinking") && block.thinking) {
|
|
8183
|
-
out.push({ type: "thinking", data: block.thinking });
|
|
8489
|
+
out.push(withEventParentId({ type: "thinking", data: block.thinking }, parentId));
|
|
8184
8490
|
continue;
|
|
8185
8491
|
}
|
|
8186
8492
|
if (block.type === "tool_use" && block.id && block.name) {
|
|
8187
|
-
out.push(
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8493
|
+
out.push(
|
|
8494
|
+
withEventParentId(
|
|
8495
|
+
{
|
|
8496
|
+
type: "tool_use",
|
|
8497
|
+
id: block.id,
|
|
8498
|
+
name: block.name,
|
|
8499
|
+
input: block.input
|
|
8500
|
+
},
|
|
8501
|
+
parentId
|
|
8502
|
+
)
|
|
8503
|
+
);
|
|
8193
8504
|
continue;
|
|
8194
8505
|
}
|
|
8195
8506
|
if (block.type === "tool_result" && block.tool_use_id) {
|
|
8196
8507
|
const content = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map(
|
|
8197
8508
|
(c) => typeof c === "string" ? c : c && typeof c === "object" && "text" in c ? String(c.text ?? "") : ""
|
|
8198
8509
|
).join("") : block.content != null ? JSON.stringify(block.content) : void 0;
|
|
8199
|
-
out.push(
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
|
|
8510
|
+
out.push(
|
|
8511
|
+
withEventParentId(
|
|
8512
|
+
{
|
|
8513
|
+
type: "tool_result",
|
|
8514
|
+
id: block.tool_use_id,
|
|
8515
|
+
content,
|
|
8516
|
+
isError: Boolean(block.is_error)
|
|
8517
|
+
},
|
|
8518
|
+
parentId
|
|
8519
|
+
)
|
|
8520
|
+
);
|
|
8205
8521
|
}
|
|
8206
8522
|
}
|
|
8207
8523
|
return out;
|
|
8208
8524
|
}
|
|
8525
|
+
function claudeParentToolUseId(obj) {
|
|
8526
|
+
const nested = obj.event && typeof obj.event === "object" && !Array.isArray(obj.event) ? obj.event : void 0;
|
|
8527
|
+
for (const id of [obj.parent_tool_use_id, nested?.parent_tool_use_id]) {
|
|
8528
|
+
if (typeof id === "string" && id.trim()) return id.trim();
|
|
8529
|
+
}
|
|
8530
|
+
return void 0;
|
|
8531
|
+
}
|
|
8209
8532
|
function parseIssuesJson(raw) {
|
|
8210
8533
|
const text4 = raw.trim();
|
|
8211
8534
|
const candidates = [text4];
|
|
@@ -8240,6 +8563,7 @@ var init_claude = __esm({
|
|
|
8240
8563
|
init_app_settings();
|
|
8241
8564
|
init_claude_mcp();
|
|
8242
8565
|
init_error_detail();
|
|
8566
|
+
init_message_parts();
|
|
8243
8567
|
init_injected_mcp();
|
|
8244
8568
|
init_turn_input();
|
|
8245
8569
|
init_types();
|
|
@@ -8251,7 +8575,10 @@ var init_claude = __esm({
|
|
|
8251
8575
|
"Glob",
|
|
8252
8576
|
"Grep",
|
|
8253
8577
|
"WebFetch",
|
|
8254
|
-
"WebSearch"
|
|
8578
|
+
"WebSearch",
|
|
8579
|
+
// Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
|
|
8580
|
+
"Task",
|
|
8581
|
+
"Agent"
|
|
8255
8582
|
];
|
|
8256
8583
|
CLAUDE_CHROME_ALLOWED_TOOLS = [
|
|
8257
8584
|
"mcp__claude-in-chrome",
|
|
@@ -8379,7 +8706,9 @@ var init_claude = __esm({
|
|
|
8379
8706
|
args,
|
|
8380
8707
|
cwd: thread.worktreePath,
|
|
8381
8708
|
stdin: useStdin ? `${promptText}
|
|
8382
|
-
` : void 0
|
|
8709
|
+
` : void 0,
|
|
8710
|
+
// Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
|
|
8711
|
+
env: { CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1" }
|
|
8383
8712
|
};
|
|
8384
8713
|
},
|
|
8385
8714
|
parseEvent(line) {
|
|
@@ -8396,8 +8725,9 @@ var init_claude = __esm({
|
|
|
8396
8725
|
return { type: "session_id", data: obj.session_id };
|
|
8397
8726
|
}
|
|
8398
8727
|
if (obj.type === "assistant" || obj.type === "user") {
|
|
8728
|
+
const parentId = claudeParentToolUseId(obj);
|
|
8399
8729
|
const message = obj.message;
|
|
8400
|
-
const events = eventsFromContentBlocks(message?.content);
|
|
8730
|
+
const events = eventsFromContentBlocks(message?.content, parentId);
|
|
8401
8731
|
if (obj.type === "assistant") {
|
|
8402
8732
|
const usage = usageFromClaude(message?.usage);
|
|
8403
8733
|
if (usage) events.push({ type: "usage", data: usage, scope: "request" });
|
|
@@ -8406,34 +8736,45 @@ var init_claude = __esm({
|
|
|
8406
8736
|
return events.length === 1 ? events[0] : events;
|
|
8407
8737
|
}
|
|
8408
8738
|
if (obj.type === "stream_event") {
|
|
8739
|
+
const parentId = claudeParentToolUseId(obj);
|
|
8409
8740
|
const event = obj.event;
|
|
8410
8741
|
if (!event) return null;
|
|
8411
8742
|
if (event.type === "content_block_start" && event.content_block) {
|
|
8412
8743
|
const block = event.content_block;
|
|
8413
8744
|
if (block.type === "tool_use" && block.id && block.name) {
|
|
8414
|
-
return
|
|
8415
|
-
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
|
|
8745
|
+
return withEventParentId(
|
|
8746
|
+
{
|
|
8747
|
+
type: "tool_use",
|
|
8748
|
+
id: block.id,
|
|
8749
|
+
name: block.name,
|
|
8750
|
+
input: block.input
|
|
8751
|
+
},
|
|
8752
|
+
parentId
|
|
8753
|
+
);
|
|
8420
8754
|
}
|
|
8421
8755
|
if (block.type === "thinking" && block.thinking) {
|
|
8422
|
-
return { type: "thinking", data: block.thinking };
|
|
8756
|
+
return withEventParentId({ type: "thinking", data: block.thinking }, parentId);
|
|
8423
8757
|
}
|
|
8424
8758
|
return null;
|
|
8425
8759
|
}
|
|
8426
8760
|
if (event.type === "content_block_delta" && event.delta) {
|
|
8427
|
-
if (event.delta.text)
|
|
8428
|
-
|
|
8761
|
+
if (event.delta.text) {
|
|
8762
|
+
return withEventParentId({ type: "stdout", data: event.delta.text }, parentId);
|
|
8763
|
+
}
|
|
8764
|
+
if (event.delta.thinking) {
|
|
8765
|
+
return withEventParentId({ type: "thinking", data: event.delta.thinking }, parentId);
|
|
8766
|
+
}
|
|
8429
8767
|
return null;
|
|
8430
8768
|
}
|
|
8431
8769
|
return null;
|
|
8432
8770
|
}
|
|
8433
8771
|
if (obj.type === "content_block_delta") {
|
|
8772
|
+
const parentId = claudeParentToolUseId(obj);
|
|
8434
8773
|
const delta = obj.delta;
|
|
8435
|
-
if (delta?.text) return { type: "stdout", data: delta.text };
|
|
8436
|
-
if (delta?.thinking)
|
|
8774
|
+
if (delta?.text) return withEventParentId({ type: "stdout", data: delta.text }, parentId);
|
|
8775
|
+
if (delta?.thinking) {
|
|
8776
|
+
return withEventParentId({ type: "thinking", data: delta.thinking }, parentId);
|
|
8777
|
+
}
|
|
8437
8778
|
return null;
|
|
8438
8779
|
}
|
|
8439
8780
|
if (obj.type === "result") {
|
|
@@ -8566,7 +8907,7 @@ function unwrapCodexMcpResult(result) {
|
|
|
8566
8907
|
return String(result);
|
|
8567
8908
|
}
|
|
8568
8909
|
}
|
|
8569
|
-
function
|
|
8910
|
+
function asRecord2(value) {
|
|
8570
8911
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
8571
8912
|
return value;
|
|
8572
8913
|
}
|
|
@@ -8731,7 +9072,7 @@ var init_codex = __esm({
|
|
|
8731
9072
|
}
|
|
8732
9073
|
if (itemType === "mcp_tool_call" && item.id && item.server && item.tool) {
|
|
8733
9074
|
const name = `mcp__${item.server}__${item.tool}`;
|
|
8734
|
-
const input =
|
|
9075
|
+
const input = asRecord2(item.arguments);
|
|
8735
9076
|
const events = [
|
|
8736
9077
|
{ type: "tool_use", id: item.id, name, input }
|
|
8737
9078
|
];
|
|
@@ -8762,6 +9103,36 @@ var init_codex = __esm({
|
|
|
8762
9103
|
}
|
|
8763
9104
|
return events.length === 1 ? events[0] : events;
|
|
8764
9105
|
}
|
|
9106
|
+
if (itemType === "collab_tool_call" && item.id) {
|
|
9107
|
+
const rawTool = typeof item.tool === "string" ? item.tool : "spawn_agent";
|
|
9108
|
+
const name = /spawn/i.test(rawTool) ? "spawn_agent" : rawTool;
|
|
9109
|
+
const input = {};
|
|
9110
|
+
if (item.prompt) input.prompt = item.prompt;
|
|
9111
|
+
if (Array.isArray(item.receiver_thread_ids)) {
|
|
9112
|
+
input.receiver_thread_ids = item.receiver_thread_ids;
|
|
9113
|
+
}
|
|
9114
|
+
const events = [{ type: "tool_use", id: item.id, name, input }];
|
|
9115
|
+
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
9116
|
+
if (finished) {
|
|
9117
|
+
const nested = [];
|
|
9118
|
+
if (item.agents_states && typeof item.agents_states === "object") {
|
|
9119
|
+
for (const value of Object.values(item.agents_states)) {
|
|
9120
|
+
const msg = value && typeof value === "object" && typeof value.message === "string" ? value.message.trim() : "";
|
|
9121
|
+
if (msg) nested.push(msg);
|
|
9122
|
+
}
|
|
9123
|
+
}
|
|
9124
|
+
for (const text4 of nested) {
|
|
9125
|
+
events.push({ type: "stdout", data: text4, parentId: item.id });
|
|
9126
|
+
}
|
|
9127
|
+
events.push({
|
|
9128
|
+
type: "tool_result",
|
|
9129
|
+
id: item.id,
|
|
9130
|
+
content: nested.join("\n") || void 0,
|
|
9131
|
+
isError: item.status === "failed"
|
|
9132
|
+
});
|
|
9133
|
+
}
|
|
9134
|
+
return events.length === 1 ? events[0] : events;
|
|
9135
|
+
}
|
|
8765
9136
|
if (item.status === "failed") {
|
|
8766
9137
|
const detail = item.message?.trim() || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
|
|
8767
9138
|
return { type: "stderr", data: detail };
|
|
@@ -8850,20 +9221,20 @@ function usageFromCursor(usage) {
|
|
|
8850
9221
|
cacheWriteTokens: usage.cacheWriteTokens ? Number(usage.cacheWriteTokens) : void 0
|
|
8851
9222
|
};
|
|
8852
9223
|
}
|
|
8853
|
-
function
|
|
9224
|
+
function asRecord3(value) {
|
|
8854
9225
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
8855
9226
|
return value;
|
|
8856
9227
|
}
|
|
8857
9228
|
return void 0;
|
|
8858
9229
|
}
|
|
8859
9230
|
function normalizeCursorToolCall(name, args) {
|
|
8860
|
-
const raw =
|
|
9231
|
+
const raw = asRecord3(args);
|
|
8861
9232
|
const toolName = typeof raw?.toolName === "string" && raw.toolName.trim() ? raw.toolName.trim() : null;
|
|
8862
|
-
const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" ||
|
|
9233
|
+
const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord3(raw?.args) != null);
|
|
8863
9234
|
if (looksLikeMcp && toolName) {
|
|
8864
9235
|
const providerRaw = typeof raw.providerIdentifier === "string" && raw.providerIdentifier.trim() ? raw.providerIdentifier.trim() : "sideboard";
|
|
8865
9236
|
const provider = providerRaw.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
8866
|
-
const nested =
|
|
9237
|
+
const nested = asRecord3(raw.args);
|
|
8867
9238
|
return {
|
|
8868
9239
|
name: `mcp__${provider}__${toolName}`,
|
|
8869
9240
|
input: nested ?? { toolName }
|
|
@@ -8874,7 +9245,7 @@ function normalizeCursorToolCall(name, args) {
|
|
|
8874
9245
|
function unwrapCursorToolResult(result) {
|
|
8875
9246
|
if (result == null) return void 0;
|
|
8876
9247
|
if (typeof result === "string") return result;
|
|
8877
|
-
const rec =
|
|
9248
|
+
const rec = asRecord3(result);
|
|
8878
9249
|
if (!rec) {
|
|
8879
9250
|
try {
|
|
8880
9251
|
return JSON.stringify(result);
|
|
@@ -8885,18 +9256,18 @@ function unwrapCursorToolResult(result) {
|
|
|
8885
9256
|
const collectTexts = (items) => {
|
|
8886
9257
|
const texts = [];
|
|
8887
9258
|
for (const item of items) {
|
|
8888
|
-
const row =
|
|
9259
|
+
const row = asRecord3(item);
|
|
8889
9260
|
if (!row) continue;
|
|
8890
9261
|
if (typeof row.text === "string") {
|
|
8891
9262
|
texts.push(row.text);
|
|
8892
9263
|
continue;
|
|
8893
9264
|
}
|
|
8894
|
-
const nested =
|
|
9265
|
+
const nested = asRecord3(row.text);
|
|
8895
9266
|
if (typeof nested?.text === "string") texts.push(nested.text);
|
|
8896
9267
|
}
|
|
8897
9268
|
return texts;
|
|
8898
9269
|
};
|
|
8899
|
-
const value =
|
|
9270
|
+
const value = asRecord3(rec.value);
|
|
8900
9271
|
if (value && Array.isArray(value.content)) {
|
|
8901
9272
|
const texts = collectTexts(value.content);
|
|
8902
9273
|
if (texts.length) return texts.join("\n");
|
|
@@ -8913,10 +9284,10 @@ function unwrapCursorToolResult(result) {
|
|
|
8913
9284
|
}
|
|
8914
9285
|
function cursorToolResultIsError(status, result) {
|
|
8915
9286
|
if (status === "error") return true;
|
|
8916
|
-
const rec =
|
|
9287
|
+
const rec = asRecord3(result);
|
|
8917
9288
|
if (!rec) return false;
|
|
8918
9289
|
if (rec.status === "error") return true;
|
|
8919
|
-
const value =
|
|
9290
|
+
const value = asRecord3(rec.value);
|
|
8920
9291
|
return value?.isError === true;
|
|
8921
9292
|
}
|
|
8922
9293
|
function cursorSdkMessageToEvents(msg) {
|
|
@@ -9259,6 +9630,24 @@ var init_cursor = __esm({
|
|
|
9259
9630
|
});
|
|
9260
9631
|
|
|
9261
9632
|
// src/agents/opencode.ts
|
|
9633
|
+
function asRecord4(value) {
|
|
9634
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
9635
|
+
return value;
|
|
9636
|
+
}
|
|
9637
|
+
return void 0;
|
|
9638
|
+
}
|
|
9639
|
+
function str3(v) {
|
|
9640
|
+
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
9641
|
+
}
|
|
9642
|
+
function opencodeToolId(name, callId, metadata) {
|
|
9643
|
+
const sessionId = str3(metadata?.sessionId) ?? str3(metadata?.sessionID);
|
|
9644
|
+
if (name === "task" && sessionId) return sessionId;
|
|
9645
|
+
return callId || `tool-${Date.now()}`;
|
|
9646
|
+
}
|
|
9647
|
+
function withTaskParent(parentId, nested) {
|
|
9648
|
+
const events = Array.isArray(nested) ? nested : [nested];
|
|
9649
|
+
return [{ type: "tool_use", id: parentId, name: "task" }, ...events];
|
|
9650
|
+
}
|
|
9262
9651
|
function displayNameFromOpencodeId(id) {
|
|
9263
9652
|
const slash = id.indexOf("/");
|
|
9264
9653
|
if (slash <= 0) return id;
|
|
@@ -9325,6 +9714,7 @@ var init_opencode = __esm({
|
|
|
9325
9714
|
init_app_settings();
|
|
9326
9715
|
init_global_workspace();
|
|
9327
9716
|
init_error_detail();
|
|
9717
|
+
init_message_parts();
|
|
9328
9718
|
init_injected_mcp();
|
|
9329
9719
|
init_turn_input();
|
|
9330
9720
|
init_types();
|
|
@@ -9441,10 +9831,15 @@ var init_opencode = __esm({
|
|
|
9441
9831
|
}
|
|
9442
9832
|
if (obj.type === "tool_use") {
|
|
9443
9833
|
const part = obj.part;
|
|
9444
|
-
const id = part?.callID ?? part?.id ?? obj.id ?? `tool-${Date.now()}`;
|
|
9445
9834
|
const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
|
|
9446
9835
|
const state = part?.state;
|
|
9447
9836
|
const input = (state?.input && typeof state.input === "object" ? state.input : void 0) ?? part?.input ?? obj.input;
|
|
9837
|
+
const metadata = asRecord4(state?.metadata);
|
|
9838
|
+
const id = opencodeToolId(
|
|
9839
|
+
name,
|
|
9840
|
+
part?.callID ?? part?.id ?? obj.id,
|
|
9841
|
+
metadata
|
|
9842
|
+
);
|
|
9448
9843
|
const events = [{ type: "tool_use", id, name, input }];
|
|
9449
9844
|
const output = state?.output;
|
|
9450
9845
|
if (output != null || state?.status === "completed" || state?.status === "error") {
|
|
@@ -9458,6 +9853,53 @@ var init_opencode = __esm({
|
|
|
9458
9853
|
}
|
|
9459
9854
|
return events.length === 1 ? events[0] : events;
|
|
9460
9855
|
}
|
|
9856
|
+
if (obj.type === "subtask_delta") {
|
|
9857
|
+
const parentId = str3(obj.childSessionID) ?? str3(obj.childSessionId);
|
|
9858
|
+
const delta = str3(obj.delta);
|
|
9859
|
+
if (parentId && delta) {
|
|
9860
|
+
return withTaskParent(
|
|
9861
|
+
parentId,
|
|
9862
|
+
withEventParentId({ type: "thinking", data: delta }, parentId)
|
|
9863
|
+
);
|
|
9864
|
+
}
|
|
9865
|
+
return null;
|
|
9866
|
+
}
|
|
9867
|
+
if (obj.type === "subtask_event") {
|
|
9868
|
+
const parentId = str3(obj.childSessionID) ?? str3(obj.childSessionId);
|
|
9869
|
+
const part = asRecord4(obj.part);
|
|
9870
|
+
if (!parentId || !part) return null;
|
|
9871
|
+
if (part.type === "text" && str3(part.text)) {
|
|
9872
|
+
return withTaskParent(
|
|
9873
|
+
parentId,
|
|
9874
|
+
withEventParentId({ type: "stdout", data: str3(part.text) }, parentId)
|
|
9875
|
+
);
|
|
9876
|
+
}
|
|
9877
|
+
if (part.type === "tool" || str3(part.tool)) {
|
|
9878
|
+
const name = str3(part.tool) ?? str3(part.name) ?? "tool";
|
|
9879
|
+
const id = str3(part.callID) ?? str3(part.id) ?? `${parentId}-${name}`;
|
|
9880
|
+
const state = asRecord4(part.state);
|
|
9881
|
+
const input = asRecord4(state?.input) ?? asRecord4(part.input);
|
|
9882
|
+
const nested = [
|
|
9883
|
+
withEventParentId({ type: "tool_use", id, name, input }, parentId)
|
|
9884
|
+
];
|
|
9885
|
+
const output = state?.output ?? part.output;
|
|
9886
|
+
if (output != null || state?.status === "completed" || state?.status === "error") {
|
|
9887
|
+
nested.push(
|
|
9888
|
+
withEventParentId(
|
|
9889
|
+
{
|
|
9890
|
+
type: "tool_result",
|
|
9891
|
+
id,
|
|
9892
|
+
content: typeof output === "string" ? output : output != null ? JSON.stringify(output) : void 0,
|
|
9893
|
+
isError: state?.status === "error" || state?.status === "failed"
|
|
9894
|
+
},
|
|
9895
|
+
parentId
|
|
9896
|
+
)
|
|
9897
|
+
);
|
|
9898
|
+
}
|
|
9899
|
+
return withTaskParent(parentId, nested);
|
|
9900
|
+
}
|
|
9901
|
+
return null;
|
|
9902
|
+
}
|
|
9461
9903
|
if (obj.type === "tool_result") {
|
|
9462
9904
|
const part = obj.part;
|
|
9463
9905
|
const id = part?.tool_use_id ?? part?.id ?? obj.tool_use_id ?? obj.id;
|
|
@@ -9887,422 +10329,189 @@ async function installAgent(agent) {
|
|
|
9887
10329
|
};
|
|
9888
10330
|
}
|
|
9889
10331
|
}
|
|
9890
|
-
enrichPathWithNpmGlobalBin();
|
|
9891
|
-
let binPath = null;
|
|
9892
|
-
if (cliBin) {
|
|
9893
|
-
binPath = await whichCli(cliBin);
|
|
9894
|
-
}
|
|
9895
|
-
return {
|
|
9896
|
-
ok: true,
|
|
9897
|
-
command: info.installCommand,
|
|
9898
|
-
exitCode: 0,
|
|
9899
|
-
stdout: result.stdout,
|
|
9900
|
-
stderr: result.stderr,
|
|
9901
|
-
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)`
|
|
9902
|
-
};
|
|
9903
|
-
}
|
|
9904
|
-
async function loginAgent(agent) {
|
|
9905
|
-
const info = getAgentSetupInfo(agent);
|
|
9906
|
-
const loginCommand = resolveLoginCommand(agent);
|
|
9907
|
-
if (!loginCommand) {
|
|
9908
|
-
return {
|
|
9909
|
-
ok: true,
|
|
9910
|
-
message: info.kind === "bundled-sdk" || info.kind === "api-key" ? info.summary : `No login command for ${agent}`
|
|
9911
|
-
};
|
|
9912
|
-
}
|
|
9913
|
-
const prepared = await prepareTerminalCommand(loginCommand);
|
|
9914
|
-
await openInSystemTerminal(prepared);
|
|
9915
|
-
return {
|
|
9916
|
-
ok: true,
|
|
9917
|
-
openedTerminal: true,
|
|
9918
|
-
command: prepared,
|
|
9919
|
-
message: `Opened Terminal to run: ${prepared}`
|
|
9920
|
-
};
|
|
9921
|
-
}
|
|
9922
|
-
var SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
|
|
9923
|
-
var init_install = __esm({
|
|
9924
|
-
"src/agents/install.ts"() {
|
|
9925
|
-
"use strict";
|
|
9926
|
-
init_run();
|
|
9927
|
-
init_app_settings();
|
|
9928
|
-
init_path();
|
|
9929
|
-
SETUP = {
|
|
9930
|
-
claude: {
|
|
9931
|
-
agent: "claude",
|
|
9932
|
-
kind: "cli",
|
|
9933
|
-
summary: "Install the Claude Code CLI, then complete login in a terminal.",
|
|
9934
|
-
docsUrl: "https://code.claude.com/docs/en/install",
|
|
9935
|
-
installCommand: "npm install -g @anthropic-ai/claude-code",
|
|
9936
|
-
loginCommand: "claude auth login",
|
|
9937
|
-
npmPackage: "@anthropic-ai/claude-code"
|
|
9938
|
-
},
|
|
9939
|
-
codex: {
|
|
9940
|
-
agent: "codex",
|
|
9941
|
-
kind: "cli",
|
|
9942
|
-
summary: "Install the Codex CLI, then run login in a terminal.",
|
|
9943
|
-
docsUrl: "https://github.com/openai/codex",
|
|
9944
|
-
installCommand: "npm install -g @openai/codex",
|
|
9945
|
-
loginCommand: "codex login",
|
|
9946
|
-
npmPackage: "@openai/codex"
|
|
9947
|
-
},
|
|
9948
|
-
opencode: {
|
|
9949
|
-
agent: "opencode",
|
|
9950
|
-
kind: "cli",
|
|
9951
|
-
summary: "Install OpenCode (curl installer or npm), then authenticate providers.",
|
|
9952
|
-
docsUrl: "https://opencode.ai/docs",
|
|
9953
|
-
// Prefer the official installer; npm package name is opencode-ai.
|
|
9954
|
-
installCommand: "curl -fsSL https://opencode.ai/install | bash",
|
|
9955
|
-
loginCommand: "opencode auth login",
|
|
9956
|
-
npmPackage: "opencode-ai@latest"
|
|
9957
|
-
},
|
|
9958
|
-
cursor: {
|
|
9959
|
-
agent: "cursor",
|
|
9960
|
-
kind: "bundled-sdk",
|
|
9961
|
-
summary: "No CLI install \u2014 Sideboard ships the Cursor SDK. Add a CURSOR_API_KEY from the Cursor dashboard.",
|
|
9962
|
-
docsUrl: "https://cursor.com/dashboard/integrations",
|
|
9963
|
-
installCommand: null,
|
|
9964
|
-
loginCommand: null
|
|
9965
|
-
},
|
|
9966
|
-
brightsy: {
|
|
9967
|
-
agent: "brightsy",
|
|
9968
|
-
kind: "cli",
|
|
9969
|
-
summary: "Install the Brightsy CLI, then run `brightsy login`.",
|
|
9970
|
-
docsUrl: "https://www.npmjs.com/package/@brightsy/cli",
|
|
9971
|
-
installCommand: "npm install -g @brightsy/cli",
|
|
9972
|
-
loginCommand: "brightsy login",
|
|
9973
|
-
npmPackage: "@brightsy/cli"
|
|
9974
|
-
}
|
|
9975
|
-
};
|
|
9976
|
-
CLI_BIN = {
|
|
9977
|
-
claude: "claude",
|
|
9978
|
-
codex: "codex",
|
|
9979
|
-
opencode: "opencode",
|
|
9980
|
-
brightsy: "brightsy"
|
|
9981
|
-
};
|
|
9982
|
-
CLI_LOGIN_AGENTS = /* @__PURE__ */ new Set([
|
|
9983
|
-
"claude",
|
|
9984
|
-
"codex",
|
|
9985
|
-
"opencode",
|
|
9986
|
-
"brightsy"
|
|
9987
|
-
]);
|
|
9988
|
-
}
|
|
9989
|
-
});
|
|
9990
|
-
|
|
9991
|
-
// src/agents/index.ts
|
|
9992
|
-
var agents_exports = {};
|
|
9993
|
-
__export(agents_exports, {
|
|
9994
|
-
CLAUDE_MODEL_CATALOG: () => CLAUDE_MODEL_CATALOG,
|
|
9995
|
-
ORCHESTRATOR_AGENT_KINDS: () => ORCHESTRATOR_AGENT_KINDS,
|
|
9996
|
-
PLAN_MODE_INSTRUCTION: () => PLAN_MODE_INSTRUCTION,
|
|
9997
|
-
allAdapters: () => allAdapters,
|
|
9998
|
-
assertOrchestratorCapableAgent: () => assertOrchestratorCapableAgent,
|
|
9999
|
-
brightsyAdapter: () => brightsyAdapter,
|
|
10000
|
-
claudeAdapter: () => claudeAdapter,
|
|
10001
|
-
codexAdapter: () => codexAdapter,
|
|
10002
|
-
coerceOrchestratorAgent: () => coerceOrchestratorAgent,
|
|
10003
|
-
conductorBundledBinDir: () => conductorBundledBinDir,
|
|
10004
|
-
cursorAdapter: () => cursorAdapter,
|
|
10005
|
-
cursorSdkMessageToEvents: () => cursorSdkMessageToEvents,
|
|
10006
|
-
decodeBrightsyTarget: () => decodeBrightsyTarget,
|
|
10007
|
-
encodeBrightsyTarget: () => encodeBrightsyTarget,
|
|
10008
|
-
enrichPathWithNpmGlobalBin: () => enrichPathWithNpmGlobalBin,
|
|
10009
|
-
ensureAgentPath: () => ensureAgentPath,
|
|
10010
|
-
getAdapter: () => getAdapter,
|
|
10011
|
-
getAgentSetupInfo: () => getAgentSetupInfo,
|
|
10012
|
-
installAgent: () => installAgent,
|
|
10013
|
-
isConductorBundledCli: () => isConductorBundledCli,
|
|
10014
|
-
isCursorAutoModel: () => isCursorAutoModel,
|
|
10015
|
-
isOrchestratorCapableAgent: () => isOrchestratorCapableAgent,
|
|
10016
|
-
isSessionQuotaLimit: () => isSessionQuotaLimit,
|
|
10017
|
-
listAgentSetupInfo: () => listAgentSetupInfo,
|
|
10018
|
-
listBrightsyChatTargets: () => listBrightsyChatTargets,
|
|
10019
|
-
listCodexModels: () => listCodexModels,
|
|
10020
|
-
listCursorModels: () => listCursorModels,
|
|
10021
|
-
listModelsForAgent: () => listModelsForAgent,
|
|
10022
|
-
listOpencodeModels: () => listOpencodeModels,
|
|
10023
|
-
loginAgent: () => loginAgent,
|
|
10024
|
-
openInSystemTerminal: () => openInSystemTerminal,
|
|
10025
|
-
opencodeAdapter: () => opencodeAdapter,
|
|
10026
|
-
parseCursorRunnerLine: () => parseCursorRunnerLine,
|
|
10027
|
-
parseSessionQuotaResetAt: () => parseSessionQuotaResetAt,
|
|
10028
|
-
permissionMode: () => permissionMode,
|
|
10029
|
-
posixShellSingleQuote: () => posixShellSingleQuote,
|
|
10030
|
-
prepareTerminalCommand: () => prepareTerminalCommand,
|
|
10031
|
-
resolveCommandBinarySync: () => resolveCommandBinarySync,
|
|
10032
|
-
resolveCursorModelId: () => resolveCursorModelId,
|
|
10033
|
-
resolveLoginCommand: () => resolveLoginCommand,
|
|
10034
|
-
resolveQuotaFallbackAgent: () => resolveQuotaFallbackAgent,
|
|
10035
|
-
withExportedPath: () => withExportedPath
|
|
10036
|
-
});
|
|
10037
|
-
function getAdapter(kind) {
|
|
10038
|
-
return adapters[kind];
|
|
10039
|
-
}
|
|
10040
|
-
function allAdapters() {
|
|
10041
|
-
return Object.values(adapters);
|
|
10042
|
-
}
|
|
10043
|
-
var adapters;
|
|
10044
|
-
var init_agents = __esm({
|
|
10045
|
-
"src/agents/index.ts"() {
|
|
10046
|
-
"use strict";
|
|
10047
|
-
init_brightsy();
|
|
10048
|
-
init_claude();
|
|
10049
|
-
init_codex();
|
|
10050
|
-
init_cursor();
|
|
10051
|
-
init_opencode();
|
|
10052
|
-
init_types();
|
|
10053
|
-
init_brightsy();
|
|
10054
|
-
init_brightsy_targets();
|
|
10055
|
-
init_claude();
|
|
10056
|
-
init_codex();
|
|
10057
|
-
init_cursor();
|
|
10058
|
-
init_cursor_events();
|
|
10059
|
-
init_cursor();
|
|
10060
|
-
init_opencode();
|
|
10061
|
-
init_list_models();
|
|
10062
|
-
init_session_quota();
|
|
10063
|
-
init_orchestrator_capable();
|
|
10064
|
-
init_path();
|
|
10065
|
-
init_install();
|
|
10066
|
-
adapters = {
|
|
10067
|
-
claude: claudeAdapter,
|
|
10068
|
-
codex: codexAdapter,
|
|
10069
|
-
opencode: opencodeAdapter,
|
|
10070
|
-
brightsy: brightsyAdapter,
|
|
10071
|
-
cursor: cursorAdapter
|
|
10072
|
-
};
|
|
10073
|
-
}
|
|
10074
|
-
});
|
|
10075
|
-
|
|
10076
|
-
// src/agents/message-parts.ts
|
|
10077
|
-
function asRecord3(input) {
|
|
10078
|
-
if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
10079
|
-
return input;
|
|
10080
|
-
}
|
|
10081
|
-
return void 0;
|
|
10082
|
-
}
|
|
10083
|
-
function str2(v) {
|
|
10084
|
-
return typeof v === "string" && v.trim() ? v : void 0;
|
|
10085
|
-
}
|
|
10086
|
-
function toolDetail(name, input) {
|
|
10087
|
-
if (!input) return void 0;
|
|
10088
|
-
const command = str2(input.command) ?? str2(input.cmd);
|
|
10089
|
-
if (command) return command;
|
|
10090
|
-
const path2 = str2(input.file_path) ?? str2(input.path) ?? str2(input.filePath) ?? str2(input.filename);
|
|
10091
|
-
if (path2) return path2;
|
|
10092
|
-
const pattern = str2(input.pattern) ?? str2(input.glob) ?? str2(input.glob_pattern);
|
|
10093
|
-
if (pattern) return pattern;
|
|
10094
|
-
const query = str2(input.query) ?? str2(input.prompt);
|
|
10095
|
-
if (query) return query.length > 80 ? `${query.slice(0, 77)}\u2026` : query;
|
|
10096
|
-
try {
|
|
10097
|
-
const raw = JSON.stringify(input);
|
|
10098
|
-
return raw.length > 80 ? `${raw.slice(0, 77)}\u2026` : raw;
|
|
10099
|
-
} catch {
|
|
10100
|
-
return name;
|
|
10101
|
-
}
|
|
10102
|
-
}
|
|
10103
|
-
function toolDescription(name, input) {
|
|
10104
|
-
const n = name.replace(/^mcp__/, "").replace(/__/g, " \xB7 ");
|
|
10105
|
-
if (/^get_record_types$|recordTypes/i.test(name)) return "List record types";
|
|
10106
|
-
if (/connectedAgentRequest/i.test(name)) {
|
|
10107
|
-
return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
|
|
10108
|
-
}
|
|
10109
|
-
if (/present_artifact$/i.test(name)) {
|
|
10110
|
-
return str2(input?.title) ? `Present ${str2(input?.title)}` : "Present artifact";
|
|
10111
|
-
}
|
|
10112
|
-
if (/present_plan$/i.test(name)) {
|
|
10113
|
-
return str2(input?.title) ? `Plan ${str2(input?.title)}` : "Present plan";
|
|
10114
|
-
}
|
|
10115
|
-
if (/present_schema$/i.test(name)) {
|
|
10116
|
-
return str2(input?.title) ? `Schema ${str2(input?.title)}` : "Present schema";
|
|
10117
|
-
}
|
|
10118
|
-
if (/present_files$/i.test(name)) {
|
|
10119
|
-
return str2(input?.title) ? `Files ${str2(input?.title)}` : "Present files";
|
|
10120
|
-
}
|
|
10121
|
-
if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
|
|
10122
|
-
return str2(input?.title) ? `Artifact ${str2(input?.title)}` : "Artifact";
|
|
10123
|
-
}
|
|
10124
|
-
if (!input) return n;
|
|
10125
|
-
if (/bash|shell|terminal/i.test(name) && str2(input.command)) {
|
|
10126
|
-
const cmd = str2(input.command);
|
|
10127
|
-
if (/git\s+fetch/i.test(cmd)) return "Fetch latest from origin and check status";
|
|
10128
|
-
if (/git\s+status/i.test(cmd)) return "Check git status";
|
|
10129
|
-
if (/git\s+log/i.test(cmd)) return "Inspect recent commits";
|
|
10130
|
-
if (/git\s+branch/i.test(cmd)) return "List branches";
|
|
10131
|
-
if (/grep|rg\b/i.test(cmd)) return "Search repository";
|
|
10132
|
-
return "Run shell command";
|
|
10133
|
-
}
|
|
10134
|
-
if (/edit|write|apply/i.test(name)) {
|
|
10135
|
-
const path2 = str2(input.file_path) ?? str2(input.path);
|
|
10136
|
-
return path2 ? `Edit ${path2.split("/").pop()}` : "Edit file";
|
|
10137
|
-
}
|
|
10138
|
-
if (/read/i.test(name)) {
|
|
10139
|
-
const path2 = str2(input.file_path) ?? str2(input.path);
|
|
10140
|
-
return path2 ? `Read ${path2.split("/").pop()}` : "Read file";
|
|
10141
|
-
}
|
|
10142
|
-
if (/grep/i.test(name)) return "Search files";
|
|
10143
|
-
if (/glob/i.test(name)) return "Find files";
|
|
10144
|
-
return n;
|
|
10145
|
-
}
|
|
10146
|
-
function toolFilePath(input) {
|
|
10147
|
-
if (!input) return void 0;
|
|
10148
|
-
return str2(input.file_path) ?? str2(input.path) ?? str2(input.filePath) ?? str2(input.filename);
|
|
10149
|
-
}
|
|
10150
|
-
function countLines(text4) {
|
|
10151
|
-
if (!text4) return 0;
|
|
10152
|
-
return text4.split("\n").length;
|
|
10153
|
-
}
|
|
10154
|
-
function diffFromInput(input) {
|
|
10155
|
-
if (!input) return {};
|
|
10156
|
-
const oldS = str2(input.old_string) ?? str2(input.oldString);
|
|
10157
|
-
const newS = str2(input.new_string) ?? str2(input.newString) ?? str2(input.content);
|
|
10158
|
-
if (oldS != null || newS != null) {
|
|
10159
|
-
return {
|
|
10160
|
-
additions: countLines(newS),
|
|
10161
|
-
deletions: countLines(oldS)
|
|
10162
|
-
};
|
|
10163
|
-
}
|
|
10164
|
-
return {};
|
|
10165
|
-
}
|
|
10166
|
-
function parseDiffStat(result) {
|
|
10167
|
-
if (!result) return {};
|
|
10168
|
-
const paired = result.match(/\+(\d+)\s+-(\d+)/);
|
|
10169
|
-
if (paired) {
|
|
10170
|
-
return {
|
|
10171
|
-
additions: Number(paired[1]),
|
|
10172
|
-
deletions: Number(paired[2])
|
|
10173
|
-
};
|
|
10174
|
-
}
|
|
10175
|
-
const verbose = result.match(
|
|
10176
|
-
/(\d+)\s+insertions?(?:,\s*(\d+)\s+deletions?)?/i
|
|
10177
|
-
);
|
|
10178
|
-
if (verbose) {
|
|
10179
|
-
return {
|
|
10180
|
-
additions: Number(verbose[1]),
|
|
10181
|
-
deletions: verbose[2] != null ? Number(verbose[2]) : void 0
|
|
10182
|
-
};
|
|
10183
|
-
}
|
|
10184
|
-
return {};
|
|
10185
|
-
}
|
|
10186
|
-
function applyAgentEvent(parts, event) {
|
|
10187
|
-
if (event.type === "stdout") {
|
|
10188
|
-
const data = event.data;
|
|
10189
|
-
if (!data) return parts;
|
|
10190
|
-
const next = [...parts];
|
|
10191
|
-
const last = next[next.length - 1];
|
|
10192
|
-
if (last?.type === "text") {
|
|
10193
|
-
next[next.length - 1] = { type: "text", text: last.text + data };
|
|
10194
|
-
} else {
|
|
10195
|
-
next.push({ type: "text", text: data });
|
|
10196
|
-
}
|
|
10197
|
-
return next;
|
|
10198
|
-
}
|
|
10199
|
-
if (event.type === "thinking") {
|
|
10200
|
-
const data = event.data;
|
|
10201
|
-
if (!data) return parts;
|
|
10202
|
-
const next = [...parts];
|
|
10203
|
-
const last = next[next.length - 1];
|
|
10204
|
-
if (last?.type === "thinking") {
|
|
10205
|
-
next[next.length - 1] = { type: "thinking", text: last.text + data };
|
|
10206
|
-
} else {
|
|
10207
|
-
next.push({ type: "thinking", text: data });
|
|
10208
|
-
}
|
|
10209
|
-
return next;
|
|
10210
|
-
}
|
|
10211
|
-
if (event.type === "tool_use") {
|
|
10212
|
-
const input = asRecord3(event.input);
|
|
10213
|
-
const diff = diffFromInput(input);
|
|
10214
|
-
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
10215
|
-
if (existing >= 0) {
|
|
10216
|
-
const prev = parts[existing];
|
|
10217
|
-
const next = [...parts];
|
|
10218
|
-
next[existing] = {
|
|
10219
|
-
...prev,
|
|
10220
|
-
name: event.name || prev.name,
|
|
10221
|
-
input: input ?? prev.input,
|
|
10222
|
-
description: toolDescription(event.name || prev.name, input ?? prev.input),
|
|
10223
|
-
detail: toolDetail(event.name || prev.name, input ?? prev.input) ?? prev.detail,
|
|
10224
|
-
filePath: toolFilePath(input) ?? prev.filePath,
|
|
10225
|
-
additions: diff.additions ?? prev.additions,
|
|
10226
|
-
deletions: diff.deletions ?? prev.deletions
|
|
10227
|
-
};
|
|
10228
|
-
return next;
|
|
10229
|
-
}
|
|
10230
|
-
return [
|
|
10231
|
-
...parts,
|
|
10232
|
-
{
|
|
10233
|
-
type: "tool",
|
|
10234
|
-
id: event.id,
|
|
10235
|
-
name: event.name,
|
|
10236
|
-
input,
|
|
10237
|
-
description: toolDescription(event.name, input),
|
|
10238
|
-
detail: toolDetail(event.name, input),
|
|
10239
|
-
status: "running",
|
|
10240
|
-
filePath: toolFilePath(input),
|
|
10241
|
-
...diff
|
|
10242
|
-
}
|
|
10243
|
-
];
|
|
10244
|
-
}
|
|
10245
|
-
if (event.type === "tool_result") {
|
|
10246
|
-
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
10247
|
-
const fromResult = parseDiffStat(event.content);
|
|
10248
|
-
if (existing < 0) {
|
|
10249
|
-
return [
|
|
10250
|
-
...parts,
|
|
10251
|
-
{
|
|
10252
|
-
type: "tool",
|
|
10253
|
-
id: event.id,
|
|
10254
|
-
name: "tool",
|
|
10255
|
-
description: "tool",
|
|
10256
|
-
status: event.isError ? "error" : "done",
|
|
10257
|
-
result: event.content,
|
|
10258
|
-
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
10259
|
-
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
10260
|
-
}
|
|
10261
|
-
];
|
|
10262
|
-
}
|
|
10263
|
-
return parts.map((p, i) => {
|
|
10264
|
-
if (i !== existing || p.type !== "tool") return p;
|
|
10265
|
-
return {
|
|
10266
|
-
...p,
|
|
10267
|
-
status: event.isError ? "error" : "done",
|
|
10268
|
-
result: event.content,
|
|
10269
|
-
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
10270
|
-
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
10271
|
-
};
|
|
10272
|
-
});
|
|
10273
|
-
}
|
|
10274
|
-
return parts;
|
|
10275
|
-
}
|
|
10276
|
-
function partsToAssistantText(parts) {
|
|
10277
|
-
return parts.filter((p) => p.type === "text").map((p) => p.text).join("").trim();
|
|
10278
|
-
}
|
|
10279
|
-
function stripBrightsyNdjsonNoise(text4) {
|
|
10280
|
-
if (!text4 || !text4.includes('"type"')) return text4;
|
|
10281
|
-
let out = text4;
|
|
10282
|
-
out = out.replace(
|
|
10283
|
-
/\{"type":"(?:tool_use|tool_result|tool|thinking|usage|done|error)"[\s\S]*?\}\s*(?=\{"type":"|$|(?=[A-Za-z*#]))/g,
|
|
10284
|
-
""
|
|
10285
|
-
);
|
|
10286
|
-
out = out.replace(/\{"type":"(?:tool_use|tool_result|tool)"[\s\S]*$/g, "");
|
|
10287
|
-
return out.trim();
|
|
10332
|
+
enrichPathWithNpmGlobalBin();
|
|
10333
|
+
let binPath = null;
|
|
10334
|
+
if (cliBin) {
|
|
10335
|
+
binPath = await whichCli(cliBin);
|
|
10336
|
+
}
|
|
10337
|
+
return {
|
|
10338
|
+
ok: true,
|
|
10339
|
+
command: info.installCommand,
|
|
10340
|
+
exitCode: 0,
|
|
10341
|
+
stdout: result.stdout,
|
|
10342
|
+
stderr: result.stderr,
|
|
10343
|
+
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)`
|
|
10344
|
+
};
|
|
10288
10345
|
}
|
|
10289
|
-
function
|
|
10290
|
-
const
|
|
10291
|
-
|
|
10292
|
-
|
|
10346
|
+
async function loginAgent(agent) {
|
|
10347
|
+
const info = getAgentSetupInfo(agent);
|
|
10348
|
+
const loginCommand = resolveLoginCommand(agent);
|
|
10349
|
+
if (!loginCommand) {
|
|
10350
|
+
return {
|
|
10351
|
+
ok: true,
|
|
10352
|
+
message: info.kind === "bundled-sdk" || info.kind === "api-key" ? info.summary : `No login command for ${agent}`
|
|
10353
|
+
};
|
|
10354
|
+
}
|
|
10355
|
+
const prepared = await prepareTerminalCommand(loginCommand);
|
|
10356
|
+
await openInSystemTerminal(prepared);
|
|
10357
|
+
return {
|
|
10358
|
+
ok: true,
|
|
10359
|
+
openedTerminal: true,
|
|
10360
|
+
command: prepared,
|
|
10361
|
+
message: `Opened Terminal to run: ${prepared}`
|
|
10362
|
+
};
|
|
10293
10363
|
}
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10364
|
+
var SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
|
|
10365
|
+
var init_install = __esm({
|
|
10366
|
+
"src/agents/install.ts"() {
|
|
10367
|
+
"use strict";
|
|
10368
|
+
init_run();
|
|
10369
|
+
init_app_settings();
|
|
10370
|
+
init_path();
|
|
10371
|
+
SETUP = {
|
|
10372
|
+
claude: {
|
|
10373
|
+
agent: "claude",
|
|
10374
|
+
kind: "cli",
|
|
10375
|
+
summary: "Install the Claude Code CLI, then complete login in a terminal.",
|
|
10376
|
+
docsUrl: "https://code.claude.com/docs/en/install",
|
|
10377
|
+
installCommand: "npm install -g @anthropic-ai/claude-code",
|
|
10378
|
+
loginCommand: "claude auth login",
|
|
10379
|
+
npmPackage: "@anthropic-ai/claude-code"
|
|
10380
|
+
},
|
|
10381
|
+
codex: {
|
|
10382
|
+
agent: "codex",
|
|
10383
|
+
kind: "cli",
|
|
10384
|
+
summary: "Install the Codex CLI, then run login in a terminal.",
|
|
10385
|
+
docsUrl: "https://github.com/openai/codex",
|
|
10386
|
+
installCommand: "npm install -g @openai/codex",
|
|
10387
|
+
loginCommand: "codex login",
|
|
10388
|
+
npmPackage: "@openai/codex"
|
|
10389
|
+
},
|
|
10390
|
+
opencode: {
|
|
10391
|
+
agent: "opencode",
|
|
10392
|
+
kind: "cli",
|
|
10393
|
+
summary: "Install OpenCode (curl installer or npm), then authenticate providers.",
|
|
10394
|
+
docsUrl: "https://opencode.ai/docs",
|
|
10395
|
+
// Prefer the official installer; npm package name is opencode-ai.
|
|
10396
|
+
installCommand: "curl -fsSL https://opencode.ai/install | bash",
|
|
10397
|
+
loginCommand: "opencode auth login",
|
|
10398
|
+
npmPackage: "opencode-ai@latest"
|
|
10399
|
+
},
|
|
10400
|
+
cursor: {
|
|
10401
|
+
agent: "cursor",
|
|
10402
|
+
kind: "bundled-sdk",
|
|
10403
|
+
summary: "No CLI install \u2014 Sideboard ships the Cursor SDK. Add a CURSOR_API_KEY from the Cursor dashboard.",
|
|
10404
|
+
docsUrl: "https://cursor.com/dashboard/integrations",
|
|
10405
|
+
installCommand: null,
|
|
10406
|
+
loginCommand: null
|
|
10407
|
+
},
|
|
10408
|
+
brightsy: {
|
|
10409
|
+
agent: "brightsy",
|
|
10410
|
+
kind: "cli",
|
|
10411
|
+
summary: "Install the Brightsy CLI, then run `brightsy login`.",
|
|
10412
|
+
docsUrl: "https://www.npmjs.com/package/@brightsy/cli",
|
|
10413
|
+
installCommand: "npm install -g @brightsy/cli",
|
|
10414
|
+
loginCommand: "brightsy login",
|
|
10415
|
+
npmPackage: "@brightsy/cli"
|
|
10416
|
+
}
|
|
10417
|
+
};
|
|
10418
|
+
CLI_BIN = {
|
|
10419
|
+
claude: "claude",
|
|
10420
|
+
codex: "codex",
|
|
10421
|
+
opencode: "opencode",
|
|
10422
|
+
brightsy: "brightsy"
|
|
10423
|
+
};
|
|
10424
|
+
CLI_LOGIN_AGENTS = /* @__PURE__ */ new Set([
|
|
10425
|
+
"claude",
|
|
10426
|
+
"codex",
|
|
10427
|
+
"opencode",
|
|
10428
|
+
"brightsy"
|
|
10429
|
+
]);
|
|
10430
|
+
}
|
|
10431
|
+
});
|
|
10432
|
+
|
|
10433
|
+
// src/agents/index.ts
|
|
10434
|
+
var agents_exports = {};
|
|
10435
|
+
__export(agents_exports, {
|
|
10436
|
+
CLAUDE_MODEL_CATALOG: () => CLAUDE_MODEL_CATALOG,
|
|
10437
|
+
ORCHESTRATOR_AGENT_KINDS: () => ORCHESTRATOR_AGENT_KINDS,
|
|
10438
|
+
PLAN_MODE_INSTRUCTION: () => PLAN_MODE_INSTRUCTION,
|
|
10439
|
+
allAdapters: () => allAdapters,
|
|
10440
|
+
assertOrchestratorCapableAgent: () => assertOrchestratorCapableAgent,
|
|
10441
|
+
brightsyAdapter: () => brightsyAdapter,
|
|
10442
|
+
claudeAdapter: () => claudeAdapter,
|
|
10443
|
+
codexAdapter: () => codexAdapter,
|
|
10444
|
+
coerceOrchestratorAgent: () => coerceOrchestratorAgent,
|
|
10445
|
+
conductorBundledBinDir: () => conductorBundledBinDir,
|
|
10446
|
+
cursorAdapter: () => cursorAdapter,
|
|
10447
|
+
cursorSdkMessageToEvents: () => cursorSdkMessageToEvents,
|
|
10448
|
+
decodeBrightsyTarget: () => decodeBrightsyTarget,
|
|
10449
|
+
encodeBrightsyTarget: () => encodeBrightsyTarget,
|
|
10450
|
+
enrichPathWithNpmGlobalBin: () => enrichPathWithNpmGlobalBin,
|
|
10451
|
+
ensureAgentPath: () => ensureAgentPath,
|
|
10452
|
+
getAdapter: () => getAdapter,
|
|
10453
|
+
getAgentSetupInfo: () => getAgentSetupInfo,
|
|
10454
|
+
installAgent: () => installAgent,
|
|
10455
|
+
isConductorBundledCli: () => isConductorBundledCli,
|
|
10456
|
+
isCursorAutoModel: () => isCursorAutoModel,
|
|
10457
|
+
isOrchestratorCapableAgent: () => isOrchestratorCapableAgent,
|
|
10458
|
+
isSessionQuotaLimit: () => isSessionQuotaLimit,
|
|
10459
|
+
listAgentSetupInfo: () => listAgentSetupInfo,
|
|
10460
|
+
listBrightsyChatTargets: () => listBrightsyChatTargets,
|
|
10461
|
+
listCodexModels: () => listCodexModels,
|
|
10462
|
+
listCursorModels: () => listCursorModels,
|
|
10463
|
+
listModelsForAgent: () => listModelsForAgent,
|
|
10464
|
+
listOpencodeModels: () => listOpencodeModels,
|
|
10465
|
+
loginAgent: () => loginAgent,
|
|
10466
|
+
openInSystemTerminal: () => openInSystemTerminal,
|
|
10467
|
+
opencodeAdapter: () => opencodeAdapter,
|
|
10468
|
+
parseCursorRunnerLine: () => parseCursorRunnerLine,
|
|
10469
|
+
parseSessionQuotaResetAt: () => parseSessionQuotaResetAt,
|
|
10470
|
+
permissionMode: () => permissionMode,
|
|
10471
|
+
posixShellSingleQuote: () => posixShellSingleQuote,
|
|
10472
|
+
prepareTerminalCommand: () => prepareTerminalCommand,
|
|
10473
|
+
resolveCommandBinarySync: () => resolveCommandBinarySync,
|
|
10474
|
+
resolveCursorModelId: () => resolveCursorModelId,
|
|
10475
|
+
resolveLoginCommand: () => resolveLoginCommand,
|
|
10476
|
+
resolveQuotaFallbackAgent: () => resolveQuotaFallbackAgent,
|
|
10477
|
+
withExportedPath: () => withExportedPath
|
|
10478
|
+
});
|
|
10479
|
+
function getAdapter(kind) {
|
|
10480
|
+
return adapters[kind];
|
|
10298
10481
|
}
|
|
10299
|
-
function
|
|
10300
|
-
|
|
10301
|
-
return Array.isArray(parsed) ? parsed : [parsed];
|
|
10482
|
+
function allAdapters() {
|
|
10483
|
+
return Object.values(adapters);
|
|
10302
10484
|
}
|
|
10303
|
-
var
|
|
10304
|
-
|
|
10485
|
+
var adapters;
|
|
10486
|
+
var init_agents = __esm({
|
|
10487
|
+
"src/agents/index.ts"() {
|
|
10305
10488
|
"use strict";
|
|
10489
|
+
init_brightsy();
|
|
10490
|
+
init_claude();
|
|
10491
|
+
init_codex();
|
|
10492
|
+
init_cursor();
|
|
10493
|
+
init_opencode();
|
|
10494
|
+
init_types();
|
|
10495
|
+
init_brightsy();
|
|
10496
|
+
init_brightsy_targets();
|
|
10497
|
+
init_claude();
|
|
10498
|
+
init_codex();
|
|
10499
|
+
init_cursor();
|
|
10500
|
+
init_cursor_events();
|
|
10501
|
+
init_cursor();
|
|
10502
|
+
init_opencode();
|
|
10503
|
+
init_list_models();
|
|
10504
|
+
init_session_quota();
|
|
10505
|
+
init_orchestrator_capable();
|
|
10506
|
+
init_path();
|
|
10507
|
+
init_install();
|
|
10508
|
+
adapters = {
|
|
10509
|
+
claude: claudeAdapter,
|
|
10510
|
+
codex: codexAdapter,
|
|
10511
|
+
opencode: opencodeAdapter,
|
|
10512
|
+
brightsy: brightsyAdapter,
|
|
10513
|
+
cursor: cursorAdapter
|
|
10514
|
+
};
|
|
10306
10515
|
}
|
|
10307
10516
|
});
|
|
10308
10517
|
|
|
@@ -10310,6 +10519,9 @@ var init_message_parts = __esm({
|
|
|
10310
10519
|
function isTextEvent(event) {
|
|
10311
10520
|
return event.type === "stdout" || event.type === "thinking";
|
|
10312
10521
|
}
|
|
10522
|
+
function parentKey(event) {
|
|
10523
|
+
return event.parentId ?? "";
|
|
10524
|
+
}
|
|
10313
10525
|
function createAgentStreamCoalescer(emit, opts) {
|
|
10314
10526
|
const intervalMs = opts?.intervalMs ?? 32;
|
|
10315
10527
|
let pending = null;
|
|
@@ -10322,7 +10534,11 @@ function createAgentStreamCoalescer(emit, opts) {
|
|
|
10322
10534
|
if (!pending) return;
|
|
10323
10535
|
const event = pending;
|
|
10324
10536
|
pending = null;
|
|
10325
|
-
emit({
|
|
10537
|
+
emit({
|
|
10538
|
+
type: event.type,
|
|
10539
|
+
data: event.data,
|
|
10540
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
10541
|
+
});
|
|
10326
10542
|
};
|
|
10327
10543
|
const schedule = () => {
|
|
10328
10544
|
if (timer) return;
|
|
@@ -10337,11 +10553,15 @@ function createAgentStreamCoalescer(emit, opts) {
|
|
|
10337
10553
|
return;
|
|
10338
10554
|
}
|
|
10339
10555
|
if (!event.data) return;
|
|
10340
|
-
if (pending && pending.type === event.type) {
|
|
10556
|
+
if (pending && pending.type === event.type && parentKey(pending) === parentKey(event)) {
|
|
10341
10557
|
pending.data += event.data;
|
|
10342
10558
|
} else {
|
|
10343
10559
|
flush2();
|
|
10344
|
-
pending = {
|
|
10560
|
+
pending = {
|
|
10561
|
+
type: event.type,
|
|
10562
|
+
data: event.data,
|
|
10563
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
10564
|
+
};
|
|
10345
10565
|
}
|
|
10346
10566
|
schedule();
|
|
10347
10567
|
},
|
|
@@ -10971,7 +11191,8 @@ function worktreeBindingFrom(from) {
|
|
|
10971
11191
|
prState: from.prState,
|
|
10972
11192
|
skipAutoArchiveOnMerge: from.skipAutoArchiveOnMerge,
|
|
10973
11193
|
stackId: from.stackId,
|
|
10974
|
-
stackLayer: from.stackLayer
|
|
11194
|
+
stackLayer: from.stackLayer,
|
|
11195
|
+
cowboy: from.cowboy
|
|
10975
11196
|
};
|
|
10976
11197
|
}
|
|
10977
11198
|
function threadsSharingWorktree(worktreePath) {
|
|
@@ -12143,6 +12364,55 @@ async function createThread(input, _onSetupLine) {
|
|
|
12143
12364
|
if (!(0, import_node_fs34.existsSync)(repoPath)) {
|
|
12144
12365
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
12145
12366
|
}
|
|
12367
|
+
if (input.cowboy) {
|
|
12368
|
+
const { cowboyModeEnabled: cowboyModeEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
12369
|
+
if (!cowboyModeEnabled2()) {
|
|
12370
|
+
throw new Error(
|
|
12371
|
+
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
12372
|
+
);
|
|
12373
|
+
}
|
|
12374
|
+
if (input.sourceType === "pr" || input.sourceType === "ticket" || input.sourceType === "adopt") {
|
|
12375
|
+
throw new Error(
|
|
12376
|
+
"Cowboy mode works on the project folder (default branch), not a PR, ticket, or adopt."
|
|
12377
|
+
);
|
|
12378
|
+
}
|
|
12379
|
+
const defaultBranch = await resolveDefaultBranch(repoPath, { network: false });
|
|
12380
|
+
const head = await currentBranch(repoPath);
|
|
12381
|
+
if (head === "HEAD") {
|
|
12382
|
+
throw new Error(
|
|
12383
|
+
"Cowboy mode needs a named branch in the project folder (not a detached HEAD)."
|
|
12384
|
+
);
|
|
12385
|
+
}
|
|
12386
|
+
if (head !== defaultBranch) {
|
|
12387
|
+
throw new Error(
|
|
12388
|
+
`Cowboy mode uses ${defaultBranch} in the project folder. Switch that checkout to ${defaultBranch} first (currently ${head}).`
|
|
12389
|
+
);
|
|
12390
|
+
}
|
|
12391
|
+
const explicitTitle2 = input.title?.trim();
|
|
12392
|
+
const thread2 = createEmptyThread({
|
|
12393
|
+
title: explicitTitle2 || `Cowboy \xB7 ${head}`,
|
|
12394
|
+
userSetTitle: Boolean(explicitTitle2),
|
|
12395
|
+
sourceType: "branch",
|
|
12396
|
+
sourceRef: head,
|
|
12397
|
+
branchName: head,
|
|
12398
|
+
worktreePath: repoPath,
|
|
12399
|
+
repoPath,
|
|
12400
|
+
agent: resolved.agent,
|
|
12401
|
+
autonomy: input.autonomy ?? "default",
|
|
12402
|
+
model: resolved.model,
|
|
12403
|
+
effort: resolved.effort,
|
|
12404
|
+
fast: resolved.fast,
|
|
12405
|
+
planMode: Boolean(input.planMode),
|
|
12406
|
+
attachments: input.attachments ?? [],
|
|
12407
|
+
sourceIsFork: false,
|
|
12408
|
+
parentThreadId: input.parentThreadId ?? null,
|
|
12409
|
+
status: "idle",
|
|
12410
|
+
cowboy: true
|
|
12411
|
+
});
|
|
12412
|
+
writeThread(thread2);
|
|
12413
|
+
await ensureWorkspace(repoPath);
|
|
12414
|
+
return readThread(thread2.id) ?? thread2;
|
|
12415
|
+
}
|
|
12146
12416
|
let sourceRef = input.sourceRef;
|
|
12147
12417
|
let sourceIsFork = false;
|
|
12148
12418
|
let prUrl = null;
|
|
@@ -12228,6 +12498,24 @@ var init_create = __esm({
|
|
|
12228
12498
|
}
|
|
12229
12499
|
});
|
|
12230
12500
|
|
|
12501
|
+
// src/threads/cowboy.ts
|
|
12502
|
+
function isCowboyThread(thread) {
|
|
12503
|
+
return Boolean(thread?.cowboy);
|
|
12504
|
+
}
|
|
12505
|
+
function isPrimaryCheckoutThread(thread) {
|
|
12506
|
+
if (!thread?.worktreePath || !thread.repoPath) return false;
|
|
12507
|
+
return normalizeWorktreePath(thread.worktreePath) === normalizeWorktreePath(thread.repoPath);
|
|
12508
|
+
}
|
|
12509
|
+
function shouldRemoveWorktreeOnTeardown(thread) {
|
|
12510
|
+
return !isCowboyThread(thread) && !isPrimaryCheckoutThread(thread);
|
|
12511
|
+
}
|
|
12512
|
+
var init_cowboy = __esm({
|
|
12513
|
+
"src/threads/cowboy.ts"() {
|
|
12514
|
+
"use strict";
|
|
12515
|
+
init_worktree_labels();
|
|
12516
|
+
}
|
|
12517
|
+
});
|
|
12518
|
+
|
|
12231
12519
|
// src/store/turn-live.ts
|
|
12232
12520
|
function trimParts(parts) {
|
|
12233
12521
|
if (parts.length <= MAX_PARTS) return parts;
|
|
@@ -13883,13 +14171,22 @@ async function previewLand(thread) {
|
|
|
13883
14171
|
isFork: true
|
|
13884
14172
|
};
|
|
13885
14173
|
}
|
|
13886
|
-
|
|
13887
|
-
|
|
14174
|
+
if (isCowboyThread(thread)) {
|
|
14175
|
+
const current2 = await currentBranch(thread.worktreePath);
|
|
14176
|
+
const dirty = await isDirty(thread.worktreePath);
|
|
14177
|
+
const diff2 = await getDiff(thread.worktreePath, thread.repoPath, { base: current2 });
|
|
14178
|
+
return {
|
|
14179
|
+
branch: current2,
|
|
14180
|
+
target: current2,
|
|
14181
|
+
diffStat: diff2.stat,
|
|
14182
|
+
dirty,
|
|
14183
|
+
blocked: false,
|
|
14184
|
+
isFork: false,
|
|
14185
|
+
cowboy: true
|
|
14186
|
+
};
|
|
13888
14187
|
}
|
|
13889
|
-
const
|
|
13890
|
-
|
|
13891
|
-
);
|
|
13892
|
-
const current = head.trim();
|
|
14188
|
+
const target = await resolveDefaultBranch(thread.repoPath);
|
|
14189
|
+
const current = await currentBranch(thread.worktreePath);
|
|
13893
14190
|
if (current === target) {
|
|
13894
14191
|
return {
|
|
13895
14192
|
branch: current,
|
|
@@ -13916,6 +14213,19 @@ async function confirmLand(thread, opts) {
|
|
|
13916
14213
|
if (preview.blocked) {
|
|
13917
14214
|
throw new Error(preview.blockReason ?? "Land blocked");
|
|
13918
14215
|
}
|
|
14216
|
+
if (preview.cowboy) {
|
|
14217
|
+
const meta2 = await suggestPrMetadata(thread.worktreePath, {
|
|
14218
|
+
base: preview.branch,
|
|
14219
|
+
fallbackTitle: thread.title,
|
|
14220
|
+
sourceLabel: `${thread.sourceType}:${thread.sourceRef}`
|
|
14221
|
+
});
|
|
14222
|
+
let committed2 = false;
|
|
14223
|
+
if (preview.dirty) {
|
|
14224
|
+
committed2 = await commitAll(thread.worktreePath, meta2.commitMessage);
|
|
14225
|
+
}
|
|
14226
|
+
await pushBranch(thread.worktreePath, preview.branch);
|
|
14227
|
+
return { prUrl: null, pushed: true, committed: committed2 };
|
|
14228
|
+
}
|
|
13919
14229
|
const meta = await suggestPrMetadata(thread.worktreePath, {
|
|
13920
14230
|
base: preview.target,
|
|
13921
14231
|
fallbackTitle: thread.title,
|
|
@@ -13960,6 +14270,7 @@ var init_land = __esm({
|
|
|
13960
14270
|
init_diff();
|
|
13961
14271
|
init_pr_metadata();
|
|
13962
14272
|
init_gh_errors();
|
|
14273
|
+
init_cowboy();
|
|
13963
14274
|
}
|
|
13964
14275
|
});
|
|
13965
14276
|
|
|
@@ -14649,7 +14960,7 @@ var init_instructions = __esm({
|
|
|
14649
14960
|
});
|
|
14650
14961
|
|
|
14651
14962
|
// src/plan/plan-present.ts
|
|
14652
|
-
function
|
|
14963
|
+
function asRecord5(v) {
|
|
14653
14964
|
return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
14654
14965
|
}
|
|
14655
14966
|
function isPresentPlanToolName(name) {
|
|
@@ -14661,7 +14972,7 @@ function extractPresentedPlan(parts) {
|
|
|
14661
14972
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
14662
14973
|
const p = parts[i];
|
|
14663
14974
|
if (p.type !== "tool" || !isPresentPlanToolName(p.name)) continue;
|
|
14664
|
-
const input =
|
|
14975
|
+
const input = asRecord5(p.input) ?? {};
|
|
14665
14976
|
const content = typeof input.content === "string" ? input.content : typeof input.plan === "string" ? input.plan : typeof input.markdown === "string" ? input.markdown : "";
|
|
14666
14977
|
if (!content.trim()) continue;
|
|
14667
14978
|
const title = typeof input.title === "string" && input.title.trim() ? input.title.trim() : "Plan";
|
|
@@ -14992,6 +15303,7 @@ var init_orchestrator = __esm({
|
|
|
14992
15303
|
init_thread_store();
|
|
14993
15304
|
init_desktop_host();
|
|
14994
15305
|
init_create();
|
|
15306
|
+
init_cowboy();
|
|
14995
15307
|
init_orchestrator_capable();
|
|
14996
15308
|
init_chat_tabs();
|
|
14997
15309
|
init_enqueue_by_key();
|
|
@@ -15268,7 +15580,9 @@ var init_orchestrator = __esm({
|
|
|
15268
15580
|
return thread;
|
|
15269
15581
|
}
|
|
15270
15582
|
async finishCreateThread(threadId, prompt) {
|
|
15271
|
-
const
|
|
15583
|
+
const created = this.getThread(threadId);
|
|
15584
|
+
const skipSetup = isCowboyThread(created);
|
|
15585
|
+
const setup = skipSetup ? Promise.resolve() : this.runSetupAfterCreate(threadId);
|
|
15272
15586
|
if (prompt) {
|
|
15273
15587
|
try {
|
|
15274
15588
|
await this.send(threadId, prompt);
|
|
@@ -15280,6 +15594,7 @@ var init_orchestrator = __esm({
|
|
|
15280
15594
|
}
|
|
15281
15595
|
}
|
|
15282
15596
|
await setup;
|
|
15597
|
+
if (skipSetup) return;
|
|
15283
15598
|
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
15284
15599
|
if (autoRunAfterSetupEnabled2()) {
|
|
15285
15600
|
try {
|
|
@@ -16611,17 +16926,19 @@ var init_orchestrator = __esm({
|
|
|
16611
16926
|
const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
|
|
16612
16927
|
if (siblings.length === 0) {
|
|
16613
16928
|
this.stopDev(thread.id);
|
|
16614
|
-
|
|
16615
|
-
|
|
16616
|
-
|
|
16617
|
-
|
|
16618
|
-
|
|
16619
|
-
|
|
16929
|
+
if (shouldRemoveWorktreeOnTeardown(thread)) {
|
|
16930
|
+
try {
|
|
16931
|
+
await runArchiveScript(thread.repoPath, thread.worktreePath, (line) => {
|
|
16932
|
+
this.emit({
|
|
16933
|
+
type: "turn_output",
|
|
16934
|
+
threadId: thread.id,
|
|
16935
|
+
event: { type: "stdout", data: `[archive] ${line}` }
|
|
16936
|
+
});
|
|
16620
16937
|
});
|
|
16621
|
-
}
|
|
16622
|
-
|
|
16938
|
+
} catch {
|
|
16939
|
+
}
|
|
16940
|
+
await removeWorktree(thread.repoPath, thread.worktreePath);
|
|
16623
16941
|
}
|
|
16624
|
-
await removeWorktree(thread.repoPath, thread.worktreePath);
|
|
16625
16942
|
}
|
|
16626
16943
|
const archived = setStatus(thread.id, "archived");
|
|
16627
16944
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
@@ -16649,15 +16966,17 @@ var init_orchestrator = __esm({
|
|
|
16649
16966
|
const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
|
|
16650
16967
|
if (siblings.length === 0) {
|
|
16651
16968
|
this.stopDev(thread.id);
|
|
16652
|
-
|
|
16653
|
-
|
|
16654
|
-
|
|
16969
|
+
if (shouldRemoveWorktreeOnTeardown(thread)) {
|
|
16970
|
+
try {
|
|
16971
|
+
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
16972
|
+
} catch {
|
|
16973
|
+
}
|
|
16974
|
+
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
16975
|
+
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled2();
|
|
16976
|
+
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
16977
|
+
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
16978
|
+
});
|
|
16655
16979
|
}
|
|
16656
|
-
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
16657
|
-
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled2();
|
|
16658
|
-
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
16659
|
-
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
16660
|
-
});
|
|
16661
16980
|
}
|
|
16662
16981
|
deleteThreadRecord(thread.id);
|
|
16663
16982
|
}
|
|
@@ -16674,6 +16993,11 @@ var init_orchestrator = __esm({
|
|
|
16674
16993
|
return restored2;
|
|
16675
16994
|
}
|
|
16676
16995
|
if (!(0, import_node_fs44.existsSync)(thread.worktreePath)) {
|
|
16996
|
+
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
16997
|
+
throw new Error(
|
|
16998
|
+
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
16999
|
+
);
|
|
17000
|
+
}
|
|
16677
17001
|
const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
|
|
16678
17002
|
const slug = thread.worktreePath.split("/").pop();
|
|
16679
17003
|
const dest = thread.worktreePath;
|
|
@@ -17010,6 +17334,7 @@ __export(index_exports, {
|
|
|
17010
17334
|
coordinatorTurnReminder: () => coordinatorTurnReminder,
|
|
17011
17335
|
copyConfiguredFiles: () => copyConfiguredFiles,
|
|
17012
17336
|
countCacheControlBlocks: () => countCacheControlBlocks,
|
|
17337
|
+
cowboyModeEnabled: () => cowboyModeEnabled,
|
|
17013
17338
|
createChatTab: () => createChatTab,
|
|
17014
17339
|
createEmptyThread: () => createEmptyThread,
|
|
17015
17340
|
createExistingBranchWorktree: () => createExistingBranchWorktree,
|
|
@@ -17160,6 +17485,7 @@ __export(index_exports, {
|
|
|
17160
17485
|
isBrightsyNdjsonLine: () => isBrightsyNdjsonLine,
|
|
17161
17486
|
isCloudCoordinatorThread: () => isCloudCoordinatorThread,
|
|
17162
17487
|
isConductorBundledCli: () => isConductorBundledCli,
|
|
17488
|
+
isCowboyThread: () => isCowboyThread,
|
|
17163
17489
|
isCursorAutoModel: () => isCursorAutoModel,
|
|
17164
17490
|
isDefaultishSourceRef: () => isDefaultishSourceRef,
|
|
17165
17491
|
isDesktopHostAlive: () => isDesktopHostAlive,
|
|
@@ -17178,11 +17504,13 @@ __export(index_exports, {
|
|
|
17178
17504
|
isPlaceholderBranch: () => isPlaceholderBranch,
|
|
17179
17505
|
isPrNotMergeableError: () => isPrNotMergeableError,
|
|
17180
17506
|
isPresentPlanToolName: () => isPresentPlanToolName,
|
|
17507
|
+
isPrimaryCheckoutThread: () => isPrimaryCheckoutThread,
|
|
17181
17508
|
isSessionQuotaLimit: () => isSessionQuotaLimit,
|
|
17182
17509
|
isSideboardScratchPath: () => isSideboardScratchPath,
|
|
17183
17510
|
isSlackCoordinatorThread: () => isSlackCoordinatorThread,
|
|
17184
17511
|
isSlackExternalReplyPrompt: () => isSlackExternalReplyPrompt,
|
|
17185
17512
|
isSlackOAuthCancelled: () => isSlackOAuthCancelled,
|
|
17513
|
+
isSubagentToolName: () => isSubagentToolName,
|
|
17186
17514
|
isThinkingEffort: () => isThinkingEffort,
|
|
17187
17515
|
isThisProcessDesktopHost: () => isThisProcessDesktopHost,
|
|
17188
17516
|
isThreadCaffeinated: () => isThreadCaffeinated,
|
|
@@ -17237,6 +17565,7 @@ __export(index_exports, {
|
|
|
17237
17565
|
mergePrStack: () => mergePrStack,
|
|
17238
17566
|
mergeSideboardIntoMcpServersJson: () => mergeSideboardIntoMcpServersJson,
|
|
17239
17567
|
mergeUsage: () => mergeUsage,
|
|
17568
|
+
messagePartParentId: () => messagePartParentId,
|
|
17240
17569
|
nextPastedTextName: () => nextPastedTextName,
|
|
17241
17570
|
nextThinkingEffort: () => nextThinkingEffort,
|
|
17242
17571
|
nonInteractiveGitProcessEnv: () => nonInteractiveGitProcessEnv,
|
|
@@ -17355,6 +17684,7 @@ __export(index_exports, {
|
|
|
17355
17684
|
shouldCompactContext: () => shouldCompactContext,
|
|
17356
17685
|
shouldInjectBrightsyMcp: () => shouldInjectBrightsyMcp,
|
|
17357
17686
|
shouldRefreshReviewRequestTemplate: () => shouldRefreshReviewRequestTemplate,
|
|
17687
|
+
shouldRemoveWorktreeOnTeardown: () => shouldRemoveWorktreeOnTeardown,
|
|
17358
17688
|
shouldResetSessionForOccupancy: () => shouldResetSessionForOccupancy,
|
|
17359
17689
|
shouldRunWorktreeCleanup: () => shouldRunWorktreeCleanup,
|
|
17360
17690
|
sideboardHomeDir: () => sideboardHomeDir,
|
|
@@ -17425,6 +17755,8 @@ __export(index_exports, {
|
|
|
17425
17755
|
waitForPidExit: () => waitForPidExit,
|
|
17426
17756
|
warmGithubAgentAuth: () => warmGithubAgentAuth,
|
|
17427
17757
|
withAgentInstructions: () => withAgentInstructions,
|
|
17758
|
+
withEventParentId: () => withEventParentId,
|
|
17759
|
+
withEventsParentId: () => withEventsParentId,
|
|
17428
17760
|
withExportedPath: () => withExportedPath,
|
|
17429
17761
|
withThreadLock: () => withThreadLock,
|
|
17430
17762
|
workspaceSettingsSourceLabel: () => workspaceSettingsSourceLabel,
|
|
@@ -18278,6 +18610,7 @@ init_context_compact();
|
|
|
18278
18610
|
init_summarize();
|
|
18279
18611
|
init_land();
|
|
18280
18612
|
init_create();
|
|
18613
|
+
init_cowboy();
|
|
18281
18614
|
init_chat_tabs();
|
|
18282
18615
|
init_fork_worktree();
|
|
18283
18616
|
init_stack_layers();
|
|
@@ -18287,7 +18620,7 @@ init_request_review();
|
|
|
18287
18620
|
init_workspace_scratch();
|
|
18288
18621
|
|
|
18289
18622
|
// src/plan/ask-user.ts
|
|
18290
|
-
function
|
|
18623
|
+
function asRecord6(v) {
|
|
18291
18624
|
return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
18292
18625
|
}
|
|
18293
18626
|
function parseOptions(raw) {
|
|
@@ -18298,7 +18631,7 @@ function parseOptions(raw) {
|
|
|
18298
18631
|
out.push({ label: item.trim() });
|
|
18299
18632
|
continue;
|
|
18300
18633
|
}
|
|
18301
|
-
const o =
|
|
18634
|
+
const o = asRecord6(item);
|
|
18302
18635
|
if (!o) continue;
|
|
18303
18636
|
const label = typeof o.label === "string" ? o.label.trim() : typeof o.text === "string" ? o.text.trim() : typeof o.title === "string" ? o.title.trim() : "";
|
|
18304
18637
|
if (!label) continue;
|
|
@@ -18308,7 +18641,7 @@ function parseOptions(raw) {
|
|
|
18308
18641
|
return out;
|
|
18309
18642
|
}
|
|
18310
18643
|
function parseOneQuestion(raw) {
|
|
18311
|
-
const o =
|
|
18644
|
+
const o = asRecord6(raw);
|
|
18312
18645
|
if (!o) return null;
|
|
18313
18646
|
const question = typeof o.question === "string" ? o.question.trim() : typeof o.text === "string" ? o.text.trim() : typeof o.prompt === "string" ? o.prompt.trim() : "";
|
|
18314
18647
|
if (!question) return null;
|
|
@@ -18319,7 +18652,7 @@ function parseOneQuestion(raw) {
|
|
|
18319
18652
|
return { question, header, multiSelect, options };
|
|
18320
18653
|
}
|
|
18321
18654
|
function parsePlanQuestionsInput(input) {
|
|
18322
|
-
const root =
|
|
18655
|
+
const root = asRecord6(input);
|
|
18323
18656
|
if (!root) return [];
|
|
18324
18657
|
const list = Array.isArray(root.questions) ? root.questions : Array.isArray(root.question) ? root.question : root.question || root.prompt ? [root] : [];
|
|
18325
18658
|
const out = [];
|
|
@@ -19488,7 +19821,7 @@ async function startMcpServer() {
|
|
|
19488
19821
|
);
|
|
19489
19822
|
server.tool(
|
|
19490
19823
|
"create_thread",
|
|
19491
|
-
`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.`,
|
|
19824
|
+
`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.`,
|
|
19492
19825
|
{
|
|
19493
19826
|
sourceType: import_zod4.z.enum(["branch", "pr", "ticket"]),
|
|
19494
19827
|
sourceRef: import_zod4.z.string(),
|
|
@@ -19498,6 +19831,9 @@ async function startMcpServer() {
|
|
|
19498
19831
|
),
|
|
19499
19832
|
repoPath: import_zod4.z.string(),
|
|
19500
19833
|
title: import_zod4.z.string().optional(),
|
|
19834
|
+
cowboy: import_zod4.z.boolean().optional().describe(
|
|
19835
|
+
"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."
|
|
19836
|
+
),
|
|
19501
19837
|
parentThreadId: import_zod4.z.string().optional().describe(
|
|
19502
19838
|
"Orchestration: omit (preferred) or pass YOUR chat id from the turn reminder / AGENTS.md. Do not invent uuids."
|
|
19503
19839
|
)
|
|
@@ -19558,7 +19894,8 @@ async function startMcpServer() {
|
|
|
19558
19894
|
fast: opts.fast,
|
|
19559
19895
|
repoPath: args.repoPath,
|
|
19560
19896
|
title: args.title,
|
|
19561
|
-
parentThreadId: parentId || null
|
|
19897
|
+
parentThreadId: parentId || null,
|
|
19898
|
+
cowboy: args.cowboy || void 0
|
|
19562
19899
|
}),
|
|
19563
19900
|
CREATE_THREAD_TIMEOUT_MS,
|
|
19564
19901
|
"create_thread"
|
|
@@ -19576,6 +19913,7 @@ async function startMcpServer() {
|
|
|
19576
19913
|
agent: thread.agent,
|
|
19577
19914
|
model: thread.model,
|
|
19578
19915
|
status: thread.status,
|
|
19916
|
+
cowboy: Boolean(thread.cowboy),
|
|
19579
19917
|
link: `sideboard://thread/${thread.id}`,
|
|
19580
19918
|
parentThreadId: thread.parentThreadId,
|
|
19581
19919
|
...agentCoercedFrom ? {
|
|
@@ -22741,6 +23079,7 @@ init_outbound_watch();
|
|
|
22741
23079
|
coordinatorTurnReminder,
|
|
22742
23080
|
copyConfiguredFiles,
|
|
22743
23081
|
countCacheControlBlocks,
|
|
23082
|
+
cowboyModeEnabled,
|
|
22744
23083
|
createChatTab,
|
|
22745
23084
|
createEmptyThread,
|
|
22746
23085
|
createExistingBranchWorktree,
|
|
@@ -22891,6 +23230,7 @@ init_outbound_watch();
|
|
|
22891
23230
|
isBrightsyNdjsonLine,
|
|
22892
23231
|
isCloudCoordinatorThread,
|
|
22893
23232
|
isConductorBundledCli,
|
|
23233
|
+
isCowboyThread,
|
|
22894
23234
|
isCursorAutoModel,
|
|
22895
23235
|
isDefaultishSourceRef,
|
|
22896
23236
|
isDesktopHostAlive,
|
|
@@ -22909,11 +23249,13 @@ init_outbound_watch();
|
|
|
22909
23249
|
isPlaceholderBranch,
|
|
22910
23250
|
isPrNotMergeableError,
|
|
22911
23251
|
isPresentPlanToolName,
|
|
23252
|
+
isPrimaryCheckoutThread,
|
|
22912
23253
|
isSessionQuotaLimit,
|
|
22913
23254
|
isSideboardScratchPath,
|
|
22914
23255
|
isSlackCoordinatorThread,
|
|
22915
23256
|
isSlackExternalReplyPrompt,
|
|
22916
23257
|
isSlackOAuthCancelled,
|
|
23258
|
+
isSubagentToolName,
|
|
22917
23259
|
isThinkingEffort,
|
|
22918
23260
|
isThisProcessDesktopHost,
|
|
22919
23261
|
isThreadCaffeinated,
|
|
@@ -22968,6 +23310,7 @@ init_outbound_watch();
|
|
|
22968
23310
|
mergePrStack,
|
|
22969
23311
|
mergeSideboardIntoMcpServersJson,
|
|
22970
23312
|
mergeUsage,
|
|
23313
|
+
messagePartParentId,
|
|
22971
23314
|
nextPastedTextName,
|
|
22972
23315
|
nextThinkingEffort,
|
|
22973
23316
|
nonInteractiveGitProcessEnv,
|
|
@@ -23086,6 +23429,7 @@ init_outbound_watch();
|
|
|
23086
23429
|
shouldCompactContext,
|
|
23087
23430
|
shouldInjectBrightsyMcp,
|
|
23088
23431
|
shouldRefreshReviewRequestTemplate,
|
|
23432
|
+
shouldRemoveWorktreeOnTeardown,
|
|
23089
23433
|
shouldResetSessionForOccupancy,
|
|
23090
23434
|
shouldRunWorktreeCleanup,
|
|
23091
23435
|
sideboardHomeDir,
|
|
@@ -23156,6 +23500,8 @@ init_outbound_watch();
|
|
|
23156
23500
|
waitForPidExit,
|
|
23157
23501
|
warmGithubAgentAuth,
|
|
23158
23502
|
withAgentInstructions,
|
|
23503
|
+
withEventParentId,
|
|
23504
|
+
withEventsParentId,
|
|
23159
23505
|
withExportedPath,
|
|
23160
23506
|
withThreadLock,
|
|
23161
23507
|
workspaceSettingsSourceLabel,
|