@sideboard-ai/core 0.1.52 → 0.1.56
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 +126 -11
- package/dist/agents/cursor-runner.js +45 -6
- package/dist/{agents-YKSS6VBO.js → agents-2YYWW723.js} +3 -3
- package/dist/{agents-ON6RKKND.js → agents-AQFEFKBL.js} +2 -2
- package/dist/{app-settings-LZP632KI.js → app-settings-2LQNRTBE.js} +3 -1
- package/dist/{app-settings-7XVDQJ7F.js → app-settings-73DI4B6T.js} +3 -1
- package/dist/{chunk-J5JTEJ5O.js → chunk-3WJAUKIL.js} +89 -7
- package/dist/{chunk-GNML24AW.js → chunk-5DMYULLC.js} +1 -1
- package/dist/{chunk-D3METLRW.js → chunk-7F454EE2.js} +96 -14
- package/dist/{chunk-6QTZVJ7A.js → chunk-C3J4GDW4.js} +188 -24
- package/dist/{chunk-HBJSHRY2.js → chunk-C4BCC5X5.js} +17 -1
- package/dist/{chunk-T5QQVXK3.js → chunk-DIOF73S2.js} +17 -1
- package/dist/{chunk-UEAHMGHW.js → chunk-DQJ5D42H.js} +16 -2
- package/dist/{chunk-YOWIYAVA.js → chunk-EBWEKG52.js} +36 -11
- package/dist/{chunk-XX5BB7NV.js → chunk-S42XDFKF.js} +36 -11
- package/dist/{chunk-LRLKJM3O.js → chunk-UA5NDAHL.js} +16 -2
- package/dist/{chunk-YDXQ72MD.js → chunk-V2DUTUNC.js} +1 -1
- package/dist/{coordinator-prompt-S6JZD5EF.js → coordinator-prompt-ICF36NUQ.js} +2 -1
- package/dist/{coordinator-prompt-6FXVTSFN.js → coordinator-prompt-RBKUNRPR.js} +2 -1
- package/dist/{global-workspace-EV4G2WMQ.js → global-workspace-667XLBW6.js} +3 -2
- package/dist/{global-workspace-MSX2K27Y.js → global-workspace-S7VLWPWG.js} +3 -2
- package/dist/index.cjs +395 -61
- package/dist/index.d.cts +25 -2
- package/dist/index.d.ts +25 -2
- package/dist/index.js +164 -43
- package/dist/mcp/run-stdio.cjs +389 -57
- package/dist/mcp/run-stdio.js +164 -44
- package/dist/{workspaces-AYTBR6KQ.js → workspaces-FPJJXXAE.js} +4 -3
- package/dist/{workspaces-3RQQZQRO.js → workspaces-LYIDE2VR.js} +4 -3
- package/package.json +1 -1
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -92,6 +92,11 @@ function summarizeTurnStderr(tail, maxChars = 500) {
|
|
|
92
92
|
if (joined.length <= maxChars) return joined;
|
|
93
93
|
return joined.slice(joined.length - maxChars);
|
|
94
94
|
}
|
|
95
|
+
function looksLikeInvalidAgentSession(text) {
|
|
96
|
+
const lower = text.trim().toLowerCase();
|
|
97
|
+
if (!lower) return false;
|
|
98
|
+
return /session not found/.test(lower) || /no conversation found/.test(lower) || /conversation .+ not found/.test(lower) || /thread .+ not found/.test(lower) || /unknown session/.test(lower) || /invalid session/.test(lower) || /session .+ (missing|expired|deleted|gone)/.test(lower) || /cannot resume/.test(lower) || /failed to (load|resume|open) session/.test(lower);
|
|
99
|
+
}
|
|
95
100
|
function looksLikeAgentFailureMessage(text) {
|
|
96
101
|
const lower = text.trim().toLowerCase();
|
|
97
102
|
if (!lower) return false;
|
|
@@ -2969,6 +2974,7 @@ __export(app_settings_exports, {
|
|
|
2969
2974
|
orchestrationQuotaOnLimit: () => orchestrationQuotaOnLimit,
|
|
2970
2975
|
resolveClaudeExecutable: () => resolveClaudeExecutable,
|
|
2971
2976
|
resolveEffectiveIssueSource: () => resolveEffectiveIssueSource,
|
|
2977
|
+
resolveNewThreadOptions: () => resolveNewThreadOptions,
|
|
2972
2978
|
resolveThreadDefaults: () => resolveThreadDefaults,
|
|
2973
2979
|
saveAppSettings: () => saveAppSettings,
|
|
2974
2980
|
updateAdvancedSettings: () => updateAdvancedSettings,
|
|
@@ -3261,6 +3267,16 @@ function resolveThreadDefaults(settings = loadAppSettings()) {
|
|
|
3261
3267
|
fast: getDefaultFast(settings)
|
|
3262
3268
|
};
|
|
3263
3269
|
}
|
|
3270
|
+
function resolveNewThreadOptions(overrides = {}, settings = loadAppSettings()) {
|
|
3271
|
+
const defaults = resolveThreadDefaults(settings);
|
|
3272
|
+
const effort = overrides.effort === void 0 || overrides.effort === null ? defaults.effort : normalizeThinkingEffort(overrides.effort) ?? defaults.effort;
|
|
3273
|
+
return {
|
|
3274
|
+
agent: overrides.agent ?? defaults.agent,
|
|
3275
|
+
model: overrides.model === void 0 ? defaults.model : overrides.model?.trim() || null,
|
|
3276
|
+
effort,
|
|
3277
|
+
fast: overrides.fast === void 0 || overrides.fast === null ? defaults.fast : Boolean(overrides.fast)
|
|
3278
|
+
};
|
|
3279
|
+
}
|
|
3264
3280
|
function isLinearConnected(settings = loadAppSettings()) {
|
|
3265
3281
|
return Boolean(settings.integrations.linearApiKey?.trim());
|
|
3266
3282
|
}
|
|
@@ -3280,7 +3296,12 @@ function brightsyCloudConnectEnabled(settings = loadAppSettings()) {
|
|
|
3280
3296
|
return Boolean(settings.brightsy.cloudConnectEnabled);
|
|
3281
3297
|
}
|
|
3282
3298
|
function brightsyCloudConnectAgent(settings = loadAppSettings()) {
|
|
3283
|
-
|
|
3299
|
+
const fallback = settings.brightsy.cloudConnectAgent && CLOUD_CONNECT_AGENTS.has(settings.brightsy.cloudConnectAgent) ? settings.brightsy.cloudConnectAgent : "claude";
|
|
3300
|
+
const preferred = getDefaultAgent(settings);
|
|
3301
|
+
if (CLOUD_CONNECT_AGENTS.has(preferred)) {
|
|
3302
|
+
return preferred;
|
|
3303
|
+
}
|
|
3304
|
+
return fallback;
|
|
3284
3305
|
}
|
|
3285
3306
|
function updateAdvancedSettings(patch) {
|
|
3286
3307
|
const current = loadAppSettings();
|
|
@@ -3528,6 +3549,11 @@ function coordinatorGreenfieldPlaybook(reposDir) {
|
|
|
3528
3549
|
"- Do coding work in the child worktree thread, not by editing files in this home cwd."
|
|
3529
3550
|
].join("\n");
|
|
3530
3551
|
}
|
|
3552
|
+
function accountDefaultsPlaybookLine() {
|
|
3553
|
+
const d = resolveThreadDefaults();
|
|
3554
|
+
const model = d.model?.trim() || "Auto";
|
|
3555
|
+
return `- Account defaults for create_thread (omit agent/model to use these): agent=${d.agent}, model=${model}, effort=${d.effort}`;
|
|
3556
|
+
}
|
|
3531
3557
|
function coordinatorTurnReminder(opts) {
|
|
3532
3558
|
const goal = opts.goal?.trim();
|
|
3533
3559
|
return [
|
|
@@ -3537,6 +3563,7 @@ function coordinatorTurnReminder(opts) {
|
|
|
3537
3563
|
"- Registered workspaces / child threads are the fleet you manage via Sideboard MCP.",
|
|
3538
3564
|
`- Parent thread id (pass as parentThreadId when creating children): ${opts.parentId}`,
|
|
3539
3565
|
goal ? `- Goal / title: ${goal}` : null,
|
|
3566
|
+
accountDefaultsPlaybookLine(),
|
|
3540
3567
|
`- For "what's going on": call list_threads (and list_workspaces if needed). Summarize fleet status \u2014 do not ls/git-status this synthetic home.`,
|
|
3541
3568
|
"- Existing repo: create_thread on a repoPath \u2192 send_to_thread \u2192 wait_for_turn.",
|
|
3542
3569
|
"- New repo: Bash (clone or gh repo create under ~/sideboard/repos/<name>) \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn \u2192 draft PR.",
|
|
@@ -3559,9 +3586,12 @@ function ensureGlobalCoordinatorCwd() {
|
|
|
3559
3586
|
"",
|
|
3560
3587
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
3561
3588
|
"",
|
|
3589
|
+
accountDefaultsPlaybookLine(),
|
|
3590
|
+
"",
|
|
3562
3591
|
coordinatorGreenfieldPlaybook(reposDir),
|
|
3563
3592
|
"",
|
|
3564
3593
|
"When creating threads, pass `repoPath` from `list_workspaces` (or the path you just registered) and `parentThreadId` for children.",
|
|
3594
|
+
"Omit `agent` / `model` on `create_thread` unless you have a reason to override Account defaults.",
|
|
3565
3595
|
"Typical flow (existing): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn.",
|
|
3566
3596
|
"Typical flow (new app): Bash create/clone under repos dir \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn \u2192 draft PR via worktree agent.",
|
|
3567
3597
|
"Always ask worktree agents to open draft PRs (`send_to_thread` + `gh pr create --draft -R <origin>`); never open PRs from the orchestrator."
|
|
@@ -3587,8 +3617,10 @@ function coordinatorSystemPrompt(opts) {
|
|
|
3587
3617
|
"You operate across ALL registered workspaces below.",
|
|
3588
3618
|
"You have no project git home \u2014 this process cwd is synthetic and empty on purpose.",
|
|
3589
3619
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
3620
|
+
accountDefaultsPlaybookLine(),
|
|
3590
3621
|
coordinatorGreenfieldPlaybook(reposDir),
|
|
3591
3622
|
"When creating threads, pass the correct repoPath for the target workspace and parentThreadId for children.",
|
|
3623
|
+
"Omit agent/model on create_thread unless you need to override Account defaults.",
|
|
3592
3624
|
"Typical flow (existing): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn \u2192 send_to_thread (ask for `gh pr create --draft -R <origin-owner/name>` using the workspace github slug) \u2192 wait_for_turn. Never target upstream. Never open PRs from the orchestrator.",
|
|
3593
3625
|
"Typical flow (new app): Bash under repos dir (clone or gh repo create) \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn \u2192 draft PR via worktree agent.",
|
|
3594
3626
|
`Goal: ${opts.goal}`,
|
|
@@ -3604,6 +3636,7 @@ var init_coordinator_prompt = __esm({
|
|
|
3604
3636
|
import_node_fs6 = require("fs");
|
|
3605
3637
|
import_node_path7 = require("path");
|
|
3606
3638
|
init_worktree();
|
|
3639
|
+
init_app_settings();
|
|
3607
3640
|
init_paths();
|
|
3608
3641
|
COORDINATOR_TOOL_PLAYBOOK = [
|
|
3609
3642
|
"Role: you oversee Sideboard worktree agents across registered repos. You do not live inside one of those worktrees.",
|
|
@@ -3612,12 +3645,12 @@ var init_coordinator_prompt = __esm({
|
|
|
3612
3645
|
"- list_workspaces \u2014 registered repos (path + github slug when known)",
|
|
3613
3646
|
"- list_branches / list_prs / list_issues \u2014 pass repoPath from list_workspaces (issues: Linear API or GitHub Issues)",
|
|
3614
3647
|
"- get_pr_stack / open_pr_stack_layers / add_stack_layer / create_pr_stack \u2014 GitHub stacked PRs (`gh stack`); one worktree per layer",
|
|
3615
|
-
"- list_models \u2014 only when you need a specific model (rare); otherwise
|
|
3648
|
+
"- list_models \u2014 only when you need a specific model (rare); otherwise omit model so Account defaults apply",
|
|
3616
3649
|
"- list_threads / get_thread \u2014 fleet status (what is going on)",
|
|
3617
3650
|
"Workspaces:",
|
|
3618
3651
|
"- add_workspace / remove_workspace \u2014 register or unregister a git repo",
|
|
3619
3652
|
"Worktree threads (chats):",
|
|
3620
|
-
"- create_thread \u2014 create a worktree + chat from branch | pr | ticket; pass repoPath + parentThreadId",
|
|
3653
|
+
"- create_thread \u2014 create a worktree + chat from branch | pr | ticket; pass repoPath + parentThreadId; omit agent and model to use Sideboard Account defaults (Settings \u2192 Default agent, model & effort)",
|
|
3621
3654
|
"- fork_worktree \u2014 fork a worktree chat into a NEW git worktree + chat (transcript attached); optional agent; leave model unset (Auto) unless you have a reason. Not for orchestration chats.",
|
|
3622
3655
|
"- fork_chat \u2014 fork a worktree chat (same worktree tab) OR a Global orchestration chat (new orchestration tab); optional agent; leave model unset (Auto) unless you have a reason. Remote coordinators: use this to continue another orchestration chat on a different agent after session limits.",
|
|
3623
3656
|
"- send_to_thread \u2014 queue a prompt (start/continue a chat turn); pass force_stop: true to interrupt mid-turn / clear stale queued prompts before replacing with a new request",
|
|
@@ -3717,7 +3750,13 @@ function createGlobalChat(opts) {
|
|
|
3717
3750
|
const explicit = opts.title?.trim();
|
|
3718
3751
|
const title = explicit && explicit !== CLOUD_ORCHESTRATOR_GOAL ? explicit : allocateTeamName(takenTeamSlugsForOrchestration()).name;
|
|
3719
3752
|
const sourceRef = opts.sourceRef?.trim() || (isCloud ? CLOUD_ORCHESTRATOR_GOAL : title);
|
|
3720
|
-
const
|
|
3753
|
+
const resolved = resolveNewThreadOptions({
|
|
3754
|
+
agent: opts.agent,
|
|
3755
|
+
model: opts.model,
|
|
3756
|
+
effort: opts.effort,
|
|
3757
|
+
fast: opts.fast
|
|
3758
|
+
});
|
|
3759
|
+
const agent = assertOrchestratorCapableAgent(resolved.agent);
|
|
3721
3760
|
const thread = createEmptyThread({
|
|
3722
3761
|
title,
|
|
3723
3762
|
// Stick nicknames the same way chat tabs do (avoid later sync overwrites).
|
|
@@ -3729,9 +3768,9 @@ function createGlobalChat(opts) {
|
|
|
3729
3768
|
repoPath: GLOBAL_WORKSPACE_ID,
|
|
3730
3769
|
agent,
|
|
3731
3770
|
autonomy: opts.autonomy ?? "default",
|
|
3732
|
-
model:
|
|
3733
|
-
effort:
|
|
3734
|
-
fast:
|
|
3771
|
+
model: resolved.model,
|
|
3772
|
+
effort: resolved.effort,
|
|
3773
|
+
fast: resolved.fast,
|
|
3735
3774
|
planMode: Boolean(opts.planMode),
|
|
3736
3775
|
attachments: opts.attachments ?? [],
|
|
3737
3776
|
parentThreadId: opts.parentThreadId ?? null,
|
|
@@ -3764,20 +3803,35 @@ function findCloudCoordinator() {
|
|
|
3764
3803
|
);
|
|
3765
3804
|
}
|
|
3766
3805
|
function ensureCloudCoordinator(agent) {
|
|
3806
|
+
const defaults = resolveThreadDefaults();
|
|
3807
|
+
const desired = assertOrchestratorCapableAgent(agent);
|
|
3767
3808
|
const existing = findCloudCoordinator();
|
|
3768
3809
|
if (existing) {
|
|
3810
|
+
const patch = {};
|
|
3769
3811
|
if (existing.repoPath !== GLOBAL_WORKSPACE_ID) {
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3812
|
+
patch.repoPath = GLOBAL_WORKSPACE_ID;
|
|
3813
|
+
patch.worktreePath = globalAgentCwd();
|
|
3814
|
+
patch.branchName = "global";
|
|
3815
|
+
}
|
|
3816
|
+
const hasAgentTurns = existing.messages.some((m) => m.role === "agent");
|
|
3817
|
+
const canRetarget = !existing.sessionId && !hasAgentTurns && existing.status !== "running" && existing.status !== "queued";
|
|
3818
|
+
if (canRetarget) {
|
|
3819
|
+
if (existing.agent !== desired) patch.agent = desired;
|
|
3820
|
+
if (existing.model !== defaults.model) patch.model = defaults.model;
|
|
3821
|
+
if (existing.effort !== defaults.effort) patch.effort = defaults.effort;
|
|
3822
|
+
if (existing.fast !== defaults.fast) patch.fast = defaults.fast;
|
|
3823
|
+
}
|
|
3824
|
+
if (Object.keys(patch).length > 0) {
|
|
3825
|
+
return updateThread(existing.id, patch);
|
|
3775
3826
|
}
|
|
3776
3827
|
return existing;
|
|
3777
3828
|
}
|
|
3778
3829
|
const created = createGlobalChat({
|
|
3779
3830
|
sourceRef: CLOUD_ORCHESTRATOR_GOAL,
|
|
3780
|
-
agent
|
|
3831
|
+
agent: desired,
|
|
3832
|
+
model: defaults.model,
|
|
3833
|
+
effort: defaults.effort,
|
|
3834
|
+
fast: defaults.fast
|
|
3781
3835
|
});
|
|
3782
3836
|
const all = listThreads({ includeArchived: true }).filter(
|
|
3783
3837
|
(t) => t.status !== "archived" && isCloudCoordinatorThread(t)
|
|
@@ -3792,6 +3846,7 @@ var init_global_workspace = __esm({
|
|
|
3792
3846
|
init_orchestrator_capable();
|
|
3793
3847
|
init_teams();
|
|
3794
3848
|
init_coordinator_prompt();
|
|
3849
|
+
init_app_settings();
|
|
3795
3850
|
init_paths();
|
|
3796
3851
|
init_thread_store();
|
|
3797
3852
|
GLOBAL_WORKSPACE_ID = "__global__";
|
|
@@ -4546,6 +4601,7 @@ function toCodexMcpConfigArgs(servers) {
|
|
|
4546
4601
|
args.push("-c", `${prefix}.env.${key}=${JSON.stringify(value)}`);
|
|
4547
4602
|
}
|
|
4548
4603
|
}
|
|
4604
|
+
args.push("-c", `${prefix}.default_tools_approval_mode=${JSON.stringify("approve")}`);
|
|
4549
4605
|
}
|
|
4550
4606
|
return args;
|
|
4551
4607
|
}
|
|
@@ -5054,6 +5110,32 @@ function codexConfigHasNetworkAccess() {
|
|
|
5054
5110
|
}
|
|
5055
5111
|
return false;
|
|
5056
5112
|
}
|
|
5113
|
+
function unwrapCodexMcpResult(result) {
|
|
5114
|
+
if (result == null) return void 0;
|
|
5115
|
+
if (typeof result === "string") return result;
|
|
5116
|
+
if (typeof result !== "object") return String(result);
|
|
5117
|
+
const rec = result;
|
|
5118
|
+
if (Array.isArray(rec.content)) {
|
|
5119
|
+
const texts = [];
|
|
5120
|
+
for (const item of rec.content) {
|
|
5121
|
+
if (!item || typeof item !== "object") continue;
|
|
5122
|
+
const text = item.text;
|
|
5123
|
+
if (typeof text === "string") texts.push(text);
|
|
5124
|
+
}
|
|
5125
|
+
if (texts.length) return texts.join("\n");
|
|
5126
|
+
}
|
|
5127
|
+
try {
|
|
5128
|
+
return JSON.stringify(result);
|
|
5129
|
+
} catch {
|
|
5130
|
+
return String(result);
|
|
5131
|
+
}
|
|
5132
|
+
}
|
|
5133
|
+
function asRecord(value) {
|
|
5134
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
5135
|
+
return value;
|
|
5136
|
+
}
|
|
5137
|
+
return void 0;
|
|
5138
|
+
}
|
|
5057
5139
|
var import_node_fs11, import_node_os7, import_node_path11, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
5058
5140
|
var init_codex = __esm({
|
|
5059
5141
|
"src/agents/codex.ts"() {
|
|
@@ -5166,15 +5248,49 @@ var init_codex = __esm({
|
|
|
5166
5248
|
}
|
|
5167
5249
|
if (typeof obj.item === "object" && obj.item !== null) {
|
|
5168
5250
|
const item = obj.item;
|
|
5169
|
-
|
|
5251
|
+
const itemType = item.type ?? item.item_type;
|
|
5252
|
+
if (itemType === "error") {
|
|
5170
5253
|
const detail = item.message?.trim() || extractJsonErrorMessage(obj) || "Codex item error";
|
|
5171
5254
|
return { type: "stderr", data: detail };
|
|
5172
5255
|
}
|
|
5173
|
-
if (
|
|
5256
|
+
if (itemType === "agent_message" && item.text) {
|
|
5174
5257
|
return { type: "stdout", data: item.text };
|
|
5175
5258
|
}
|
|
5259
|
+
if (itemType === "mcp_tool_call" && item.id && item.server && item.tool) {
|
|
5260
|
+
const name = `mcp__${item.server}__${item.tool}`;
|
|
5261
|
+
const input = asRecord(item.arguments);
|
|
5262
|
+
const events = [
|
|
5263
|
+
{ type: "tool_use", id: item.id, name, input }
|
|
5264
|
+
];
|
|
5265
|
+
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
5266
|
+
if (finished) {
|
|
5267
|
+
const errMsg = item.error && typeof item.error.message === "string" ? item.error.message : void 0;
|
|
5268
|
+
events.push({
|
|
5269
|
+
type: "tool_result",
|
|
5270
|
+
id: item.id,
|
|
5271
|
+
content: unwrapCodexMcpResult(item.result) ?? errMsg,
|
|
5272
|
+
isError: item.status === "failed" || Boolean(errMsg)
|
|
5273
|
+
});
|
|
5274
|
+
}
|
|
5275
|
+
return events.length === 1 ? events[0] : events;
|
|
5276
|
+
}
|
|
5277
|
+
if (itemType === "command_execution" && item.id) {
|
|
5278
|
+
const input = item.command ? { command: item.command } : void 0;
|
|
5279
|
+
const events = [
|
|
5280
|
+
{ type: "tool_use", id: item.id, name: "Bash", input }
|
|
5281
|
+
];
|
|
5282
|
+
if (type === "item.completed" || item.status === "completed" || item.status === "failed") {
|
|
5283
|
+
events.push({
|
|
5284
|
+
type: "tool_result",
|
|
5285
|
+
id: item.id,
|
|
5286
|
+
content: item.aggregated_output,
|
|
5287
|
+
isError: item.status === "failed"
|
|
5288
|
+
});
|
|
5289
|
+
}
|
|
5290
|
+
return events.length === 1 ? events[0] : events;
|
|
5291
|
+
}
|
|
5176
5292
|
if (item.status === "failed") {
|
|
5177
|
-
const detail = item.message?.trim() || extractJsonErrorMessage(item) || `Codex ${
|
|
5293
|
+
const detail = item.message?.trim() || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
|
|
5178
5294
|
return { type: "stderr", data: detail };
|
|
5179
5295
|
}
|
|
5180
5296
|
}
|
|
@@ -5260,6 +5376,75 @@ function usageFromCursor(usage) {
|
|
|
5260
5376
|
cacheWriteTokens: usage.cacheWriteTokens ? Number(usage.cacheWriteTokens) : void 0
|
|
5261
5377
|
};
|
|
5262
5378
|
}
|
|
5379
|
+
function asRecord2(value) {
|
|
5380
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
5381
|
+
return value;
|
|
5382
|
+
}
|
|
5383
|
+
return void 0;
|
|
5384
|
+
}
|
|
5385
|
+
function normalizeCursorToolCall(name, args) {
|
|
5386
|
+
const raw = asRecord2(args);
|
|
5387
|
+
const toolName = typeof raw?.toolName === "string" && raw.toolName.trim() ? raw.toolName.trim() : null;
|
|
5388
|
+
const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord2(raw?.args) != null);
|
|
5389
|
+
if (looksLikeMcp && toolName) {
|
|
5390
|
+
const providerRaw = typeof raw.providerIdentifier === "string" && raw.providerIdentifier.trim() ? raw.providerIdentifier.trim() : "sideboard";
|
|
5391
|
+
const provider = providerRaw.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
5392
|
+
const nested = asRecord2(raw.args);
|
|
5393
|
+
return {
|
|
5394
|
+
name: `mcp__${provider}__${toolName}`,
|
|
5395
|
+
input: nested ?? { toolName }
|
|
5396
|
+
};
|
|
5397
|
+
}
|
|
5398
|
+
return { name, input: raw };
|
|
5399
|
+
}
|
|
5400
|
+
function unwrapCursorToolResult(result) {
|
|
5401
|
+
if (result == null) return void 0;
|
|
5402
|
+
if (typeof result === "string") return result;
|
|
5403
|
+
const rec = asRecord2(result);
|
|
5404
|
+
if (!rec) {
|
|
5405
|
+
try {
|
|
5406
|
+
return JSON.stringify(result);
|
|
5407
|
+
} catch {
|
|
5408
|
+
return String(result);
|
|
5409
|
+
}
|
|
5410
|
+
}
|
|
5411
|
+
const collectTexts = (items) => {
|
|
5412
|
+
const texts = [];
|
|
5413
|
+
for (const item of items) {
|
|
5414
|
+
const row = asRecord2(item);
|
|
5415
|
+
if (!row) continue;
|
|
5416
|
+
if (typeof row.text === "string") {
|
|
5417
|
+
texts.push(row.text);
|
|
5418
|
+
continue;
|
|
5419
|
+
}
|
|
5420
|
+
const nested = asRecord2(row.text);
|
|
5421
|
+
if (typeof nested?.text === "string") texts.push(nested.text);
|
|
5422
|
+
}
|
|
5423
|
+
return texts;
|
|
5424
|
+
};
|
|
5425
|
+
const value = asRecord2(rec.value);
|
|
5426
|
+
if (value && Array.isArray(value.content)) {
|
|
5427
|
+
const texts = collectTexts(value.content);
|
|
5428
|
+
if (texts.length) return texts.join("\n");
|
|
5429
|
+
}
|
|
5430
|
+
if (Array.isArray(rec.content)) {
|
|
5431
|
+
const texts = collectTexts(rec.content);
|
|
5432
|
+
if (texts.length) return texts.join("\n");
|
|
5433
|
+
}
|
|
5434
|
+
try {
|
|
5435
|
+
return JSON.stringify(result);
|
|
5436
|
+
} catch {
|
|
5437
|
+
return String(result);
|
|
5438
|
+
}
|
|
5439
|
+
}
|
|
5440
|
+
function cursorToolResultIsError(status, result) {
|
|
5441
|
+
if (status === "error") return true;
|
|
5442
|
+
const rec = asRecord2(result);
|
|
5443
|
+
if (!rec) return false;
|
|
5444
|
+
if (rec.status === "error") return true;
|
|
5445
|
+
const value = asRecord2(rec.value);
|
|
5446
|
+
return value?.isError === true;
|
|
5447
|
+
}
|
|
5263
5448
|
function cursorSdkMessageToEvents(msg) {
|
|
5264
5449
|
if (!msg?.type) return [];
|
|
5265
5450
|
if (msg.type === "system" && msg.agent_id) {
|
|
@@ -5274,35 +5459,42 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
5274
5459
|
if (block?.type === "text" && block.text) {
|
|
5275
5460
|
out.push({ type: "stdout", data: block.text });
|
|
5276
5461
|
} else if (block?.type === "tool_use" && block.id && block.name) {
|
|
5462
|
+
const normalized = normalizeCursorToolCall(block.name, block.input);
|
|
5277
5463
|
out.push({
|
|
5278
5464
|
type: "tool_use",
|
|
5279
5465
|
id: block.id,
|
|
5280
|
-
name:
|
|
5281
|
-
input:
|
|
5466
|
+
name: normalized.name,
|
|
5467
|
+
input: normalized.input
|
|
5282
5468
|
});
|
|
5283
5469
|
}
|
|
5284
5470
|
}
|
|
5285
5471
|
return out;
|
|
5286
5472
|
}
|
|
5287
5473
|
if (msg.type === "tool_call" && msg.call_id && msg.name) {
|
|
5474
|
+
const normalized = normalizeCursorToolCall(msg.name, msg.args);
|
|
5288
5475
|
if (msg.status === "running") {
|
|
5289
5476
|
return [
|
|
5290
5477
|
{
|
|
5291
5478
|
type: "tool_use",
|
|
5292
5479
|
id: msg.call_id,
|
|
5293
|
-
name:
|
|
5294
|
-
input:
|
|
5480
|
+
name: normalized.name,
|
|
5481
|
+
input: normalized.input
|
|
5295
5482
|
}
|
|
5296
5483
|
];
|
|
5297
5484
|
}
|
|
5298
5485
|
if (msg.status === "completed" || msg.status === "error") {
|
|
5299
|
-
const content = typeof msg.result === "string" ? msg.result : msg.result != null ? JSON.stringify(msg.result) : void 0;
|
|
5300
5486
|
return [
|
|
5487
|
+
{
|
|
5488
|
+
type: "tool_use",
|
|
5489
|
+
id: msg.call_id,
|
|
5490
|
+
name: normalized.name,
|
|
5491
|
+
input: normalized.input
|
|
5492
|
+
},
|
|
5301
5493
|
{
|
|
5302
5494
|
type: "tool_result",
|
|
5303
5495
|
id: msg.call_id,
|
|
5304
|
-
content,
|
|
5305
|
-
isError: msg.status
|
|
5496
|
+
content: unwrapCursorToolResult(msg.result),
|
|
5497
|
+
isError: cursorToolResultIsError(msg.status, msg.result)
|
|
5306
5498
|
}
|
|
5307
5499
|
];
|
|
5308
5500
|
}
|
|
@@ -5672,17 +5864,31 @@ var init_opencode = __esm({
|
|
|
5672
5864
|
return { type: "stderr", data: detail };
|
|
5673
5865
|
}
|
|
5674
5866
|
const sid = typeof obj.sessionID === "string" && obj.sessionID || typeof obj.sessionId === "string" && obj.sessionId || typeof obj.session_id === "string" && obj.session_id;
|
|
5675
|
-
if (sid
|
|
5867
|
+
if (sid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
|
|
5868
|
+
return { type: "session_id", data: sid };
|
|
5869
|
+
}
|
|
5676
5870
|
if (obj.type === "text") {
|
|
5677
5871
|
const text = obj.part?.text ?? obj.text;
|
|
5678
5872
|
if (text) return { type: "stdout", data: text };
|
|
5679
5873
|
}
|
|
5680
5874
|
if (obj.type === "tool_use") {
|
|
5681
5875
|
const part = obj.part;
|
|
5682
|
-
const id = part?.id ?? obj.id ?? `tool-${Date.now()}`;
|
|
5683
|
-
const name = part?.
|
|
5684
|
-
const
|
|
5685
|
-
|
|
5876
|
+
const id = part?.callID ?? part?.id ?? obj.id ?? `tool-${Date.now()}`;
|
|
5877
|
+
const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
|
|
5878
|
+
const state = part?.state;
|
|
5879
|
+
const input = (state?.input && typeof state.input === "object" ? state.input : void 0) ?? part?.input ?? obj.input;
|
|
5880
|
+
const events = [{ type: "tool_use", id, name, input }];
|
|
5881
|
+
const output = state?.output;
|
|
5882
|
+
if (output != null || state?.status === "completed" || state?.status === "error") {
|
|
5883
|
+
const content = typeof output === "string" ? output : output != null ? JSON.stringify(output) : formatUnknownDetail(state?.error) || void 0;
|
|
5884
|
+
events.push({
|
|
5885
|
+
type: "tool_result",
|
|
5886
|
+
id,
|
|
5887
|
+
content,
|
|
5888
|
+
isError: state?.status === "error" || state?.status === "failed"
|
|
5889
|
+
});
|
|
5890
|
+
}
|
|
5891
|
+
return events.length === 1 ? events[0] : events;
|
|
5686
5892
|
}
|
|
5687
5893
|
if (obj.type === "tool_result") {
|
|
5688
5894
|
const part = obj.part;
|
|
@@ -5710,6 +5916,7 @@ var init_opencode = __esm({
|
|
|
5710
5916
|
}
|
|
5711
5917
|
},
|
|
5712
5918
|
async resolveSessionId(worktreePath, cached) {
|
|
5919
|
+
const cachedId = cached?.trim() || null;
|
|
5713
5920
|
const listed = await run(
|
|
5714
5921
|
"opencode",
|
|
5715
5922
|
["session", "list", "--format", "json"],
|
|
@@ -5721,15 +5928,21 @@ var init_opencode = __esm({
|
|
|
5721
5928
|
if (Array.isArray(sessions) && sessions.length > 0) {
|
|
5722
5929
|
const norm = (p) => p.replace(/\/+$/, "");
|
|
5723
5930
|
const wt = norm(worktreePath);
|
|
5724
|
-
const
|
|
5931
|
+
const forWorktree = sessions.filter(
|
|
5725
5932
|
(s) => s.directory && norm(s.directory) === wt || s.path && norm(s.path) === wt
|
|
5726
5933
|
);
|
|
5727
|
-
if (
|
|
5934
|
+
if (cachedId && forWorktree.some((s) => s.id === cachedId)) {
|
|
5935
|
+
return cachedId;
|
|
5936
|
+
}
|
|
5937
|
+
if (cachedId && sessions.some((s) => s.id === cachedId)) {
|
|
5938
|
+
return cachedId;
|
|
5939
|
+
}
|
|
5940
|
+
return null;
|
|
5728
5941
|
}
|
|
5729
5942
|
} catch {
|
|
5730
5943
|
}
|
|
5731
5944
|
}
|
|
5732
|
-
return
|
|
5945
|
+
return cachedId;
|
|
5733
5946
|
},
|
|
5734
5947
|
async buildAttach(thread) {
|
|
5735
5948
|
const sessionId = await this.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
@@ -6347,7 +6560,7 @@ var init_workspaces = __esm({
|
|
|
6347
6560
|
});
|
|
6348
6561
|
|
|
6349
6562
|
// src/plan/plan-present.ts
|
|
6350
|
-
function
|
|
6563
|
+
function asRecord4(v) {
|
|
6351
6564
|
return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
6352
6565
|
}
|
|
6353
6566
|
function isPresentPlanToolName(name) {
|
|
@@ -6359,7 +6572,7 @@ function extractPresentedPlan(parts) {
|
|
|
6359
6572
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
6360
6573
|
const p = parts[i];
|
|
6361
6574
|
if (p.type !== "tool" || !isPresentPlanToolName(p.name)) continue;
|
|
6362
|
-
const input =
|
|
6575
|
+
const input = asRecord4(p.input) ?? {};
|
|
6363
6576
|
const content = typeof input.content === "string" ? input.content : typeof input.plan === "string" ? input.plan : typeof input.markdown === "string" ? input.markdown : "";
|
|
6364
6577
|
if (!content.trim()) continue;
|
|
6365
6578
|
const title = typeof input.title === "string" && input.title.trim() ? input.title.trim() : "Plan";
|
|
@@ -6525,7 +6738,7 @@ init_agents();
|
|
|
6525
6738
|
init_orchestrator_capable();
|
|
6526
6739
|
|
|
6527
6740
|
// src/agents/message-parts.ts
|
|
6528
|
-
function
|
|
6741
|
+
function asRecord3(input) {
|
|
6529
6742
|
if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
6530
6743
|
return input;
|
|
6531
6744
|
}
|
|
@@ -6660,7 +6873,7 @@ function applyAgentEvent(parts, event) {
|
|
|
6660
6873
|
return next;
|
|
6661
6874
|
}
|
|
6662
6875
|
if (event.type === "tool_use") {
|
|
6663
|
-
const input =
|
|
6876
|
+
const input = asRecord3(event.input);
|
|
6664
6877
|
const diff = diffFromInput(input);
|
|
6665
6878
|
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
6666
6879
|
if (existing >= 0) {
|
|
@@ -6694,9 +6907,25 @@ function applyAgentEvent(parts, event) {
|
|
|
6694
6907
|
];
|
|
6695
6908
|
}
|
|
6696
6909
|
if (event.type === "tool_result") {
|
|
6697
|
-
const
|
|
6698
|
-
|
|
6699
|
-
|
|
6910
|
+
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
6911
|
+
const fromResult = parseDiffStat(event.content);
|
|
6912
|
+
if (existing < 0) {
|
|
6913
|
+
return [
|
|
6914
|
+
...parts,
|
|
6915
|
+
{
|
|
6916
|
+
type: "tool",
|
|
6917
|
+
id: event.id,
|
|
6918
|
+
name: "tool",
|
|
6919
|
+
description: "tool",
|
|
6920
|
+
status: event.isError ? "error" : "done",
|
|
6921
|
+
result: event.content,
|
|
6922
|
+
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
6923
|
+
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
6924
|
+
}
|
|
6925
|
+
];
|
|
6926
|
+
}
|
|
6927
|
+
return parts.map((p, i) => {
|
|
6928
|
+
if (i !== existing || p.type !== "tool") return p;
|
|
6700
6929
|
return {
|
|
6701
6930
|
...p,
|
|
6702
6931
|
status: event.isError ? "error" : "done",
|
|
@@ -6705,7 +6934,6 @@ function applyAgentEvent(parts, event) {
|
|
|
6705
6934
|
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
6706
6935
|
};
|
|
6707
6936
|
});
|
|
6708
|
-
return next;
|
|
6709
6937
|
}
|
|
6710
6938
|
return parts;
|
|
6711
6939
|
}
|
|
@@ -7501,10 +7729,17 @@ async function requireAgent(agent, opts) {
|
|
|
7501
7729
|
|
|
7502
7730
|
// src/threads/create.ts
|
|
7503
7731
|
init_worktree();
|
|
7732
|
+
init_app_settings();
|
|
7504
7733
|
init_thread_store();
|
|
7505
7734
|
init_workspaces();
|
|
7506
7735
|
async function createThread(input, _onSetupLine) {
|
|
7507
|
-
|
|
7736
|
+
const resolved = resolveNewThreadOptions({
|
|
7737
|
+
agent: input.agent,
|
|
7738
|
+
model: input.model,
|
|
7739
|
+
effort: input.effort,
|
|
7740
|
+
fast: input.fast
|
|
7741
|
+
});
|
|
7742
|
+
await requireAgent(resolved.agent);
|
|
7508
7743
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
7509
7744
|
if (!(0, import_node_fs18.existsSync)(repoPath)) {
|
|
7510
7745
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
@@ -7547,11 +7782,11 @@ async function createThread(input, _onSetupLine) {
|
|
|
7547
7782
|
branchName,
|
|
7548
7783
|
worktreePath,
|
|
7549
7784
|
repoPath,
|
|
7550
|
-
agent:
|
|
7785
|
+
agent: resolved.agent,
|
|
7551
7786
|
autonomy: input.autonomy ?? "default",
|
|
7552
|
-
model:
|
|
7553
|
-
effort:
|
|
7554
|
-
fast:
|
|
7787
|
+
model: resolved.model,
|
|
7788
|
+
effort: resolved.effort,
|
|
7789
|
+
fast: resolved.fast,
|
|
7555
7790
|
planMode: Boolean(input.planMode),
|
|
7556
7791
|
attachments: input.attachments ?? [],
|
|
7557
7792
|
sourceIsFork,
|
|
@@ -10479,21 +10714,30 @@ var Orchestrator = class {
|
|
|
10479
10714
|
return findThreadByRef(idOrRef) ?? readThread(idOrRef);
|
|
10480
10715
|
}
|
|
10481
10716
|
async createThread(input) {
|
|
10482
|
-
|
|
10717
|
+
const thread = await createThread(input);
|
|
10483
10718
|
this.emit({ type: "status_changed", threadId: thread.id, status: thread.status });
|
|
10484
|
-
|
|
10719
|
+
void this.finishCreateThread(thread.id, input.prompt?.trim() || void 0);
|
|
10720
|
+
return thread;
|
|
10721
|
+
}
|
|
10722
|
+
async finishCreateThread(threadId, prompt) {
|
|
10723
|
+
await this.runSetupAfterCreate(threadId);
|
|
10485
10724
|
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
10486
10725
|
if (autoRunAfterSetupEnabled2()) {
|
|
10487
10726
|
try {
|
|
10488
|
-
await this.startDev(
|
|
10727
|
+
await this.startDev(threadId);
|
|
10489
10728
|
} catch {
|
|
10490
10729
|
}
|
|
10491
10730
|
}
|
|
10492
|
-
const prompt = input.prompt?.trim();
|
|
10493
10731
|
if (prompt) {
|
|
10494
|
-
|
|
10732
|
+
try {
|
|
10733
|
+
await this.send(threadId, prompt);
|
|
10734
|
+
} catch (err) {
|
|
10735
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
10736
|
+
updateThread(threadId, {
|
|
10737
|
+
lastError: `First prompt failed: ${message}`
|
|
10738
|
+
});
|
|
10739
|
+
}
|
|
10495
10740
|
}
|
|
10496
|
-
return thread;
|
|
10497
10741
|
}
|
|
10498
10742
|
/** Run workspace setup after a new worktree is created (no-op if none configured). */
|
|
10499
10743
|
async runSetupAfterCreate(threadId) {
|
|
@@ -10509,7 +10753,7 @@ var Orchestrator = class {
|
|
|
10509
10753
|
}
|
|
10510
10754
|
}
|
|
10511
10755
|
listWorkspaces() {
|
|
10512
|
-
const fromThreads = listThreads({ includeArchived:
|
|
10756
|
+
const fromThreads = listThreads({ includeArchived: true }).map((t) => t.repoPath);
|
|
10513
10757
|
return syncWorkspacesFromThreads(fromThreads);
|
|
10514
10758
|
}
|
|
10515
10759
|
async addWorkspace(repoPath) {
|
|
@@ -10839,8 +11083,73 @@ var Orchestrator = class {
|
|
|
10839
11083
|
}
|
|
10840
11084
|
}
|
|
10841
11085
|
}
|
|
10842
|
-
|
|
10843
|
-
|
|
11086
|
+
let lastStderr = summarizeTurnStderr(stderrTail);
|
|
11087
|
+
let detail = lastStderr || (exitCode !== 0 ? fallbackTurnFailDetail(assistantText) : "");
|
|
11088
|
+
if (exitCode !== 0 && !assistantText && parts.length === 0 && !this.stoppedTurns.has(threadId) && looksLikeInvalidAgentSession(detail) && this.requireThread(threadId).sessionId && this.requireThread(threadId).agent !== "cursor" && this.requireThread(threadId).agent !== "brightsy") {
|
|
11089
|
+
updateThread(threadId, { sessionId: null });
|
|
11090
|
+
pushTurnStderr(
|
|
11091
|
+
stderrTail,
|
|
11092
|
+
"Agent session missing \u2014 starting a fresh session"
|
|
11093
|
+
);
|
|
11094
|
+
this.emit({
|
|
11095
|
+
type: "turn_output",
|
|
11096
|
+
threadId,
|
|
11097
|
+
event: {
|
|
11098
|
+
type: "stderr",
|
|
11099
|
+
data: "Agent session missing \u2014 starting a fresh session"
|
|
11100
|
+
}
|
|
11101
|
+
});
|
|
11102
|
+
const retryThread = this.requireThread(threadId);
|
|
11103
|
+
const prior = retryThread.messages.slice(0, -1);
|
|
11104
|
+
const retrySeed = buildSessionSeed(prior);
|
|
11105
|
+
const retryInstructions = retryThread.agent === "claude" ? null : formatAgentInstructions(
|
|
11106
|
+
loadAgentInstructions(retryThread.worktreePath, retryThread.agent)
|
|
11107
|
+
);
|
|
11108
|
+
const retryPrefix = [
|
|
11109
|
+
coordinatorDirective,
|
|
11110
|
+
worktreeDirective,
|
|
11111
|
+
artifactDirective,
|
|
11112
|
+
renameBranchDirective,
|
|
11113
|
+
retryInstructions,
|
|
11114
|
+
retrySeed
|
|
11115
|
+
].filter(Boolean).join("\n\n---\n\n");
|
|
11116
|
+
const retryHandle = await spawnAgentTurn(
|
|
11117
|
+
retryThread,
|
|
11118
|
+
{ cachedPrefix: retryPrefix, prompt: agentPrompt },
|
|
11119
|
+
(event) => {
|
|
11120
|
+
this.emit({ type: "turn_output", threadId, event });
|
|
11121
|
+
if (event.type === "session_id") {
|
|
11122
|
+
updateThread(threadId, { sessionId: event.data });
|
|
11123
|
+
}
|
|
11124
|
+
if (event.type === "stderr" && typeof event.data === "string") {
|
|
11125
|
+
pushTurnStderr(stderrTail, event.data);
|
|
11126
|
+
}
|
|
11127
|
+
}
|
|
11128
|
+
);
|
|
11129
|
+
this.activeTurns.set(threadId, retryHandle);
|
|
11130
|
+
if (typeof retryHandle.pid === "number" && retryHandle.pid > 0) {
|
|
11131
|
+
updateThread(threadId, { agentPid: retryHandle.pid });
|
|
11132
|
+
}
|
|
11133
|
+
this.processes.set(`${threadId}:agent`, {
|
|
11134
|
+
kind: "agent",
|
|
11135
|
+
pid: retryHandle.pid,
|
|
11136
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11137
|
+
kill: retryHandle.kill
|
|
11138
|
+
});
|
|
11139
|
+
if (this.stoppedTurns.has(threadId)) {
|
|
11140
|
+
retryHandle.kill();
|
|
11141
|
+
}
|
|
11142
|
+
const retryResult = await retryHandle.done;
|
|
11143
|
+
if (retryResult.sessionId) {
|
|
11144
|
+
updateThread(threadId, { sessionId: retryResult.sessionId });
|
|
11145
|
+
}
|
|
11146
|
+
assistantText = retryResult.assistantText.trim();
|
|
11147
|
+
parts = retryResult.parts;
|
|
11148
|
+
usage = retryResult.usage ?? void 0;
|
|
11149
|
+
exitCode = retryResult.exitCode;
|
|
11150
|
+
lastStderr = summarizeTurnStderr(stderrTail);
|
|
11151
|
+
detail = lastStderr || (exitCode !== 0 ? fallbackTurnFailDetail(assistantText) : "");
|
|
11152
|
+
}
|
|
10844
11153
|
let chatText = assistantText;
|
|
10845
11154
|
if (exitCode !== 0 && !chatText && looksLikeAgentFailureMessage(detail)) {
|
|
10846
11155
|
chatText = humanizeAgentFailDetail(detail);
|
|
@@ -11544,7 +11853,15 @@ var Orchestrator = class {
|
|
|
11544
11853
|
}
|
|
11545
11854
|
await removeWorktree(thread.repoPath, thread.worktreePath);
|
|
11546
11855
|
}
|
|
11547
|
-
|
|
11856
|
+
const archived = setStatus(thread.id, "archived");
|
|
11857
|
+
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
11858
|
+
try {
|
|
11859
|
+
const { ensureWorkspace: ensureWorkspace2 } = await Promise.resolve().then(() => (init_workspaces(), workspaces_exports));
|
|
11860
|
+
await ensureWorkspace2(thread.repoPath);
|
|
11861
|
+
} catch {
|
|
11862
|
+
}
|
|
11863
|
+
}
|
|
11864
|
+
return archived;
|
|
11548
11865
|
}
|
|
11549
11866
|
async purge(threadRef, opts) {
|
|
11550
11867
|
const thread = this.requireThread(threadRef);
|
|
@@ -11966,13 +12283,19 @@ async function startMcpServer() {
|
|
|
11966
12283
|
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
11967
12284
|
}
|
|
11968
12285
|
);
|
|
12286
|
+
const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
12287
|
+
const accountDefaults = resolveThreadDefaults2();
|
|
12288
|
+
const accountDefaultsHint = `Account defaults: agent=${accountDefaults.agent}, model=${accountDefaults.model?.trim() || "Auto"}, effort=${accountDefaults.effort}`;
|
|
11969
12289
|
server.tool(
|
|
11970
12290
|
"create_thread",
|
|
11971
|
-
|
|
12291
|
+
`Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces and parentThreadId when spawning from an orchestrator. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Then use send_to_thread to chat.`,
|
|
11972
12292
|
{
|
|
11973
12293
|
sourceType: import_zod.z.enum(["branch", "pr", "ticket"]),
|
|
11974
12294
|
sourceRef: import_zod.z.string(),
|
|
11975
|
-
agent: import_zod.z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]),
|
|
12295
|
+
agent: import_zod.z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]).optional().describe(`Omit to use Account default agent (${accountDefaults.agent})`),
|
|
12296
|
+
model: import_zod.z.string().nullable().optional().describe(
|
|
12297
|
+
`Usually omit to use Account default model (${accountDefaults.model?.trim() || "Auto"}). Pass null only to force Auto / agent-default.`
|
|
12298
|
+
),
|
|
11976
12299
|
repoPath: import_zod.z.string(),
|
|
11977
12300
|
title: import_zod.z.string().optional(),
|
|
11978
12301
|
parentThreadId: import_zod.z.string().optional()
|
|
@@ -11992,10 +12315,17 @@ async function startMcpServer() {
|
|
|
11992
12315
|
};
|
|
11993
12316
|
}
|
|
11994
12317
|
}
|
|
12318
|
+
const opts = resolveNewThreadOptions2({
|
|
12319
|
+
agent: args.agent,
|
|
12320
|
+
model: args.model
|
|
12321
|
+
});
|
|
11995
12322
|
const thread = await orch.createThread({
|
|
11996
12323
|
sourceType: args.sourceType,
|
|
11997
12324
|
sourceRef: args.sourceRef,
|
|
11998
|
-
agent:
|
|
12325
|
+
agent: opts.agent,
|
|
12326
|
+
model: opts.model,
|
|
12327
|
+
effort: opts.effort,
|
|
12328
|
+
fast: opts.fast,
|
|
11999
12329
|
repoPath: args.repoPath,
|
|
12000
12330
|
title: args.title,
|
|
12001
12331
|
parentThreadId: args.parentThreadId ?? null
|
|
@@ -12009,6 +12339,8 @@ async function startMcpServer() {
|
|
|
12009
12339
|
title: thread.title,
|
|
12010
12340
|
branchName: thread.branchName,
|
|
12011
12341
|
worktreePath: thread.worktreePath,
|
|
12342
|
+
agent: thread.agent,
|
|
12343
|
+
model: thread.model,
|
|
12012
12344
|
status: thread.status,
|
|
12013
12345
|
link: `sideboard://thread/${thread.id}`
|
|
12014
12346
|
})
|