@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/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,
|
|
@@ -2559,6 +2561,7 @@ __export(app_settings_exports, {
|
|
|
2559
2561
|
childEnvWithAppSettings: () => childEnvWithAppSettings,
|
|
2560
2562
|
claudeChromeEnabled: () => claudeChromeEnabled,
|
|
2561
2563
|
claudeUserSettingsPath: () => claudeUserSettingsPath,
|
|
2564
|
+
cowboyModeEnabled: () => cowboyModeEnabled,
|
|
2562
2565
|
deleteBranchOnPurgeEnabled: () => deleteBranchOnPurgeEnabled,
|
|
2563
2566
|
disconnectLinearConnection: () => disconnectLinearConnection,
|
|
2564
2567
|
ensureSlackDeviceIdentity: () => ensureSlackDeviceIdentity,
|
|
@@ -2797,6 +2800,9 @@ function normalizeAdvanced(raw) {
|
|
|
2797
2800
|
if (typeof source.deleteBranchOnPurge === "boolean") {
|
|
2798
2801
|
out.deleteBranchOnPurge = source.deleteBranchOnPurge;
|
|
2799
2802
|
}
|
|
2803
|
+
if (typeof source.cowboyMode === "boolean") {
|
|
2804
|
+
out.cowboyMode = source.cowboyMode;
|
|
2805
|
+
}
|
|
2800
2806
|
if (typeof source.autoArchiveOnMerge === "boolean") {
|
|
2801
2807
|
out.autoArchiveOnMerge = source.autoArchiveOnMerge;
|
|
2802
2808
|
}
|
|
@@ -3321,6 +3327,9 @@ function updateAdvancedSettings(patch) {
|
|
|
3321
3327
|
if (typeof patch.deleteBranchOnPurge === "boolean") {
|
|
3322
3328
|
advanced.deleteBranchOnPurge = patch.deleteBranchOnPurge;
|
|
3323
3329
|
}
|
|
3330
|
+
if (typeof patch.cowboyMode === "boolean") {
|
|
3331
|
+
advanced.cowboyMode = patch.cowboyMode;
|
|
3332
|
+
}
|
|
3324
3333
|
if (typeof patch.autoArchiveOnMerge === "boolean") {
|
|
3325
3334
|
advanced.autoArchiveOnMerge = patch.autoArchiveOnMerge;
|
|
3326
3335
|
}
|
|
@@ -3371,6 +3380,9 @@ function caffeinateWhileCloudConnectEnabled(settings = loadAppSettings()) {
|
|
|
3371
3380
|
function deleteBranchOnPurgeEnabled(settings = loadAppSettings()) {
|
|
3372
3381
|
return Boolean(settings.advanced.deleteBranchOnPurge);
|
|
3373
3382
|
}
|
|
3383
|
+
function cowboyModeEnabled(settings = loadAppSettings()) {
|
|
3384
|
+
return Boolean(settings.advanced.cowboyMode);
|
|
3385
|
+
}
|
|
3374
3386
|
function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
|
|
3375
3387
|
return Boolean(settings.advanced.autoArchiveOnMerge);
|
|
3376
3388
|
}
|
|
@@ -6675,6 +6687,296 @@ var init_claude_mcp = __esm({
|
|
|
6675
6687
|
}
|
|
6676
6688
|
});
|
|
6677
6689
|
|
|
6690
|
+
// src/agents/message-parts.ts
|
|
6691
|
+
function asRecord(input) {
|
|
6692
|
+
if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
6693
|
+
return input;
|
|
6694
|
+
}
|
|
6695
|
+
return void 0;
|
|
6696
|
+
}
|
|
6697
|
+
function str2(v) {
|
|
6698
|
+
return typeof v === "string" && v.trim() ? v : void 0;
|
|
6699
|
+
}
|
|
6700
|
+
function toolDetail(name, input) {
|
|
6701
|
+
if (!input) return void 0;
|
|
6702
|
+
const command = str2(input.command) ?? str2(input.cmd);
|
|
6703
|
+
if (command) return command;
|
|
6704
|
+
const path = str2(input.file_path) ?? str2(input.path) ?? str2(input.filePath) ?? str2(input.filename);
|
|
6705
|
+
if (path) return path;
|
|
6706
|
+
const pattern = str2(input.pattern) ?? str2(input.glob) ?? str2(input.glob_pattern);
|
|
6707
|
+
if (pattern) return pattern;
|
|
6708
|
+
const query = str2(input.query) ?? str2(input.prompt);
|
|
6709
|
+
if (query) return query.length > 80 ? `${query.slice(0, 77)}\u2026` : query;
|
|
6710
|
+
try {
|
|
6711
|
+
const raw = JSON.stringify(input);
|
|
6712
|
+
return raw.length > 80 ? `${raw.slice(0, 77)}\u2026` : raw;
|
|
6713
|
+
} catch {
|
|
6714
|
+
return name;
|
|
6715
|
+
}
|
|
6716
|
+
}
|
|
6717
|
+
function toolDescription(name, input) {
|
|
6718
|
+
const n = name.replace(/^mcp__/, "").replace(/__/g, " \xB7 ");
|
|
6719
|
+
if (/^get_record_types$|recordTypes/i.test(name)) return "List record types";
|
|
6720
|
+
if (/connectedAgentRequest/i.test(name)) {
|
|
6721
|
+
return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
|
|
6722
|
+
}
|
|
6723
|
+
if (/present_artifact$/i.test(name)) {
|
|
6724
|
+
return str2(input?.title) ? `Present ${str2(input?.title)}` : "Present artifact";
|
|
6725
|
+
}
|
|
6726
|
+
if (/present_plan$/i.test(name)) {
|
|
6727
|
+
return str2(input?.title) ? `Plan ${str2(input?.title)}` : "Present plan";
|
|
6728
|
+
}
|
|
6729
|
+
if (/present_schema$/i.test(name)) {
|
|
6730
|
+
return str2(input?.title) ? `Schema ${str2(input?.title)}` : "Present schema";
|
|
6731
|
+
}
|
|
6732
|
+
if (/present_files$/i.test(name)) {
|
|
6733
|
+
return str2(input?.title) ? `Files ${str2(input?.title)}` : "Present files";
|
|
6734
|
+
}
|
|
6735
|
+
if (isSubagentToolName(name)) {
|
|
6736
|
+
const desc = str2(input?.description);
|
|
6737
|
+
const sub = asRecord(input?.subagentType);
|
|
6738
|
+
const kind = str2(sub?.name) ?? str2(sub?.kind) ?? str2(input?.subagent_type) ?? str2(input?.subagentType);
|
|
6739
|
+
if (/^spawn_agent$/i.test(name)) {
|
|
6740
|
+
return str2(input?.prompt) ?? desc ?? "Subagent";
|
|
6741
|
+
}
|
|
6742
|
+
if (/connectedAgentRequest/i.test(name)) {
|
|
6743
|
+
return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
|
|
6744
|
+
}
|
|
6745
|
+
if (desc && kind) return `${kind}: ${desc}`;
|
|
6746
|
+
if (desc) return desc;
|
|
6747
|
+
return "Subagent";
|
|
6748
|
+
}
|
|
6749
|
+
if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
|
|
6750
|
+
return str2(input?.title) ? `Artifact ${str2(input?.title)}` : "Artifact";
|
|
6751
|
+
}
|
|
6752
|
+
if (!input) return n;
|
|
6753
|
+
if (/bash|shell|terminal/i.test(name) && str2(input.command)) {
|
|
6754
|
+
const cmd = str2(input.command);
|
|
6755
|
+
if (/git\s+fetch/i.test(cmd)) return "Fetch latest from origin and check status";
|
|
6756
|
+
if (/git\s+status/i.test(cmd)) return "Check git status";
|
|
6757
|
+
if (/git\s+log/i.test(cmd)) return "Inspect recent commits";
|
|
6758
|
+
if (/git\s+branch/i.test(cmd)) return "List branches";
|
|
6759
|
+
if (/grep|rg\b/i.test(cmd)) return "Search repository";
|
|
6760
|
+
return "Run shell command";
|
|
6761
|
+
}
|
|
6762
|
+
if (/edit|write|apply/i.test(name)) {
|
|
6763
|
+
const path = str2(input.file_path) ?? str2(input.path);
|
|
6764
|
+
return path ? `Edit ${path.split("/").pop()}` : "Edit file";
|
|
6765
|
+
}
|
|
6766
|
+
if (/read/i.test(name)) {
|
|
6767
|
+
const path = str2(input.file_path) ?? str2(input.path);
|
|
6768
|
+
return path ? `Read ${path.split("/").pop()}` : "Read file";
|
|
6769
|
+
}
|
|
6770
|
+
if (/grep/i.test(name)) return "Search files";
|
|
6771
|
+
if (/glob/i.test(name)) return "Find files";
|
|
6772
|
+
return n;
|
|
6773
|
+
}
|
|
6774
|
+
function isSubagentToolName(name) {
|
|
6775
|
+
const n = (name ?? "").trim();
|
|
6776
|
+
if (/^(task|agent|spawn_agent)$/i.test(n)) return true;
|
|
6777
|
+
return /connectedAgentRequest/i.test(n);
|
|
6778
|
+
}
|
|
6779
|
+
function messagePartParentId(part) {
|
|
6780
|
+
if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
|
|
6781
|
+
return part.parentId;
|
|
6782
|
+
}
|
|
6783
|
+
return void 0;
|
|
6784
|
+
}
|
|
6785
|
+
function sameParentId(a, b) {
|
|
6786
|
+
return (a ?? "") === (b ?? "");
|
|
6787
|
+
}
|
|
6788
|
+
function withEventParentId(event, parentId) {
|
|
6789
|
+
if (!parentId) return event;
|
|
6790
|
+
if (event.type === "stdout" || event.type === "thinking" || event.type === "tool_use" || event.type === "tool_result") {
|
|
6791
|
+
return { ...event, parentId: event.parentId ?? parentId };
|
|
6792
|
+
}
|
|
6793
|
+
return event;
|
|
6794
|
+
}
|
|
6795
|
+
function toolFilePath(input) {
|
|
6796
|
+
if (!input) return void 0;
|
|
6797
|
+
return str2(input.file_path) ?? str2(input.path) ?? str2(input.filePath) ?? str2(input.filename);
|
|
6798
|
+
}
|
|
6799
|
+
function countLines(text4) {
|
|
6800
|
+
if (!text4) return 0;
|
|
6801
|
+
return text4.split("\n").length;
|
|
6802
|
+
}
|
|
6803
|
+
function diffFromInput(input) {
|
|
6804
|
+
if (!input) return {};
|
|
6805
|
+
const oldS = str2(input.old_string) ?? str2(input.oldString);
|
|
6806
|
+
const newS = str2(input.new_string) ?? str2(input.newString) ?? str2(input.content);
|
|
6807
|
+
if (oldS != null || newS != null) {
|
|
6808
|
+
return {
|
|
6809
|
+
additions: countLines(newS),
|
|
6810
|
+
deletions: countLines(oldS)
|
|
6811
|
+
};
|
|
6812
|
+
}
|
|
6813
|
+
return {};
|
|
6814
|
+
}
|
|
6815
|
+
function parseDiffStat(result) {
|
|
6816
|
+
if (!result) return {};
|
|
6817
|
+
const paired = result.match(/\+(\d+)\s+-(\d+)/);
|
|
6818
|
+
if (paired) {
|
|
6819
|
+
return {
|
|
6820
|
+
additions: Number(paired[1]),
|
|
6821
|
+
deletions: Number(paired[2])
|
|
6822
|
+
};
|
|
6823
|
+
}
|
|
6824
|
+
const verbose = result.match(
|
|
6825
|
+
/(\d+)\s+insertions?(?:,\s*(\d+)\s+deletions?)?/i
|
|
6826
|
+
);
|
|
6827
|
+
if (verbose) {
|
|
6828
|
+
return {
|
|
6829
|
+
additions: Number(verbose[1]),
|
|
6830
|
+
deletions: verbose[2] != null ? Number(verbose[2]) : void 0
|
|
6831
|
+
};
|
|
6832
|
+
}
|
|
6833
|
+
return {};
|
|
6834
|
+
}
|
|
6835
|
+
function applyAgentEvent(parts, event) {
|
|
6836
|
+
if (event.type === "stdout") {
|
|
6837
|
+
const data = event.data;
|
|
6838
|
+
if (!data) return parts;
|
|
6839
|
+
const next = [...parts];
|
|
6840
|
+
const last = next[next.length - 1];
|
|
6841
|
+
if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
|
|
6842
|
+
next[next.length - 1] = {
|
|
6843
|
+
type: "text",
|
|
6844
|
+
text: last.text + data,
|
|
6845
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
6846
|
+
};
|
|
6847
|
+
} else {
|
|
6848
|
+
next.push({
|
|
6849
|
+
type: "text",
|
|
6850
|
+
text: data,
|
|
6851
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
6852
|
+
});
|
|
6853
|
+
}
|
|
6854
|
+
return next;
|
|
6855
|
+
}
|
|
6856
|
+
if (event.type === "thinking") {
|
|
6857
|
+
const data = event.data;
|
|
6858
|
+
if (!data) return parts;
|
|
6859
|
+
const next = [...parts];
|
|
6860
|
+
const last = next[next.length - 1];
|
|
6861
|
+
if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
|
|
6862
|
+
next[next.length - 1] = {
|
|
6863
|
+
type: "thinking",
|
|
6864
|
+
text: last.text + data,
|
|
6865
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
6866
|
+
};
|
|
6867
|
+
} else {
|
|
6868
|
+
next.push({
|
|
6869
|
+
type: "thinking",
|
|
6870
|
+
text: data,
|
|
6871
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
6872
|
+
});
|
|
6873
|
+
}
|
|
6874
|
+
return next;
|
|
6875
|
+
}
|
|
6876
|
+
if (event.type === "tool_use") {
|
|
6877
|
+
const input = asRecord(event.input);
|
|
6878
|
+
const diff = diffFromInput(input);
|
|
6879
|
+
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
6880
|
+
if (existing >= 0) {
|
|
6881
|
+
const prev = parts[existing];
|
|
6882
|
+
const next = [...parts];
|
|
6883
|
+
const mergedInput = input && Object.keys(input).length > 0 ? input : prev.input ?? input;
|
|
6884
|
+
next[existing] = {
|
|
6885
|
+
...prev,
|
|
6886
|
+
name: event.name || prev.name,
|
|
6887
|
+
input: mergedInput,
|
|
6888
|
+
description: toolDescription(event.name || prev.name, mergedInput),
|
|
6889
|
+
detail: toolDetail(event.name || prev.name, mergedInput) ?? prev.detail,
|
|
6890
|
+
filePath: toolFilePath(mergedInput) ?? prev.filePath,
|
|
6891
|
+
additions: diff.additions ?? prev.additions,
|
|
6892
|
+
deletions: diff.deletions ?? prev.deletions,
|
|
6893
|
+
parentId: event.parentId ?? prev.parentId
|
|
6894
|
+
};
|
|
6895
|
+
return next;
|
|
6896
|
+
}
|
|
6897
|
+
return [
|
|
6898
|
+
...parts,
|
|
6899
|
+
{
|
|
6900
|
+
type: "tool",
|
|
6901
|
+
id: event.id,
|
|
6902
|
+
name: event.name,
|
|
6903
|
+
input,
|
|
6904
|
+
description: toolDescription(event.name, input),
|
|
6905
|
+
detail: toolDetail(event.name, input),
|
|
6906
|
+
status: "running",
|
|
6907
|
+
filePath: toolFilePath(input),
|
|
6908
|
+
...event.parentId ? { parentId: event.parentId } : {},
|
|
6909
|
+
...diff
|
|
6910
|
+
}
|
|
6911
|
+
];
|
|
6912
|
+
}
|
|
6913
|
+
if (event.type === "tool_result") {
|
|
6914
|
+
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
6915
|
+
const fromResult = parseDiffStat(event.content);
|
|
6916
|
+
if (existing < 0) {
|
|
6917
|
+
return [
|
|
6918
|
+
...parts,
|
|
6919
|
+
{
|
|
6920
|
+
type: "tool",
|
|
6921
|
+
id: event.id,
|
|
6922
|
+
name: "tool",
|
|
6923
|
+
description: "tool",
|
|
6924
|
+
status: event.isError ? "error" : "done",
|
|
6925
|
+
result: event.content,
|
|
6926
|
+
...event.parentId ? { parentId: event.parentId } : {},
|
|
6927
|
+
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
6928
|
+
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
6929
|
+
}
|
|
6930
|
+
];
|
|
6931
|
+
}
|
|
6932
|
+
return parts.map((p, i) => {
|
|
6933
|
+
if (i !== existing || p.type !== "tool") return p;
|
|
6934
|
+
return {
|
|
6935
|
+
...p,
|
|
6936
|
+
status: event.isError ? "error" : "done",
|
|
6937
|
+
result: event.content,
|
|
6938
|
+
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
6939
|
+
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
6940
|
+
};
|
|
6941
|
+
});
|
|
6942
|
+
}
|
|
6943
|
+
return parts;
|
|
6944
|
+
}
|
|
6945
|
+
function partsToAssistantText(parts) {
|
|
6946
|
+
return parts.filter(
|
|
6947
|
+
(p) => p.type === "text" && !messagePartParentId(p)
|
|
6948
|
+
).map((p) => p.text).join("").trim();
|
|
6949
|
+
}
|
|
6950
|
+
function stripBrightsyNdjsonNoise(text4) {
|
|
6951
|
+
if (!text4 || !text4.includes('"type"')) return text4;
|
|
6952
|
+
let out = text4;
|
|
6953
|
+
out = out.replace(
|
|
6954
|
+
/\{"type":"(?:tool_use|tool_result|tool|thinking|usage|done|error)"[\s\S]*?\}\s*(?=\{"type":"|$|(?=[A-Za-z*#]))/g,
|
|
6955
|
+
""
|
|
6956
|
+
);
|
|
6957
|
+
out = out.replace(/\{"type":"(?:tool_use|tool_result|tool)"[\s\S]*$/g, "");
|
|
6958
|
+
return out.trim();
|
|
6959
|
+
}
|
|
6960
|
+
function isBrightsyNdjsonLine(line) {
|
|
6961
|
+
const t = line.trim();
|
|
6962
|
+
if (!t.startsWith("{")) return false;
|
|
6963
|
+
return /"type"\s*:\s*"(tool_use|tool_result|tool|thinking|usage|done|error|text)"/.test(t);
|
|
6964
|
+
}
|
|
6965
|
+
function finalizeParts(parts) {
|
|
6966
|
+
return parts.map(
|
|
6967
|
+
(p) => p.type === "tool" && p.status === "running" ? { ...p, status: "done" } : p
|
|
6968
|
+
);
|
|
6969
|
+
}
|
|
6970
|
+
function normalizeParseResult(parsed) {
|
|
6971
|
+
if (!parsed) return [];
|
|
6972
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
6973
|
+
}
|
|
6974
|
+
var init_message_parts = __esm({
|
|
6975
|
+
"src/agents/message-parts.ts"() {
|
|
6976
|
+
"use strict";
|
|
6977
|
+
}
|
|
6978
|
+
});
|
|
6979
|
+
|
|
6678
6980
|
// src/mcp/profile.ts
|
|
6679
6981
|
function sideboardMcpProfile(env = process.env) {
|
|
6680
6982
|
return env[SIDEBOARD_MCP_PROFILE_ENV]?.trim().toLowerCase() === "worktree" ? "worktree" : "orchestration";
|
|
@@ -7300,42 +7602,59 @@ function claudeResultErrorDetail(obj) {
|
|
|
7300
7602
|
}
|
|
7301
7603
|
return "Claude turn failed";
|
|
7302
7604
|
}
|
|
7303
|
-
function eventsFromContentBlocks(blocks) {
|
|
7605
|
+
function eventsFromContentBlocks(blocks, parentId) {
|
|
7304
7606
|
if (!blocks?.length) return [];
|
|
7305
7607
|
const out = [];
|
|
7306
7608
|
for (const block of blocks) {
|
|
7307
7609
|
if (!block?.type) continue;
|
|
7308
7610
|
if (block.type === "text" && block.text) {
|
|
7309
|
-
out.push({ type: "stdout", data: block.text });
|
|
7611
|
+
out.push(withEventParentId({ type: "stdout", data: block.text }, parentId));
|
|
7310
7612
|
continue;
|
|
7311
7613
|
}
|
|
7312
7614
|
if ((block.type === "thinking" || block.type === "redacted_thinking") && block.thinking) {
|
|
7313
|
-
out.push({ type: "thinking", data: block.thinking });
|
|
7615
|
+
out.push(withEventParentId({ type: "thinking", data: block.thinking }, parentId));
|
|
7314
7616
|
continue;
|
|
7315
7617
|
}
|
|
7316
7618
|
if (block.type === "tool_use" && block.id && block.name) {
|
|
7317
|
-
out.push(
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7619
|
+
out.push(
|
|
7620
|
+
withEventParentId(
|
|
7621
|
+
{
|
|
7622
|
+
type: "tool_use",
|
|
7623
|
+
id: block.id,
|
|
7624
|
+
name: block.name,
|
|
7625
|
+
input: block.input
|
|
7626
|
+
},
|
|
7627
|
+
parentId
|
|
7628
|
+
)
|
|
7629
|
+
);
|
|
7323
7630
|
continue;
|
|
7324
7631
|
}
|
|
7325
7632
|
if (block.type === "tool_result" && block.tool_use_id) {
|
|
7326
7633
|
const content = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map(
|
|
7327
7634
|
(c) => typeof c === "string" ? c : c && typeof c === "object" && "text" in c ? String(c.text ?? "") : ""
|
|
7328
7635
|
).join("") : block.content != null ? JSON.stringify(block.content) : void 0;
|
|
7329
|
-
out.push(
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7636
|
+
out.push(
|
|
7637
|
+
withEventParentId(
|
|
7638
|
+
{
|
|
7639
|
+
type: "tool_result",
|
|
7640
|
+
id: block.tool_use_id,
|
|
7641
|
+
content,
|
|
7642
|
+
isError: Boolean(block.is_error)
|
|
7643
|
+
},
|
|
7644
|
+
parentId
|
|
7645
|
+
)
|
|
7646
|
+
);
|
|
7335
7647
|
}
|
|
7336
7648
|
}
|
|
7337
7649
|
return out;
|
|
7338
7650
|
}
|
|
7651
|
+
function claudeParentToolUseId(obj) {
|
|
7652
|
+
const nested = obj.event && typeof obj.event === "object" && !Array.isArray(obj.event) ? obj.event : void 0;
|
|
7653
|
+
for (const id of [obj.parent_tool_use_id, nested?.parent_tool_use_id]) {
|
|
7654
|
+
if (typeof id === "string" && id.trim()) return id.trim();
|
|
7655
|
+
}
|
|
7656
|
+
return void 0;
|
|
7657
|
+
}
|
|
7339
7658
|
function parseIssuesJson(raw) {
|
|
7340
7659
|
const text4 = raw.trim();
|
|
7341
7660
|
const candidates = [text4];
|
|
@@ -7370,6 +7689,7 @@ var init_claude = __esm({
|
|
|
7370
7689
|
init_app_settings();
|
|
7371
7690
|
init_claude_mcp();
|
|
7372
7691
|
init_error_detail();
|
|
7692
|
+
init_message_parts();
|
|
7373
7693
|
init_injected_mcp();
|
|
7374
7694
|
init_turn_input();
|
|
7375
7695
|
init_types();
|
|
@@ -7381,7 +7701,10 @@ var init_claude = __esm({
|
|
|
7381
7701
|
"Glob",
|
|
7382
7702
|
"Grep",
|
|
7383
7703
|
"WebFetch",
|
|
7384
|
-
"WebSearch"
|
|
7704
|
+
"WebSearch",
|
|
7705
|
+
// Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
|
|
7706
|
+
"Task",
|
|
7707
|
+
"Agent"
|
|
7385
7708
|
];
|
|
7386
7709
|
CLAUDE_CHROME_ALLOWED_TOOLS = [
|
|
7387
7710
|
"mcp__claude-in-chrome",
|
|
@@ -7509,7 +7832,9 @@ var init_claude = __esm({
|
|
|
7509
7832
|
args,
|
|
7510
7833
|
cwd: thread.worktreePath,
|
|
7511
7834
|
stdin: useStdin ? `${promptText}
|
|
7512
|
-
` : void 0
|
|
7835
|
+
` : void 0,
|
|
7836
|
+
// Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
|
|
7837
|
+
env: { CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1" }
|
|
7513
7838
|
};
|
|
7514
7839
|
},
|
|
7515
7840
|
parseEvent(line) {
|
|
@@ -7526,8 +7851,9 @@ var init_claude = __esm({
|
|
|
7526
7851
|
return { type: "session_id", data: obj.session_id };
|
|
7527
7852
|
}
|
|
7528
7853
|
if (obj.type === "assistant" || obj.type === "user") {
|
|
7854
|
+
const parentId = claudeParentToolUseId(obj);
|
|
7529
7855
|
const message = obj.message;
|
|
7530
|
-
const events = eventsFromContentBlocks(message?.content);
|
|
7856
|
+
const events = eventsFromContentBlocks(message?.content, parentId);
|
|
7531
7857
|
if (obj.type === "assistant") {
|
|
7532
7858
|
const usage = usageFromClaude(message?.usage);
|
|
7533
7859
|
if (usage) events.push({ type: "usage", data: usage, scope: "request" });
|
|
@@ -7536,34 +7862,45 @@ var init_claude = __esm({
|
|
|
7536
7862
|
return events.length === 1 ? events[0] : events;
|
|
7537
7863
|
}
|
|
7538
7864
|
if (obj.type === "stream_event") {
|
|
7865
|
+
const parentId = claudeParentToolUseId(obj);
|
|
7539
7866
|
const event = obj.event;
|
|
7540
7867
|
if (!event) return null;
|
|
7541
7868
|
if (event.type === "content_block_start" && event.content_block) {
|
|
7542
7869
|
const block = event.content_block;
|
|
7543
7870
|
if (block.type === "tool_use" && block.id && block.name) {
|
|
7544
|
-
return
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7871
|
+
return withEventParentId(
|
|
7872
|
+
{
|
|
7873
|
+
type: "tool_use",
|
|
7874
|
+
id: block.id,
|
|
7875
|
+
name: block.name,
|
|
7876
|
+
input: block.input
|
|
7877
|
+
},
|
|
7878
|
+
parentId
|
|
7879
|
+
);
|
|
7550
7880
|
}
|
|
7551
7881
|
if (block.type === "thinking" && block.thinking) {
|
|
7552
|
-
return { type: "thinking", data: block.thinking };
|
|
7882
|
+
return withEventParentId({ type: "thinking", data: block.thinking }, parentId);
|
|
7553
7883
|
}
|
|
7554
7884
|
return null;
|
|
7555
7885
|
}
|
|
7556
7886
|
if (event.type === "content_block_delta" && event.delta) {
|
|
7557
|
-
if (event.delta.text)
|
|
7558
|
-
|
|
7559
|
-
|
|
7887
|
+
if (event.delta.text) {
|
|
7888
|
+
return withEventParentId({ type: "stdout", data: event.delta.text }, parentId);
|
|
7889
|
+
}
|
|
7890
|
+
if (event.delta.thinking) {
|
|
7891
|
+
return withEventParentId({ type: "thinking", data: event.delta.thinking }, parentId);
|
|
7892
|
+
}
|
|
7893
|
+
return null;
|
|
7560
7894
|
}
|
|
7561
7895
|
return null;
|
|
7562
7896
|
}
|
|
7563
7897
|
if (obj.type === "content_block_delta") {
|
|
7898
|
+
const parentId = claudeParentToolUseId(obj);
|
|
7564
7899
|
const delta = obj.delta;
|
|
7565
|
-
if (delta?.text) return { type: "stdout", data: delta.text };
|
|
7566
|
-
if (delta?.thinking)
|
|
7900
|
+
if (delta?.text) return withEventParentId({ type: "stdout", data: delta.text }, parentId);
|
|
7901
|
+
if (delta?.thinking) {
|
|
7902
|
+
return withEventParentId({ type: "thinking", data: delta.thinking }, parentId);
|
|
7903
|
+
}
|
|
7567
7904
|
return null;
|
|
7568
7905
|
}
|
|
7569
7906
|
if (obj.type === "result") {
|
|
@@ -7696,7 +8033,7 @@ function unwrapCodexMcpResult(result) {
|
|
|
7696
8033
|
return String(result);
|
|
7697
8034
|
}
|
|
7698
8035
|
}
|
|
7699
|
-
function
|
|
8036
|
+
function asRecord2(value) {
|
|
7700
8037
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
7701
8038
|
return value;
|
|
7702
8039
|
}
|
|
@@ -7861,7 +8198,7 @@ var init_codex = __esm({
|
|
|
7861
8198
|
}
|
|
7862
8199
|
if (itemType === "mcp_tool_call" && item.id && item.server && item.tool) {
|
|
7863
8200
|
const name = `mcp__${item.server}__${item.tool}`;
|
|
7864
|
-
const input =
|
|
8201
|
+
const input = asRecord2(item.arguments);
|
|
7865
8202
|
const events = [
|
|
7866
8203
|
{ type: "tool_use", id: item.id, name, input }
|
|
7867
8204
|
];
|
|
@@ -7892,6 +8229,36 @@ var init_codex = __esm({
|
|
|
7892
8229
|
}
|
|
7893
8230
|
return events.length === 1 ? events[0] : events;
|
|
7894
8231
|
}
|
|
8232
|
+
if (itemType === "collab_tool_call" && item.id) {
|
|
8233
|
+
const rawTool = typeof item.tool === "string" ? item.tool : "spawn_agent";
|
|
8234
|
+
const name = /spawn/i.test(rawTool) ? "spawn_agent" : rawTool;
|
|
8235
|
+
const input = {};
|
|
8236
|
+
if (item.prompt) input.prompt = item.prompt;
|
|
8237
|
+
if (Array.isArray(item.receiver_thread_ids)) {
|
|
8238
|
+
input.receiver_thread_ids = item.receiver_thread_ids;
|
|
8239
|
+
}
|
|
8240
|
+
const events = [{ type: "tool_use", id: item.id, name, input }];
|
|
8241
|
+
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
8242
|
+
if (finished) {
|
|
8243
|
+
const nested = [];
|
|
8244
|
+
if (item.agents_states && typeof item.agents_states === "object") {
|
|
8245
|
+
for (const value of Object.values(item.agents_states)) {
|
|
8246
|
+
const msg = value && typeof value === "object" && typeof value.message === "string" ? value.message.trim() : "";
|
|
8247
|
+
if (msg) nested.push(msg);
|
|
8248
|
+
}
|
|
8249
|
+
}
|
|
8250
|
+
for (const text4 of nested) {
|
|
8251
|
+
events.push({ type: "stdout", data: text4, parentId: item.id });
|
|
8252
|
+
}
|
|
8253
|
+
events.push({
|
|
8254
|
+
type: "tool_result",
|
|
8255
|
+
id: item.id,
|
|
8256
|
+
content: nested.join("\n") || void 0,
|
|
8257
|
+
isError: item.status === "failed"
|
|
8258
|
+
});
|
|
8259
|
+
}
|
|
8260
|
+
return events.length === 1 ? events[0] : events;
|
|
8261
|
+
}
|
|
7895
8262
|
if (item.status === "failed") {
|
|
7896
8263
|
const detail = item.message?.trim() || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
|
|
7897
8264
|
return { type: "stderr", data: detail };
|
|
@@ -7980,20 +8347,20 @@ function usageFromCursor(usage) {
|
|
|
7980
8347
|
cacheWriteTokens: usage.cacheWriteTokens ? Number(usage.cacheWriteTokens) : void 0
|
|
7981
8348
|
};
|
|
7982
8349
|
}
|
|
7983
|
-
function
|
|
8350
|
+
function asRecord3(value) {
|
|
7984
8351
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
7985
8352
|
return value;
|
|
7986
8353
|
}
|
|
7987
8354
|
return void 0;
|
|
7988
8355
|
}
|
|
7989
8356
|
function normalizeCursorToolCall(name, args) {
|
|
7990
|
-
const raw =
|
|
8357
|
+
const raw = asRecord3(args);
|
|
7991
8358
|
const toolName = typeof raw?.toolName === "string" && raw.toolName.trim() ? raw.toolName.trim() : null;
|
|
7992
|
-
const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" ||
|
|
8359
|
+
const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord3(raw?.args) != null);
|
|
7993
8360
|
if (looksLikeMcp && toolName) {
|
|
7994
8361
|
const providerRaw = typeof raw.providerIdentifier === "string" && raw.providerIdentifier.trim() ? raw.providerIdentifier.trim() : "sideboard";
|
|
7995
8362
|
const provider = providerRaw.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
7996
|
-
const nested =
|
|
8363
|
+
const nested = asRecord3(raw.args);
|
|
7997
8364
|
return {
|
|
7998
8365
|
name: `mcp__${provider}__${toolName}`,
|
|
7999
8366
|
input: nested ?? { toolName }
|
|
@@ -8004,7 +8371,7 @@ function normalizeCursorToolCall(name, args) {
|
|
|
8004
8371
|
function unwrapCursorToolResult(result) {
|
|
8005
8372
|
if (result == null) return void 0;
|
|
8006
8373
|
if (typeof result === "string") return result;
|
|
8007
|
-
const rec =
|
|
8374
|
+
const rec = asRecord3(result);
|
|
8008
8375
|
if (!rec) {
|
|
8009
8376
|
try {
|
|
8010
8377
|
return JSON.stringify(result);
|
|
@@ -8015,18 +8382,18 @@ function unwrapCursorToolResult(result) {
|
|
|
8015
8382
|
const collectTexts = (items) => {
|
|
8016
8383
|
const texts = [];
|
|
8017
8384
|
for (const item of items) {
|
|
8018
|
-
const row =
|
|
8385
|
+
const row = asRecord3(item);
|
|
8019
8386
|
if (!row) continue;
|
|
8020
8387
|
if (typeof row.text === "string") {
|
|
8021
8388
|
texts.push(row.text);
|
|
8022
8389
|
continue;
|
|
8023
8390
|
}
|
|
8024
|
-
const nested =
|
|
8391
|
+
const nested = asRecord3(row.text);
|
|
8025
8392
|
if (typeof nested?.text === "string") texts.push(nested.text);
|
|
8026
8393
|
}
|
|
8027
8394
|
return texts;
|
|
8028
8395
|
};
|
|
8029
|
-
const value =
|
|
8396
|
+
const value = asRecord3(rec.value);
|
|
8030
8397
|
if (value && Array.isArray(value.content)) {
|
|
8031
8398
|
const texts = collectTexts(value.content);
|
|
8032
8399
|
if (texts.length) return texts.join("\n");
|
|
@@ -8043,10 +8410,10 @@ function unwrapCursorToolResult(result) {
|
|
|
8043
8410
|
}
|
|
8044
8411
|
function cursorToolResultIsError(status, result) {
|
|
8045
8412
|
if (status === "error") return true;
|
|
8046
|
-
const rec =
|
|
8413
|
+
const rec = asRecord3(result);
|
|
8047
8414
|
if (!rec) return false;
|
|
8048
8415
|
if (rec.status === "error") return true;
|
|
8049
|
-
const value =
|
|
8416
|
+
const value = asRecord3(rec.value);
|
|
8050
8417
|
return value?.isError === true;
|
|
8051
8418
|
}
|
|
8052
8419
|
function cursorSdkMessageToEvents(msg) {
|
|
@@ -8389,6 +8756,24 @@ var init_cursor = __esm({
|
|
|
8389
8756
|
});
|
|
8390
8757
|
|
|
8391
8758
|
// src/agents/opencode.ts
|
|
8759
|
+
function asRecord4(value) {
|
|
8760
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
8761
|
+
return value;
|
|
8762
|
+
}
|
|
8763
|
+
return void 0;
|
|
8764
|
+
}
|
|
8765
|
+
function str3(v) {
|
|
8766
|
+
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
8767
|
+
}
|
|
8768
|
+
function opencodeToolId(name, callId, metadata) {
|
|
8769
|
+
const sessionId = str3(metadata?.sessionId) ?? str3(metadata?.sessionID);
|
|
8770
|
+
if (name === "task" && sessionId) return sessionId;
|
|
8771
|
+
return callId || `tool-${Date.now()}`;
|
|
8772
|
+
}
|
|
8773
|
+
function withTaskParent(parentId, nested) {
|
|
8774
|
+
const events = Array.isArray(nested) ? nested : [nested];
|
|
8775
|
+
return [{ type: "tool_use", id: parentId, name: "task" }, ...events];
|
|
8776
|
+
}
|
|
8392
8777
|
function displayNameFromOpencodeId(id) {
|
|
8393
8778
|
const slash = id.indexOf("/");
|
|
8394
8779
|
if (slash <= 0) return id;
|
|
@@ -8455,6 +8840,7 @@ var init_opencode = __esm({
|
|
|
8455
8840
|
init_app_settings();
|
|
8456
8841
|
init_global_workspace();
|
|
8457
8842
|
init_error_detail();
|
|
8843
|
+
init_message_parts();
|
|
8458
8844
|
init_injected_mcp();
|
|
8459
8845
|
init_turn_input();
|
|
8460
8846
|
init_types();
|
|
@@ -8571,10 +8957,15 @@ var init_opencode = __esm({
|
|
|
8571
8957
|
}
|
|
8572
8958
|
if (obj.type === "tool_use") {
|
|
8573
8959
|
const part = obj.part;
|
|
8574
|
-
const id = part?.callID ?? part?.id ?? obj.id ?? `tool-${Date.now()}`;
|
|
8575
8960
|
const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
|
|
8576
8961
|
const state = part?.state;
|
|
8577
8962
|
const input = (state?.input && typeof state.input === "object" ? state.input : void 0) ?? part?.input ?? obj.input;
|
|
8963
|
+
const metadata = asRecord4(state?.metadata);
|
|
8964
|
+
const id = opencodeToolId(
|
|
8965
|
+
name,
|
|
8966
|
+
part?.callID ?? part?.id ?? obj.id,
|
|
8967
|
+
metadata
|
|
8968
|
+
);
|
|
8578
8969
|
const events = [{ type: "tool_use", id, name, input }];
|
|
8579
8970
|
const output = state?.output;
|
|
8580
8971
|
if (output != null || state?.status === "completed" || state?.status === "error") {
|
|
@@ -8588,6 +8979,53 @@ var init_opencode = __esm({
|
|
|
8588
8979
|
}
|
|
8589
8980
|
return events.length === 1 ? events[0] : events;
|
|
8590
8981
|
}
|
|
8982
|
+
if (obj.type === "subtask_delta") {
|
|
8983
|
+
const parentId = str3(obj.childSessionID) ?? str3(obj.childSessionId);
|
|
8984
|
+
const delta = str3(obj.delta);
|
|
8985
|
+
if (parentId && delta) {
|
|
8986
|
+
return withTaskParent(
|
|
8987
|
+
parentId,
|
|
8988
|
+
withEventParentId({ type: "thinking", data: delta }, parentId)
|
|
8989
|
+
);
|
|
8990
|
+
}
|
|
8991
|
+
return null;
|
|
8992
|
+
}
|
|
8993
|
+
if (obj.type === "subtask_event") {
|
|
8994
|
+
const parentId = str3(obj.childSessionID) ?? str3(obj.childSessionId);
|
|
8995
|
+
const part = asRecord4(obj.part);
|
|
8996
|
+
if (!parentId || !part) return null;
|
|
8997
|
+
if (part.type === "text" && str3(part.text)) {
|
|
8998
|
+
return withTaskParent(
|
|
8999
|
+
parentId,
|
|
9000
|
+
withEventParentId({ type: "stdout", data: str3(part.text) }, parentId)
|
|
9001
|
+
);
|
|
9002
|
+
}
|
|
9003
|
+
if (part.type === "tool" || str3(part.tool)) {
|
|
9004
|
+
const name = str3(part.tool) ?? str3(part.name) ?? "tool";
|
|
9005
|
+
const id = str3(part.callID) ?? str3(part.id) ?? `${parentId}-${name}`;
|
|
9006
|
+
const state = asRecord4(part.state);
|
|
9007
|
+
const input = asRecord4(state?.input) ?? asRecord4(part.input);
|
|
9008
|
+
const nested = [
|
|
9009
|
+
withEventParentId({ type: "tool_use", id, name, input }, parentId)
|
|
9010
|
+
];
|
|
9011
|
+
const output = state?.output ?? part.output;
|
|
9012
|
+
if (output != null || state?.status === "completed" || state?.status === "error") {
|
|
9013
|
+
nested.push(
|
|
9014
|
+
withEventParentId(
|
|
9015
|
+
{
|
|
9016
|
+
type: "tool_result",
|
|
9017
|
+
id,
|
|
9018
|
+
content: typeof output === "string" ? output : output != null ? JSON.stringify(output) : void 0,
|
|
9019
|
+
isError: state?.status === "error" || state?.status === "failed"
|
|
9020
|
+
},
|
|
9021
|
+
parentId
|
|
9022
|
+
)
|
|
9023
|
+
);
|
|
9024
|
+
}
|
|
9025
|
+
return withTaskParent(parentId, nested);
|
|
9026
|
+
}
|
|
9027
|
+
return null;
|
|
9028
|
+
}
|
|
8591
9029
|
if (obj.type === "tool_result") {
|
|
8592
9030
|
const part = obj.part;
|
|
8593
9031
|
const id = part?.tool_use_id ?? part?.id ?? obj.tool_use_id ?? obj.id;
|
|
@@ -9015,424 +9453,191 @@ async function installAgent(agent) {
|
|
|
9015
9453
|
stderr: result.stderr,
|
|
9016
9454
|
message: result.stderr.trim() || result.stdout.trim() || `npm install failed (exit ${result.exitCode})`
|
|
9017
9455
|
};
|
|
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
|
-
});
|
|
9456
|
+
}
|
|
9403
9457
|
}
|
|
9404
|
-
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
}
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
return out.trim();
|
|
9458
|
+
enrichPathWithNpmGlobalBin();
|
|
9459
|
+
let binPath = null;
|
|
9460
|
+
if (cliBin) {
|
|
9461
|
+
binPath = await whichCli(cliBin);
|
|
9462
|
+
}
|
|
9463
|
+
return {
|
|
9464
|
+
ok: true,
|
|
9465
|
+
command: info.installCommand,
|
|
9466
|
+
exitCode: 0,
|
|
9467
|
+
stdout: result.stdout,
|
|
9468
|
+
stderr: result.stderr,
|
|
9469
|
+
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)`
|
|
9470
|
+
};
|
|
9418
9471
|
}
|
|
9419
|
-
function
|
|
9420
|
-
const
|
|
9421
|
-
|
|
9422
|
-
|
|
9472
|
+
async function loginAgent(agent) {
|
|
9473
|
+
const info = getAgentSetupInfo(agent);
|
|
9474
|
+
const loginCommand = resolveLoginCommand(agent);
|
|
9475
|
+
if (!loginCommand) {
|
|
9476
|
+
return {
|
|
9477
|
+
ok: true,
|
|
9478
|
+
message: info.kind === "bundled-sdk" || info.kind === "api-key" ? info.summary : `No login command for ${agent}`
|
|
9479
|
+
};
|
|
9480
|
+
}
|
|
9481
|
+
const prepared = await prepareTerminalCommand(loginCommand);
|
|
9482
|
+
await openInSystemTerminal(prepared);
|
|
9483
|
+
return {
|
|
9484
|
+
ok: true,
|
|
9485
|
+
openedTerminal: true,
|
|
9486
|
+
command: prepared,
|
|
9487
|
+
message: `Opened Terminal to run: ${prepared}`
|
|
9488
|
+
};
|
|
9423
9489
|
}
|
|
9424
|
-
|
|
9425
|
-
|
|
9426
|
-
|
|
9427
|
-
|
|
9490
|
+
var SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
|
|
9491
|
+
var init_install = __esm({
|
|
9492
|
+
"src/agents/install.ts"() {
|
|
9493
|
+
"use strict";
|
|
9494
|
+
init_run();
|
|
9495
|
+
init_app_settings();
|
|
9496
|
+
init_path();
|
|
9497
|
+
SETUP = {
|
|
9498
|
+
claude: {
|
|
9499
|
+
agent: "claude",
|
|
9500
|
+
kind: "cli",
|
|
9501
|
+
summary: "Install the Claude Code CLI, then complete login in a terminal.",
|
|
9502
|
+
docsUrl: "https://code.claude.com/docs/en/install",
|
|
9503
|
+
installCommand: "npm install -g @anthropic-ai/claude-code",
|
|
9504
|
+
loginCommand: "claude auth login",
|
|
9505
|
+
npmPackage: "@anthropic-ai/claude-code"
|
|
9506
|
+
},
|
|
9507
|
+
codex: {
|
|
9508
|
+
agent: "codex",
|
|
9509
|
+
kind: "cli",
|
|
9510
|
+
summary: "Install the Codex CLI, then run login in a terminal.",
|
|
9511
|
+
docsUrl: "https://github.com/openai/codex",
|
|
9512
|
+
installCommand: "npm install -g @openai/codex",
|
|
9513
|
+
loginCommand: "codex login",
|
|
9514
|
+
npmPackage: "@openai/codex"
|
|
9515
|
+
},
|
|
9516
|
+
opencode: {
|
|
9517
|
+
agent: "opencode",
|
|
9518
|
+
kind: "cli",
|
|
9519
|
+
summary: "Install OpenCode (curl installer or npm), then authenticate providers.",
|
|
9520
|
+
docsUrl: "https://opencode.ai/docs",
|
|
9521
|
+
// Prefer the official installer; npm package name is opencode-ai.
|
|
9522
|
+
installCommand: "curl -fsSL https://opencode.ai/install | bash",
|
|
9523
|
+
loginCommand: "opencode auth login",
|
|
9524
|
+
npmPackage: "opencode-ai@latest"
|
|
9525
|
+
},
|
|
9526
|
+
cursor: {
|
|
9527
|
+
agent: "cursor",
|
|
9528
|
+
kind: "bundled-sdk",
|
|
9529
|
+
summary: "No CLI install \u2014 Sideboard ships the Cursor SDK. Add a CURSOR_API_KEY from the Cursor dashboard.",
|
|
9530
|
+
docsUrl: "https://cursor.com/dashboard/integrations",
|
|
9531
|
+
installCommand: null,
|
|
9532
|
+
loginCommand: null
|
|
9533
|
+
},
|
|
9534
|
+
brightsy: {
|
|
9535
|
+
agent: "brightsy",
|
|
9536
|
+
kind: "cli",
|
|
9537
|
+
summary: "Install the Brightsy CLI, then run `brightsy login`.",
|
|
9538
|
+
docsUrl: "https://www.npmjs.com/package/@brightsy/cli",
|
|
9539
|
+
installCommand: "npm install -g @brightsy/cli",
|
|
9540
|
+
loginCommand: "brightsy login",
|
|
9541
|
+
npmPackage: "@brightsy/cli"
|
|
9542
|
+
}
|
|
9543
|
+
};
|
|
9544
|
+
CLI_BIN = {
|
|
9545
|
+
claude: "claude",
|
|
9546
|
+
codex: "codex",
|
|
9547
|
+
opencode: "opencode",
|
|
9548
|
+
brightsy: "brightsy"
|
|
9549
|
+
};
|
|
9550
|
+
CLI_LOGIN_AGENTS = /* @__PURE__ */ new Set([
|
|
9551
|
+
"claude",
|
|
9552
|
+
"codex",
|
|
9553
|
+
"opencode",
|
|
9554
|
+
"brightsy"
|
|
9555
|
+
]);
|
|
9556
|
+
}
|
|
9557
|
+
});
|
|
9558
|
+
|
|
9559
|
+
// src/agents/index.ts
|
|
9560
|
+
var agents_exports = {};
|
|
9561
|
+
__export(agents_exports, {
|
|
9562
|
+
CLAUDE_MODEL_CATALOG: () => CLAUDE_MODEL_CATALOG,
|
|
9563
|
+
ORCHESTRATOR_AGENT_KINDS: () => ORCHESTRATOR_AGENT_KINDS,
|
|
9564
|
+
PLAN_MODE_INSTRUCTION: () => PLAN_MODE_INSTRUCTION,
|
|
9565
|
+
allAdapters: () => allAdapters,
|
|
9566
|
+
assertOrchestratorCapableAgent: () => assertOrchestratorCapableAgent,
|
|
9567
|
+
brightsyAdapter: () => brightsyAdapter,
|
|
9568
|
+
claudeAdapter: () => claudeAdapter,
|
|
9569
|
+
codexAdapter: () => codexAdapter,
|
|
9570
|
+
coerceOrchestratorAgent: () => coerceOrchestratorAgent,
|
|
9571
|
+
conductorBundledBinDir: () => conductorBundledBinDir,
|
|
9572
|
+
cursorAdapter: () => cursorAdapter,
|
|
9573
|
+
cursorSdkMessageToEvents: () => cursorSdkMessageToEvents,
|
|
9574
|
+
decodeBrightsyTarget: () => decodeBrightsyTarget,
|
|
9575
|
+
encodeBrightsyTarget: () => encodeBrightsyTarget,
|
|
9576
|
+
enrichPathWithNpmGlobalBin: () => enrichPathWithNpmGlobalBin,
|
|
9577
|
+
ensureAgentPath: () => ensureAgentPath,
|
|
9578
|
+
getAdapter: () => getAdapter,
|
|
9579
|
+
getAgentSetupInfo: () => getAgentSetupInfo,
|
|
9580
|
+
installAgent: () => installAgent,
|
|
9581
|
+
isConductorBundledCli: () => isConductorBundledCli,
|
|
9582
|
+
isCursorAutoModel: () => isCursorAutoModel,
|
|
9583
|
+
isOrchestratorCapableAgent: () => isOrchestratorCapableAgent,
|
|
9584
|
+
isSessionQuotaLimit: () => isSessionQuotaLimit,
|
|
9585
|
+
listAgentSetupInfo: () => listAgentSetupInfo,
|
|
9586
|
+
listBrightsyChatTargets: () => listBrightsyChatTargets,
|
|
9587
|
+
listCodexModels: () => listCodexModels,
|
|
9588
|
+
listCursorModels: () => listCursorModels,
|
|
9589
|
+
listModelsForAgent: () => listModelsForAgent,
|
|
9590
|
+
listOpencodeModels: () => listOpencodeModels,
|
|
9591
|
+
loginAgent: () => loginAgent,
|
|
9592
|
+
openInSystemTerminal: () => openInSystemTerminal,
|
|
9593
|
+
opencodeAdapter: () => opencodeAdapter,
|
|
9594
|
+
parseCursorRunnerLine: () => parseCursorRunnerLine,
|
|
9595
|
+
parseSessionQuotaResetAt: () => parseSessionQuotaResetAt,
|
|
9596
|
+
permissionMode: () => permissionMode,
|
|
9597
|
+
posixShellSingleQuote: () => posixShellSingleQuote,
|
|
9598
|
+
prepareTerminalCommand: () => prepareTerminalCommand,
|
|
9599
|
+
resolveCommandBinarySync: () => resolveCommandBinarySync,
|
|
9600
|
+
resolveCursorModelId: () => resolveCursorModelId,
|
|
9601
|
+
resolveLoginCommand: () => resolveLoginCommand,
|
|
9602
|
+
resolveQuotaFallbackAgent: () => resolveQuotaFallbackAgent,
|
|
9603
|
+
withExportedPath: () => withExportedPath
|
|
9604
|
+
});
|
|
9605
|
+
function getAdapter(kind) {
|
|
9606
|
+
return adapters[kind];
|
|
9428
9607
|
}
|
|
9429
|
-
function
|
|
9430
|
-
|
|
9431
|
-
return Array.isArray(parsed) ? parsed : [parsed];
|
|
9608
|
+
function allAdapters() {
|
|
9609
|
+
return Object.values(adapters);
|
|
9432
9610
|
}
|
|
9433
|
-
var
|
|
9434
|
-
|
|
9611
|
+
var adapters;
|
|
9612
|
+
var init_agents = __esm({
|
|
9613
|
+
"src/agents/index.ts"() {
|
|
9435
9614
|
"use strict";
|
|
9615
|
+
init_brightsy();
|
|
9616
|
+
init_claude();
|
|
9617
|
+
init_codex();
|
|
9618
|
+
init_cursor();
|
|
9619
|
+
init_opencode();
|
|
9620
|
+
init_types();
|
|
9621
|
+
init_brightsy();
|
|
9622
|
+
init_brightsy_targets();
|
|
9623
|
+
init_claude();
|
|
9624
|
+
init_codex();
|
|
9625
|
+
init_cursor();
|
|
9626
|
+
init_cursor_events();
|
|
9627
|
+
init_cursor();
|
|
9628
|
+
init_opencode();
|
|
9629
|
+
init_list_models();
|
|
9630
|
+
init_session_quota();
|
|
9631
|
+
init_orchestrator_capable();
|
|
9632
|
+
init_path();
|
|
9633
|
+
init_install();
|
|
9634
|
+
adapters = {
|
|
9635
|
+
claude: claudeAdapter,
|
|
9636
|
+
codex: codexAdapter,
|
|
9637
|
+
opencode: opencodeAdapter,
|
|
9638
|
+
brightsy: brightsyAdapter,
|
|
9639
|
+
cursor: cursorAdapter
|
|
9640
|
+
};
|
|
9436
9641
|
}
|
|
9437
9642
|
});
|
|
9438
9643
|
|
|
@@ -9440,6 +9645,9 @@ var init_message_parts = __esm({
|
|
|
9440
9645
|
function isTextEvent(event) {
|
|
9441
9646
|
return event.type === "stdout" || event.type === "thinking";
|
|
9442
9647
|
}
|
|
9648
|
+
function parentKey(event) {
|
|
9649
|
+
return event.parentId ?? "";
|
|
9650
|
+
}
|
|
9443
9651
|
function createAgentStreamCoalescer(emit, opts) {
|
|
9444
9652
|
const intervalMs = opts?.intervalMs ?? 32;
|
|
9445
9653
|
let pending = null;
|
|
@@ -9452,7 +9660,11 @@ function createAgentStreamCoalescer(emit, opts) {
|
|
|
9452
9660
|
if (!pending) return;
|
|
9453
9661
|
const event = pending;
|
|
9454
9662
|
pending = null;
|
|
9455
|
-
emit({
|
|
9663
|
+
emit({
|
|
9664
|
+
type: event.type,
|
|
9665
|
+
data: event.data,
|
|
9666
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
9667
|
+
});
|
|
9456
9668
|
};
|
|
9457
9669
|
const schedule = () => {
|
|
9458
9670
|
if (timer) return;
|
|
@@ -9467,11 +9679,15 @@ function createAgentStreamCoalescer(emit, opts) {
|
|
|
9467
9679
|
return;
|
|
9468
9680
|
}
|
|
9469
9681
|
if (!event.data) return;
|
|
9470
|
-
if (pending && pending.type === event.type) {
|
|
9682
|
+
if (pending && pending.type === event.type && parentKey(pending) === parentKey(event)) {
|
|
9471
9683
|
pending.data += event.data;
|
|
9472
9684
|
} else {
|
|
9473
9685
|
flush2();
|
|
9474
|
-
pending = {
|
|
9686
|
+
pending = {
|
|
9687
|
+
type: event.type,
|
|
9688
|
+
data: event.data,
|
|
9689
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
9690
|
+
};
|
|
9475
9691
|
}
|
|
9476
9692
|
schedule();
|
|
9477
9693
|
},
|
|
@@ -10101,7 +10317,8 @@ function worktreeBindingFrom(from) {
|
|
|
10101
10317
|
prState: from.prState,
|
|
10102
10318
|
skipAutoArchiveOnMerge: from.skipAutoArchiveOnMerge,
|
|
10103
10319
|
stackId: from.stackId,
|
|
10104
|
-
stackLayer: from.stackLayer
|
|
10320
|
+
stackLayer: from.stackLayer,
|
|
10321
|
+
cowboy: from.cowboy
|
|
10105
10322
|
};
|
|
10106
10323
|
}
|
|
10107
10324
|
function threadsSharingWorktree(worktreePath) {
|
|
@@ -11294,6 +11511,55 @@ async function createThread(input, _onSetupLine) {
|
|
|
11294
11511
|
if (!(0, import_node_fs32.existsSync)(repoPath)) {
|
|
11295
11512
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
11296
11513
|
}
|
|
11514
|
+
if (input.cowboy) {
|
|
11515
|
+
const { cowboyModeEnabled: cowboyModeEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
11516
|
+
if (!cowboyModeEnabled2()) {
|
|
11517
|
+
throw new Error(
|
|
11518
|
+
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
11519
|
+
);
|
|
11520
|
+
}
|
|
11521
|
+
if (input.sourceType === "pr" || input.sourceType === "ticket" || input.sourceType === "adopt") {
|
|
11522
|
+
throw new Error(
|
|
11523
|
+
"Cowboy mode works on the project folder (default branch), not a PR, ticket, or adopt."
|
|
11524
|
+
);
|
|
11525
|
+
}
|
|
11526
|
+
const defaultBranch = await resolveDefaultBranch(repoPath, { network: false });
|
|
11527
|
+
const head = await currentBranch(repoPath);
|
|
11528
|
+
if (head === "HEAD") {
|
|
11529
|
+
throw new Error(
|
|
11530
|
+
"Cowboy mode needs a named branch in the project folder (not a detached HEAD)."
|
|
11531
|
+
);
|
|
11532
|
+
}
|
|
11533
|
+
if (head !== defaultBranch) {
|
|
11534
|
+
throw new Error(
|
|
11535
|
+
`Cowboy mode uses ${defaultBranch} in the project folder. Switch that checkout to ${defaultBranch} first (currently ${head}).`
|
|
11536
|
+
);
|
|
11537
|
+
}
|
|
11538
|
+
const explicitTitle2 = input.title?.trim();
|
|
11539
|
+
const thread2 = createEmptyThread({
|
|
11540
|
+
title: explicitTitle2 || `Cowboy \xB7 ${head}`,
|
|
11541
|
+
userSetTitle: Boolean(explicitTitle2),
|
|
11542
|
+
sourceType: "branch",
|
|
11543
|
+
sourceRef: head,
|
|
11544
|
+
branchName: head,
|
|
11545
|
+
worktreePath: repoPath,
|
|
11546
|
+
repoPath,
|
|
11547
|
+
agent: resolved.agent,
|
|
11548
|
+
autonomy: input.autonomy ?? "default",
|
|
11549
|
+
model: resolved.model,
|
|
11550
|
+
effort: resolved.effort,
|
|
11551
|
+
fast: resolved.fast,
|
|
11552
|
+
planMode: Boolean(input.planMode),
|
|
11553
|
+
attachments: input.attachments ?? [],
|
|
11554
|
+
sourceIsFork: false,
|
|
11555
|
+
parentThreadId: input.parentThreadId ?? null,
|
|
11556
|
+
status: "idle",
|
|
11557
|
+
cowboy: true
|
|
11558
|
+
});
|
|
11559
|
+
writeThread(thread2);
|
|
11560
|
+
await ensureWorkspace(repoPath);
|
|
11561
|
+
return readThread(thread2.id) ?? thread2;
|
|
11562
|
+
}
|
|
11297
11563
|
let sourceRef = input.sourceRef;
|
|
11298
11564
|
let sourceIsFork = false;
|
|
11299
11565
|
let prUrl = null;
|
|
@@ -11379,6 +11645,24 @@ var init_create = __esm({
|
|
|
11379
11645
|
}
|
|
11380
11646
|
});
|
|
11381
11647
|
|
|
11648
|
+
// src/threads/cowboy.ts
|
|
11649
|
+
function isCowboyThread(thread) {
|
|
11650
|
+
return Boolean(thread?.cowboy);
|
|
11651
|
+
}
|
|
11652
|
+
function isPrimaryCheckoutThread(thread) {
|
|
11653
|
+
if (!thread?.worktreePath || !thread.repoPath) return false;
|
|
11654
|
+
return normalizeWorktreePath(thread.worktreePath) === normalizeWorktreePath(thread.repoPath);
|
|
11655
|
+
}
|
|
11656
|
+
function shouldRemoveWorktreeOnTeardown(thread) {
|
|
11657
|
+
return !isCowboyThread(thread) && !isPrimaryCheckoutThread(thread);
|
|
11658
|
+
}
|
|
11659
|
+
var init_cowboy = __esm({
|
|
11660
|
+
"src/threads/cowboy.ts"() {
|
|
11661
|
+
"use strict";
|
|
11662
|
+
init_worktree_labels();
|
|
11663
|
+
}
|
|
11664
|
+
});
|
|
11665
|
+
|
|
11382
11666
|
// src/store/turn-live.ts
|
|
11383
11667
|
function trimParts(parts) {
|
|
11384
11668
|
if (parts.length <= MAX_PARTS) return parts;
|
|
@@ -13021,13 +13305,22 @@ async function previewLand(thread) {
|
|
|
13021
13305
|
isFork: true
|
|
13022
13306
|
};
|
|
13023
13307
|
}
|
|
13024
|
-
|
|
13025
|
-
|
|
13308
|
+
if (isCowboyThread(thread)) {
|
|
13309
|
+
const current2 = await currentBranch(thread.worktreePath);
|
|
13310
|
+
const dirty = await isDirty(thread.worktreePath);
|
|
13311
|
+
const diff2 = await getDiff(thread.worktreePath, thread.repoPath, { base: current2 });
|
|
13312
|
+
return {
|
|
13313
|
+
branch: current2,
|
|
13314
|
+
target: current2,
|
|
13315
|
+
diffStat: diff2.stat,
|
|
13316
|
+
dirty,
|
|
13317
|
+
blocked: false,
|
|
13318
|
+
isFork: false,
|
|
13319
|
+
cowboy: true
|
|
13320
|
+
};
|
|
13026
13321
|
}
|
|
13027
|
-
const
|
|
13028
|
-
|
|
13029
|
-
);
|
|
13030
|
-
const current = head.trim();
|
|
13322
|
+
const target = await resolveDefaultBranch(thread.repoPath);
|
|
13323
|
+
const current = await currentBranch(thread.worktreePath);
|
|
13031
13324
|
if (current === target) {
|
|
13032
13325
|
return {
|
|
13033
13326
|
branch: current,
|
|
@@ -13054,6 +13347,19 @@ async function confirmLand(thread, opts) {
|
|
|
13054
13347
|
if (preview.blocked) {
|
|
13055
13348
|
throw new Error(preview.blockReason ?? "Land blocked");
|
|
13056
13349
|
}
|
|
13350
|
+
if (preview.cowboy) {
|
|
13351
|
+
const meta2 = await suggestPrMetadata(thread.worktreePath, {
|
|
13352
|
+
base: preview.branch,
|
|
13353
|
+
fallbackTitle: thread.title,
|
|
13354
|
+
sourceLabel: `${thread.sourceType}:${thread.sourceRef}`
|
|
13355
|
+
});
|
|
13356
|
+
let committed2 = false;
|
|
13357
|
+
if (preview.dirty) {
|
|
13358
|
+
committed2 = await commitAll(thread.worktreePath, meta2.commitMessage);
|
|
13359
|
+
}
|
|
13360
|
+
await pushBranch(thread.worktreePath, preview.branch);
|
|
13361
|
+
return { prUrl: null, pushed: true, committed: committed2 };
|
|
13362
|
+
}
|
|
13057
13363
|
const meta = await suggestPrMetadata(thread.worktreePath, {
|
|
13058
13364
|
base: preview.target,
|
|
13059
13365
|
fallbackTitle: thread.title,
|
|
@@ -13098,6 +13404,7 @@ var init_land = __esm({
|
|
|
13098
13404
|
init_diff();
|
|
13099
13405
|
init_pr_metadata();
|
|
13100
13406
|
init_gh_errors();
|
|
13407
|
+
init_cowboy();
|
|
13101
13408
|
}
|
|
13102
13409
|
});
|
|
13103
13410
|
|
|
@@ -13683,7 +13990,7 @@ var init_instructions = __esm({
|
|
|
13683
13990
|
});
|
|
13684
13991
|
|
|
13685
13992
|
// src/plan/plan-present.ts
|
|
13686
|
-
function
|
|
13993
|
+
function asRecord5(v) {
|
|
13687
13994
|
return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
13688
13995
|
}
|
|
13689
13996
|
function isPresentPlanToolName(name) {
|
|
@@ -13695,7 +14002,7 @@ function extractPresentedPlan(parts) {
|
|
|
13695
14002
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
13696
14003
|
const p = parts[i];
|
|
13697
14004
|
if (p.type !== "tool" || !isPresentPlanToolName(p.name)) continue;
|
|
13698
|
-
const input =
|
|
14005
|
+
const input = asRecord5(p.input) ?? {};
|
|
13699
14006
|
const content = typeof input.content === "string" ? input.content : typeof input.plan === "string" ? input.plan : typeof input.markdown === "string" ? input.markdown : "";
|
|
13700
14007
|
if (!content.trim()) continue;
|
|
13701
14008
|
const title = typeof input.title === "string" && input.title.trim() ? input.title.trim() : "Plan";
|
|
@@ -14558,6 +14865,7 @@ var init_orchestrator = __esm({
|
|
|
14558
14865
|
init_thread_store();
|
|
14559
14866
|
init_desktop_host();
|
|
14560
14867
|
init_create();
|
|
14868
|
+
init_cowboy();
|
|
14561
14869
|
init_orchestrator_capable();
|
|
14562
14870
|
init_chat_tabs();
|
|
14563
14871
|
init_enqueue_by_key();
|
|
@@ -14834,7 +15142,9 @@ var init_orchestrator = __esm({
|
|
|
14834
15142
|
return thread;
|
|
14835
15143
|
}
|
|
14836
15144
|
async finishCreateThread(threadId, prompt) {
|
|
14837
|
-
const
|
|
15145
|
+
const created = this.getThread(threadId);
|
|
15146
|
+
const skipSetup = isCowboyThread(created);
|
|
15147
|
+
const setup = skipSetup ? Promise.resolve() : this.runSetupAfterCreate(threadId);
|
|
14838
15148
|
if (prompt) {
|
|
14839
15149
|
try {
|
|
14840
15150
|
await this.send(threadId, prompt);
|
|
@@ -14846,6 +15156,7 @@ var init_orchestrator = __esm({
|
|
|
14846
15156
|
}
|
|
14847
15157
|
}
|
|
14848
15158
|
await setup;
|
|
15159
|
+
if (skipSetup) return;
|
|
14849
15160
|
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
14850
15161
|
if (autoRunAfterSetupEnabled2()) {
|
|
14851
15162
|
try {
|
|
@@ -16177,17 +16488,19 @@ var init_orchestrator = __esm({
|
|
|
16177
16488
|
const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
|
|
16178
16489
|
if (siblings.length === 0) {
|
|
16179
16490
|
this.stopDev(thread.id);
|
|
16180
|
-
|
|
16181
|
-
|
|
16182
|
-
|
|
16183
|
-
|
|
16184
|
-
|
|
16185
|
-
|
|
16491
|
+
if (shouldRemoveWorktreeOnTeardown(thread)) {
|
|
16492
|
+
try {
|
|
16493
|
+
await runArchiveScript(thread.repoPath, thread.worktreePath, (line) => {
|
|
16494
|
+
this.emit({
|
|
16495
|
+
type: "turn_output",
|
|
16496
|
+
threadId: thread.id,
|
|
16497
|
+
event: { type: "stdout", data: `[archive] ${line}` }
|
|
16498
|
+
});
|
|
16186
16499
|
});
|
|
16187
|
-
}
|
|
16188
|
-
|
|
16500
|
+
} catch {
|
|
16501
|
+
}
|
|
16502
|
+
await removeWorktree(thread.repoPath, thread.worktreePath);
|
|
16189
16503
|
}
|
|
16190
|
-
await removeWorktree(thread.repoPath, thread.worktreePath);
|
|
16191
16504
|
}
|
|
16192
16505
|
const archived = setStatus(thread.id, "archived");
|
|
16193
16506
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
@@ -16215,15 +16528,17 @@ var init_orchestrator = __esm({
|
|
|
16215
16528
|
const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
|
|
16216
16529
|
if (siblings.length === 0) {
|
|
16217
16530
|
this.stopDev(thread.id);
|
|
16218
|
-
|
|
16219
|
-
|
|
16220
|
-
|
|
16531
|
+
if (shouldRemoveWorktreeOnTeardown(thread)) {
|
|
16532
|
+
try {
|
|
16533
|
+
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
16534
|
+
} catch {
|
|
16535
|
+
}
|
|
16536
|
+
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
16537
|
+
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled2();
|
|
16538
|
+
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
16539
|
+
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
16540
|
+
});
|
|
16221
16541
|
}
|
|
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
16542
|
}
|
|
16228
16543
|
deleteThreadRecord(thread.id);
|
|
16229
16544
|
}
|
|
@@ -16240,6 +16555,11 @@ var init_orchestrator = __esm({
|
|
|
16240
16555
|
return restored2;
|
|
16241
16556
|
}
|
|
16242
16557
|
if (!(0, import_node_fs44.existsSync)(thread.worktreePath)) {
|
|
16558
|
+
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
16559
|
+
throw new Error(
|
|
16560
|
+
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
16561
|
+
);
|
|
16562
|
+
}
|
|
16243
16563
|
const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
|
|
16244
16564
|
const slug = thread.worktreePath.split("/").pop();
|
|
16245
16565
|
const dest = thread.worktreePath;
|
|
@@ -17886,7 +18206,7 @@ async function startMcpServer() {
|
|
|
17886
18206
|
);
|
|
17887
18207
|
server.tool(
|
|
17888
18208
|
"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.`,
|
|
18209
|
+
`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
18210
|
{
|
|
17891
18211
|
sourceType: import_zod4.z.enum(["branch", "pr", "ticket"]),
|
|
17892
18212
|
sourceRef: import_zod4.z.string(),
|
|
@@ -17896,6 +18216,9 @@ async function startMcpServer() {
|
|
|
17896
18216
|
),
|
|
17897
18217
|
repoPath: import_zod4.z.string(),
|
|
17898
18218
|
title: import_zod4.z.string().optional(),
|
|
18219
|
+
cowboy: import_zod4.z.boolean().optional().describe(
|
|
18220
|
+
"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."
|
|
18221
|
+
),
|
|
17899
18222
|
parentThreadId: import_zod4.z.string().optional().describe(
|
|
17900
18223
|
"Orchestration: omit (preferred) or pass YOUR chat id from the turn reminder / AGENTS.md. Do not invent uuids."
|
|
17901
18224
|
)
|
|
@@ -17956,7 +18279,8 @@ async function startMcpServer() {
|
|
|
17956
18279
|
fast: opts.fast,
|
|
17957
18280
|
repoPath: args.repoPath,
|
|
17958
18281
|
title: args.title,
|
|
17959
|
-
parentThreadId: parentId || null
|
|
18282
|
+
parentThreadId: parentId || null,
|
|
18283
|
+
cowboy: args.cowboy || void 0
|
|
17960
18284
|
}),
|
|
17961
18285
|
CREATE_THREAD_TIMEOUT_MS,
|
|
17962
18286
|
"create_thread"
|
|
@@ -17974,6 +18298,7 @@ async function startMcpServer() {
|
|
|
17974
18298
|
agent: thread.agent,
|
|
17975
18299
|
model: thread.model,
|
|
17976
18300
|
status: thread.status,
|
|
18301
|
+
cowboy: Boolean(thread.cowboy),
|
|
17977
18302
|
link: `sideboard://thread/${thread.id}`,
|
|
17978
18303
|
parentThreadId: thread.parentThreadId,
|
|
17979
18304
|
...agentCoercedFrom ? {
|