@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/index.cjs
CHANGED
|
@@ -416,6 +416,7 @@ __export(app_settings_exports, {
|
|
|
416
416
|
orchestrationQuotaOnLimit: () => orchestrationQuotaOnLimit,
|
|
417
417
|
resolveClaudeExecutable: () => resolveClaudeExecutable,
|
|
418
418
|
resolveEffectiveIssueSource: () => resolveEffectiveIssueSource,
|
|
419
|
+
resolveNewThreadOptions: () => resolveNewThreadOptions,
|
|
419
420
|
resolveThreadDefaults: () => resolveThreadDefaults,
|
|
420
421
|
saveAppSettings: () => saveAppSettings,
|
|
421
422
|
updateAdvancedSettings: () => updateAdvancedSettings,
|
|
@@ -708,6 +709,16 @@ function resolveThreadDefaults(settings = loadAppSettings()) {
|
|
|
708
709
|
fast: getDefaultFast(settings)
|
|
709
710
|
};
|
|
710
711
|
}
|
|
712
|
+
function resolveNewThreadOptions(overrides = {}, settings = loadAppSettings()) {
|
|
713
|
+
const defaults = resolveThreadDefaults(settings);
|
|
714
|
+
const effort = overrides.effort === void 0 || overrides.effort === null ? defaults.effort : normalizeThinkingEffort(overrides.effort) ?? defaults.effort;
|
|
715
|
+
return {
|
|
716
|
+
agent: overrides.agent ?? defaults.agent,
|
|
717
|
+
model: overrides.model === void 0 ? defaults.model : overrides.model?.trim() || null,
|
|
718
|
+
effort,
|
|
719
|
+
fast: overrides.fast === void 0 || overrides.fast === null ? defaults.fast : Boolean(overrides.fast)
|
|
720
|
+
};
|
|
721
|
+
}
|
|
711
722
|
function isLinearConnected(settings = loadAppSettings()) {
|
|
712
723
|
return Boolean(settings.integrations.linearApiKey?.trim());
|
|
713
724
|
}
|
|
@@ -727,7 +738,12 @@ function brightsyCloudConnectEnabled(settings = loadAppSettings()) {
|
|
|
727
738
|
return Boolean(settings.brightsy.cloudConnectEnabled);
|
|
728
739
|
}
|
|
729
740
|
function brightsyCloudConnectAgent(settings = loadAppSettings()) {
|
|
730
|
-
|
|
741
|
+
const fallback = settings.brightsy.cloudConnectAgent && CLOUD_CONNECT_AGENTS.has(settings.brightsy.cloudConnectAgent) ? settings.brightsy.cloudConnectAgent : "claude";
|
|
742
|
+
const preferred = getDefaultAgent(settings);
|
|
743
|
+
if (CLOUD_CONNECT_AGENTS.has(preferred)) {
|
|
744
|
+
return preferred;
|
|
745
|
+
}
|
|
746
|
+
return fallback;
|
|
731
747
|
}
|
|
732
748
|
function updateAdvancedSettings(patch) {
|
|
733
749
|
const current = loadAppSettings();
|
|
@@ -3512,6 +3528,11 @@ function coordinatorGreenfieldPlaybook(reposDir) {
|
|
|
3512
3528
|
"- Do coding work in the child worktree thread, not by editing files in this home cwd."
|
|
3513
3529
|
].join("\n");
|
|
3514
3530
|
}
|
|
3531
|
+
function accountDefaultsPlaybookLine() {
|
|
3532
|
+
const d = resolveThreadDefaults();
|
|
3533
|
+
const model = d.model?.trim() || "Auto";
|
|
3534
|
+
return `- Account defaults for create_thread (omit agent/model to use these): agent=${d.agent}, model=${model}, effort=${d.effort}`;
|
|
3535
|
+
}
|
|
3515
3536
|
function coordinatorTurnReminder(opts) {
|
|
3516
3537
|
const goal = opts.goal?.trim();
|
|
3517
3538
|
return [
|
|
@@ -3521,6 +3542,7 @@ function coordinatorTurnReminder(opts) {
|
|
|
3521
3542
|
"- Registered workspaces / child threads are the fleet you manage via Sideboard MCP.",
|
|
3522
3543
|
`- Parent thread id (pass as parentThreadId when creating children): ${opts.parentId}`,
|
|
3523
3544
|
goal ? `- Goal / title: ${goal}` : null,
|
|
3545
|
+
accountDefaultsPlaybookLine(),
|
|
3524
3546
|
`- 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.`,
|
|
3525
3547
|
"- Existing repo: create_thread on a repoPath \u2192 send_to_thread \u2192 wait_for_turn.",
|
|
3526
3548
|
"- 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.",
|
|
@@ -3543,9 +3565,12 @@ function ensureGlobalCoordinatorCwd() {
|
|
|
3543
3565
|
"",
|
|
3544
3566
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
3545
3567
|
"",
|
|
3568
|
+
accountDefaultsPlaybookLine(),
|
|
3569
|
+
"",
|
|
3546
3570
|
coordinatorGreenfieldPlaybook(reposDir),
|
|
3547
3571
|
"",
|
|
3548
3572
|
"When creating threads, pass `repoPath` from `list_workspaces` (or the path you just registered) and `parentThreadId` for children.",
|
|
3573
|
+
"Omit `agent` / `model` on `create_thread` unless you have a reason to override Account defaults.",
|
|
3549
3574
|
"Typical flow (existing): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn.",
|
|
3550
3575
|
"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.",
|
|
3551
3576
|
"Always ask worktree agents to open draft PRs (`send_to_thread` + `gh pr create --draft -R <origin>`); never open PRs from the orchestrator."
|
|
@@ -3571,8 +3596,10 @@ function coordinatorSystemPrompt(opts) {
|
|
|
3571
3596
|
"You operate across ALL registered workspaces below.",
|
|
3572
3597
|
"You have no project git home \u2014 this process cwd is synthetic and empty on purpose.",
|
|
3573
3598
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
3599
|
+
accountDefaultsPlaybookLine(),
|
|
3574
3600
|
coordinatorGreenfieldPlaybook(reposDir),
|
|
3575
3601
|
"When creating threads, pass the correct repoPath for the target workspace and parentThreadId for children.",
|
|
3602
|
+
"Omit agent/model on create_thread unless you need to override Account defaults.",
|
|
3576
3603
|
"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.",
|
|
3577
3604
|
"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.",
|
|
3578
3605
|
`Goal: ${opts.goal}`,
|
|
@@ -3588,6 +3615,7 @@ var init_coordinator_prompt = __esm({
|
|
|
3588
3615
|
import_node_fs6 = require("fs");
|
|
3589
3616
|
import_node_path7 = require("path");
|
|
3590
3617
|
init_worktree();
|
|
3618
|
+
init_app_settings();
|
|
3591
3619
|
init_paths();
|
|
3592
3620
|
COORDINATOR_TOOL_PLAYBOOK = [
|
|
3593
3621
|
"Role: you oversee Sideboard worktree agents across registered repos. You do not live inside one of those worktrees.",
|
|
@@ -3596,12 +3624,12 @@ var init_coordinator_prompt = __esm({
|
|
|
3596
3624
|
"- list_workspaces \u2014 registered repos (path + github slug when known)",
|
|
3597
3625
|
"- list_branches / list_prs / list_issues \u2014 pass repoPath from list_workspaces (issues: Linear API or GitHub Issues)",
|
|
3598
3626
|
"- get_pr_stack / open_pr_stack_layers / add_stack_layer / create_pr_stack \u2014 GitHub stacked PRs (`gh stack`); one worktree per layer",
|
|
3599
|
-
"- list_models \u2014 only when you need a specific model (rare); otherwise
|
|
3627
|
+
"- list_models \u2014 only when you need a specific model (rare); otherwise omit model so Account defaults apply",
|
|
3600
3628
|
"- list_threads / get_thread \u2014 fleet status (what is going on)",
|
|
3601
3629
|
"Workspaces:",
|
|
3602
3630
|
"- add_workspace / remove_workspace \u2014 register or unregister a git repo",
|
|
3603
3631
|
"Worktree threads (chats):",
|
|
3604
|
-
"- create_thread \u2014 create a worktree + chat from branch | pr | ticket; pass repoPath + parentThreadId",
|
|
3632
|
+
"- 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)",
|
|
3605
3633
|
"- 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.",
|
|
3606
3634
|
"- 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.",
|
|
3607
3635
|
"- 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",
|
|
@@ -3701,7 +3729,13 @@ function createGlobalChat(opts) {
|
|
|
3701
3729
|
const explicit = opts.title?.trim();
|
|
3702
3730
|
const title = explicit && explicit !== CLOUD_ORCHESTRATOR_GOAL ? explicit : allocateTeamName(takenTeamSlugsForOrchestration()).name;
|
|
3703
3731
|
const sourceRef = opts.sourceRef?.trim() || (isCloud ? CLOUD_ORCHESTRATOR_GOAL : title);
|
|
3704
|
-
const
|
|
3732
|
+
const resolved = resolveNewThreadOptions({
|
|
3733
|
+
agent: opts.agent,
|
|
3734
|
+
model: opts.model,
|
|
3735
|
+
effort: opts.effort,
|
|
3736
|
+
fast: opts.fast
|
|
3737
|
+
});
|
|
3738
|
+
const agent = assertOrchestratorCapableAgent(resolved.agent);
|
|
3705
3739
|
const thread = createEmptyThread({
|
|
3706
3740
|
title,
|
|
3707
3741
|
// Stick nicknames the same way chat tabs do (avoid later sync overwrites).
|
|
@@ -3713,9 +3747,9 @@ function createGlobalChat(opts) {
|
|
|
3713
3747
|
repoPath: GLOBAL_WORKSPACE_ID,
|
|
3714
3748
|
agent,
|
|
3715
3749
|
autonomy: opts.autonomy ?? "default",
|
|
3716
|
-
model:
|
|
3717
|
-
effort:
|
|
3718
|
-
fast:
|
|
3750
|
+
model: resolved.model,
|
|
3751
|
+
effort: resolved.effort,
|
|
3752
|
+
fast: resolved.fast,
|
|
3719
3753
|
planMode: Boolean(opts.planMode),
|
|
3720
3754
|
attachments: opts.attachments ?? [],
|
|
3721
3755
|
parentThreadId: opts.parentThreadId ?? null,
|
|
@@ -3748,20 +3782,35 @@ function findCloudCoordinator() {
|
|
|
3748
3782
|
);
|
|
3749
3783
|
}
|
|
3750
3784
|
function ensureCloudCoordinator(agent) {
|
|
3785
|
+
const defaults = resolveThreadDefaults();
|
|
3786
|
+
const desired = assertOrchestratorCapableAgent(agent);
|
|
3751
3787
|
const existing = findCloudCoordinator();
|
|
3752
3788
|
if (existing) {
|
|
3789
|
+
const patch = {};
|
|
3753
3790
|
if (existing.repoPath !== GLOBAL_WORKSPACE_ID) {
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3791
|
+
patch.repoPath = GLOBAL_WORKSPACE_ID;
|
|
3792
|
+
patch.worktreePath = globalAgentCwd();
|
|
3793
|
+
patch.branchName = "global";
|
|
3794
|
+
}
|
|
3795
|
+
const hasAgentTurns = existing.messages.some((m) => m.role === "agent");
|
|
3796
|
+
const canRetarget = !existing.sessionId && !hasAgentTurns && existing.status !== "running" && existing.status !== "queued";
|
|
3797
|
+
if (canRetarget) {
|
|
3798
|
+
if (existing.agent !== desired) patch.agent = desired;
|
|
3799
|
+
if (existing.model !== defaults.model) patch.model = defaults.model;
|
|
3800
|
+
if (existing.effort !== defaults.effort) patch.effort = defaults.effort;
|
|
3801
|
+
if (existing.fast !== defaults.fast) patch.fast = defaults.fast;
|
|
3802
|
+
}
|
|
3803
|
+
if (Object.keys(patch).length > 0) {
|
|
3804
|
+
return updateThread(existing.id, patch);
|
|
3759
3805
|
}
|
|
3760
3806
|
return existing;
|
|
3761
3807
|
}
|
|
3762
3808
|
const created = createGlobalChat({
|
|
3763
3809
|
sourceRef: CLOUD_ORCHESTRATOR_GOAL,
|
|
3764
|
-
agent
|
|
3810
|
+
agent: desired,
|
|
3811
|
+
model: defaults.model,
|
|
3812
|
+
effort: defaults.effort,
|
|
3813
|
+
fast: defaults.fast
|
|
3765
3814
|
});
|
|
3766
3815
|
const all = listThreads({ includeArchived: true }).filter(
|
|
3767
3816
|
(t) => t.status !== "archived" && isCloudCoordinatorThread(t)
|
|
@@ -3776,6 +3825,7 @@ var init_global_workspace = __esm({
|
|
|
3776
3825
|
init_orchestrator_capable();
|
|
3777
3826
|
init_teams();
|
|
3778
3827
|
init_coordinator_prompt();
|
|
3828
|
+
init_app_settings();
|
|
3779
3829
|
init_paths();
|
|
3780
3830
|
init_thread_store();
|
|
3781
3831
|
GLOBAL_WORKSPACE_ID = "__global__";
|
|
@@ -4316,6 +4366,11 @@ function summarizeTurnStderr(tail, maxChars = 500) {
|
|
|
4316
4366
|
if (joined.length <= maxChars) return joined;
|
|
4317
4367
|
return joined.slice(joined.length - maxChars);
|
|
4318
4368
|
}
|
|
4369
|
+
function looksLikeInvalidAgentSession(text) {
|
|
4370
|
+
const lower = text.trim().toLowerCase();
|
|
4371
|
+
if (!lower) return false;
|
|
4372
|
+
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);
|
|
4373
|
+
}
|
|
4319
4374
|
function looksLikeAgentFailureMessage(text) {
|
|
4320
4375
|
const lower = text.trim().toLowerCase();
|
|
4321
4376
|
if (!lower) return false;
|
|
@@ -4953,6 +5008,7 @@ function toCodexMcpConfigArgs(servers) {
|
|
|
4953
5008
|
args.push("-c", `${prefix}.env.${key}=${JSON.stringify(value)}`);
|
|
4954
5009
|
}
|
|
4955
5010
|
}
|
|
5011
|
+
args.push("-c", `${prefix}.default_tools_approval_mode=${JSON.stringify("approve")}`);
|
|
4956
5012
|
}
|
|
4957
5013
|
return args;
|
|
4958
5014
|
}
|
|
@@ -5468,6 +5524,32 @@ function codexConfigHasNetworkAccess() {
|
|
|
5468
5524
|
}
|
|
5469
5525
|
return false;
|
|
5470
5526
|
}
|
|
5527
|
+
function unwrapCodexMcpResult(result) {
|
|
5528
|
+
if (result == null) return void 0;
|
|
5529
|
+
if (typeof result === "string") return result;
|
|
5530
|
+
if (typeof result !== "object") return String(result);
|
|
5531
|
+
const rec = result;
|
|
5532
|
+
if (Array.isArray(rec.content)) {
|
|
5533
|
+
const texts = [];
|
|
5534
|
+
for (const item of rec.content) {
|
|
5535
|
+
if (!item || typeof item !== "object") continue;
|
|
5536
|
+
const text = item.text;
|
|
5537
|
+
if (typeof text === "string") texts.push(text);
|
|
5538
|
+
}
|
|
5539
|
+
if (texts.length) return texts.join("\n");
|
|
5540
|
+
}
|
|
5541
|
+
try {
|
|
5542
|
+
return JSON.stringify(result);
|
|
5543
|
+
} catch {
|
|
5544
|
+
return String(result);
|
|
5545
|
+
}
|
|
5546
|
+
}
|
|
5547
|
+
function asRecord(value) {
|
|
5548
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
5549
|
+
return value;
|
|
5550
|
+
}
|
|
5551
|
+
return void 0;
|
|
5552
|
+
}
|
|
5471
5553
|
var import_node_fs12, import_node_os7, import_node_path12, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
5472
5554
|
var init_codex = __esm({
|
|
5473
5555
|
"src/agents/codex.ts"() {
|
|
@@ -5580,15 +5662,49 @@ var init_codex = __esm({
|
|
|
5580
5662
|
}
|
|
5581
5663
|
if (typeof obj.item === "object" && obj.item !== null) {
|
|
5582
5664
|
const item = obj.item;
|
|
5583
|
-
|
|
5665
|
+
const itemType = item.type ?? item.item_type;
|
|
5666
|
+
if (itemType === "error") {
|
|
5584
5667
|
const detail = item.message?.trim() || extractJsonErrorMessage(obj) || "Codex item error";
|
|
5585
5668
|
return { type: "stderr", data: detail };
|
|
5586
5669
|
}
|
|
5587
|
-
if (
|
|
5670
|
+
if (itemType === "agent_message" && item.text) {
|
|
5588
5671
|
return { type: "stdout", data: item.text };
|
|
5589
5672
|
}
|
|
5673
|
+
if (itemType === "mcp_tool_call" && item.id && item.server && item.tool) {
|
|
5674
|
+
const name = `mcp__${item.server}__${item.tool}`;
|
|
5675
|
+
const input = asRecord(item.arguments);
|
|
5676
|
+
const events = [
|
|
5677
|
+
{ type: "tool_use", id: item.id, name, input }
|
|
5678
|
+
];
|
|
5679
|
+
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
5680
|
+
if (finished) {
|
|
5681
|
+
const errMsg = item.error && typeof item.error.message === "string" ? item.error.message : void 0;
|
|
5682
|
+
events.push({
|
|
5683
|
+
type: "tool_result",
|
|
5684
|
+
id: item.id,
|
|
5685
|
+
content: unwrapCodexMcpResult(item.result) ?? errMsg,
|
|
5686
|
+
isError: item.status === "failed" || Boolean(errMsg)
|
|
5687
|
+
});
|
|
5688
|
+
}
|
|
5689
|
+
return events.length === 1 ? events[0] : events;
|
|
5690
|
+
}
|
|
5691
|
+
if (itemType === "command_execution" && item.id) {
|
|
5692
|
+
const input = item.command ? { command: item.command } : void 0;
|
|
5693
|
+
const events = [
|
|
5694
|
+
{ type: "tool_use", id: item.id, name: "Bash", input }
|
|
5695
|
+
];
|
|
5696
|
+
if (type === "item.completed" || item.status === "completed" || item.status === "failed") {
|
|
5697
|
+
events.push({
|
|
5698
|
+
type: "tool_result",
|
|
5699
|
+
id: item.id,
|
|
5700
|
+
content: item.aggregated_output,
|
|
5701
|
+
isError: item.status === "failed"
|
|
5702
|
+
});
|
|
5703
|
+
}
|
|
5704
|
+
return events.length === 1 ? events[0] : events;
|
|
5705
|
+
}
|
|
5590
5706
|
if (item.status === "failed") {
|
|
5591
|
-
const detail = item.message?.trim() || extractJsonErrorMessage(item) || `Codex ${
|
|
5707
|
+
const detail = item.message?.trim() || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
|
|
5592
5708
|
return { type: "stderr", data: detail };
|
|
5593
5709
|
}
|
|
5594
5710
|
}
|
|
@@ -5674,6 +5790,75 @@ function usageFromCursor(usage) {
|
|
|
5674
5790
|
cacheWriteTokens: usage.cacheWriteTokens ? Number(usage.cacheWriteTokens) : void 0
|
|
5675
5791
|
};
|
|
5676
5792
|
}
|
|
5793
|
+
function asRecord2(value) {
|
|
5794
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
5795
|
+
return value;
|
|
5796
|
+
}
|
|
5797
|
+
return void 0;
|
|
5798
|
+
}
|
|
5799
|
+
function normalizeCursorToolCall(name, args) {
|
|
5800
|
+
const raw = asRecord2(args);
|
|
5801
|
+
const toolName = typeof raw?.toolName === "string" && raw.toolName.trim() ? raw.toolName.trim() : null;
|
|
5802
|
+
const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord2(raw?.args) != null);
|
|
5803
|
+
if (looksLikeMcp && toolName) {
|
|
5804
|
+
const providerRaw = typeof raw.providerIdentifier === "string" && raw.providerIdentifier.trim() ? raw.providerIdentifier.trim() : "sideboard";
|
|
5805
|
+
const provider = providerRaw.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
5806
|
+
const nested = asRecord2(raw.args);
|
|
5807
|
+
return {
|
|
5808
|
+
name: `mcp__${provider}__${toolName}`,
|
|
5809
|
+
input: nested ?? { toolName }
|
|
5810
|
+
};
|
|
5811
|
+
}
|
|
5812
|
+
return { name, input: raw };
|
|
5813
|
+
}
|
|
5814
|
+
function unwrapCursorToolResult(result) {
|
|
5815
|
+
if (result == null) return void 0;
|
|
5816
|
+
if (typeof result === "string") return result;
|
|
5817
|
+
const rec = asRecord2(result);
|
|
5818
|
+
if (!rec) {
|
|
5819
|
+
try {
|
|
5820
|
+
return JSON.stringify(result);
|
|
5821
|
+
} catch {
|
|
5822
|
+
return String(result);
|
|
5823
|
+
}
|
|
5824
|
+
}
|
|
5825
|
+
const collectTexts = (items) => {
|
|
5826
|
+
const texts = [];
|
|
5827
|
+
for (const item of items) {
|
|
5828
|
+
const row = asRecord2(item);
|
|
5829
|
+
if (!row) continue;
|
|
5830
|
+
if (typeof row.text === "string") {
|
|
5831
|
+
texts.push(row.text);
|
|
5832
|
+
continue;
|
|
5833
|
+
}
|
|
5834
|
+
const nested = asRecord2(row.text);
|
|
5835
|
+
if (typeof nested?.text === "string") texts.push(nested.text);
|
|
5836
|
+
}
|
|
5837
|
+
return texts;
|
|
5838
|
+
};
|
|
5839
|
+
const value = asRecord2(rec.value);
|
|
5840
|
+
if (value && Array.isArray(value.content)) {
|
|
5841
|
+
const texts = collectTexts(value.content);
|
|
5842
|
+
if (texts.length) return texts.join("\n");
|
|
5843
|
+
}
|
|
5844
|
+
if (Array.isArray(rec.content)) {
|
|
5845
|
+
const texts = collectTexts(rec.content);
|
|
5846
|
+
if (texts.length) return texts.join("\n");
|
|
5847
|
+
}
|
|
5848
|
+
try {
|
|
5849
|
+
return JSON.stringify(result);
|
|
5850
|
+
} catch {
|
|
5851
|
+
return String(result);
|
|
5852
|
+
}
|
|
5853
|
+
}
|
|
5854
|
+
function cursorToolResultIsError(status, result) {
|
|
5855
|
+
if (status === "error") return true;
|
|
5856
|
+
const rec = asRecord2(result);
|
|
5857
|
+
if (!rec) return false;
|
|
5858
|
+
if (rec.status === "error") return true;
|
|
5859
|
+
const value = asRecord2(rec.value);
|
|
5860
|
+
return value?.isError === true;
|
|
5861
|
+
}
|
|
5677
5862
|
function cursorSdkMessageToEvents(msg) {
|
|
5678
5863
|
if (!msg?.type) return [];
|
|
5679
5864
|
if (msg.type === "system" && msg.agent_id) {
|
|
@@ -5688,35 +5873,42 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
5688
5873
|
if (block?.type === "text" && block.text) {
|
|
5689
5874
|
out.push({ type: "stdout", data: block.text });
|
|
5690
5875
|
} else if (block?.type === "tool_use" && block.id && block.name) {
|
|
5876
|
+
const normalized = normalizeCursorToolCall(block.name, block.input);
|
|
5691
5877
|
out.push({
|
|
5692
5878
|
type: "tool_use",
|
|
5693
5879
|
id: block.id,
|
|
5694
|
-
name:
|
|
5695
|
-
input:
|
|
5880
|
+
name: normalized.name,
|
|
5881
|
+
input: normalized.input
|
|
5696
5882
|
});
|
|
5697
5883
|
}
|
|
5698
5884
|
}
|
|
5699
5885
|
return out;
|
|
5700
5886
|
}
|
|
5701
5887
|
if (msg.type === "tool_call" && msg.call_id && msg.name) {
|
|
5888
|
+
const normalized = normalizeCursorToolCall(msg.name, msg.args);
|
|
5702
5889
|
if (msg.status === "running") {
|
|
5703
5890
|
return [
|
|
5704
5891
|
{
|
|
5705
5892
|
type: "tool_use",
|
|
5706
5893
|
id: msg.call_id,
|
|
5707
|
-
name:
|
|
5708
|
-
input:
|
|
5894
|
+
name: normalized.name,
|
|
5895
|
+
input: normalized.input
|
|
5709
5896
|
}
|
|
5710
5897
|
];
|
|
5711
5898
|
}
|
|
5712
5899
|
if (msg.status === "completed" || msg.status === "error") {
|
|
5713
|
-
const content = typeof msg.result === "string" ? msg.result : msg.result != null ? JSON.stringify(msg.result) : void 0;
|
|
5714
5900
|
return [
|
|
5901
|
+
{
|
|
5902
|
+
type: "tool_use",
|
|
5903
|
+
id: msg.call_id,
|
|
5904
|
+
name: normalized.name,
|
|
5905
|
+
input: normalized.input
|
|
5906
|
+
},
|
|
5715
5907
|
{
|
|
5716
5908
|
type: "tool_result",
|
|
5717
5909
|
id: msg.call_id,
|
|
5718
|
-
content,
|
|
5719
|
-
isError: msg.status
|
|
5910
|
+
content: unwrapCursorToolResult(msg.result),
|
|
5911
|
+
isError: cursorToolResultIsError(msg.status, msg.result)
|
|
5720
5912
|
}
|
|
5721
5913
|
];
|
|
5722
5914
|
}
|
|
@@ -6086,17 +6278,31 @@ var init_opencode = __esm({
|
|
|
6086
6278
|
return { type: "stderr", data: detail };
|
|
6087
6279
|
}
|
|
6088
6280
|
const sid = typeof obj.sessionID === "string" && obj.sessionID || typeof obj.sessionId === "string" && obj.sessionId || typeof obj.session_id === "string" && obj.session_id;
|
|
6089
|
-
if (sid
|
|
6281
|
+
if (sid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
|
|
6282
|
+
return { type: "session_id", data: sid };
|
|
6283
|
+
}
|
|
6090
6284
|
if (obj.type === "text") {
|
|
6091
6285
|
const text = obj.part?.text ?? obj.text;
|
|
6092
6286
|
if (text) return { type: "stdout", data: text };
|
|
6093
6287
|
}
|
|
6094
6288
|
if (obj.type === "tool_use") {
|
|
6095
6289
|
const part = obj.part;
|
|
6096
|
-
const id = part?.id ?? obj.id ?? `tool-${Date.now()}`;
|
|
6097
|
-
const name = part?.
|
|
6098
|
-
const
|
|
6099
|
-
|
|
6290
|
+
const id = part?.callID ?? part?.id ?? obj.id ?? `tool-${Date.now()}`;
|
|
6291
|
+
const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
|
|
6292
|
+
const state = part?.state;
|
|
6293
|
+
const input = (state?.input && typeof state.input === "object" ? state.input : void 0) ?? part?.input ?? obj.input;
|
|
6294
|
+
const events = [{ type: "tool_use", id, name, input }];
|
|
6295
|
+
const output = state?.output;
|
|
6296
|
+
if (output != null || state?.status === "completed" || state?.status === "error") {
|
|
6297
|
+
const content = typeof output === "string" ? output : output != null ? JSON.stringify(output) : formatUnknownDetail(state?.error) || void 0;
|
|
6298
|
+
events.push({
|
|
6299
|
+
type: "tool_result",
|
|
6300
|
+
id,
|
|
6301
|
+
content,
|
|
6302
|
+
isError: state?.status === "error" || state?.status === "failed"
|
|
6303
|
+
});
|
|
6304
|
+
}
|
|
6305
|
+
return events.length === 1 ? events[0] : events;
|
|
6100
6306
|
}
|
|
6101
6307
|
if (obj.type === "tool_result") {
|
|
6102
6308
|
const part = obj.part;
|
|
@@ -6124,6 +6330,7 @@ var init_opencode = __esm({
|
|
|
6124
6330
|
}
|
|
6125
6331
|
},
|
|
6126
6332
|
async resolveSessionId(worktreePath, cached) {
|
|
6333
|
+
const cachedId = cached?.trim() || null;
|
|
6127
6334
|
const listed = await run(
|
|
6128
6335
|
"opencode",
|
|
6129
6336
|
["session", "list", "--format", "json"],
|
|
@@ -6135,15 +6342,21 @@ var init_opencode = __esm({
|
|
|
6135
6342
|
if (Array.isArray(sessions) && sessions.length > 0) {
|
|
6136
6343
|
const norm = (p) => p.replace(/\/+$/, "");
|
|
6137
6344
|
const wt = norm(worktreePath);
|
|
6138
|
-
const
|
|
6345
|
+
const forWorktree = sessions.filter(
|
|
6139
6346
|
(s) => s.directory && norm(s.directory) === wt || s.path && norm(s.path) === wt
|
|
6140
6347
|
);
|
|
6141
|
-
if (
|
|
6348
|
+
if (cachedId && forWorktree.some((s) => s.id === cachedId)) {
|
|
6349
|
+
return cachedId;
|
|
6350
|
+
}
|
|
6351
|
+
if (cachedId && sessions.some((s) => s.id === cachedId)) {
|
|
6352
|
+
return cachedId;
|
|
6353
|
+
}
|
|
6354
|
+
return null;
|
|
6142
6355
|
}
|
|
6143
6356
|
} catch {
|
|
6144
6357
|
}
|
|
6145
6358
|
}
|
|
6146
|
-
return
|
|
6359
|
+
return cachedId;
|
|
6147
6360
|
},
|
|
6148
6361
|
async buildAttach(thread) {
|
|
6149
6362
|
const sessionId = await this.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
@@ -6642,7 +6855,7 @@ var init_agents = __esm({
|
|
|
6642
6855
|
});
|
|
6643
6856
|
|
|
6644
6857
|
// src/plan/plan-present.ts
|
|
6645
|
-
function
|
|
6858
|
+
function asRecord4(v) {
|
|
6646
6859
|
return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
6647
6860
|
}
|
|
6648
6861
|
function isPresentPlanToolName(name) {
|
|
@@ -6654,7 +6867,7 @@ function extractPresentedPlan(parts) {
|
|
|
6654
6867
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
6655
6868
|
const p = parts[i];
|
|
6656
6869
|
if (p.type !== "tool" || !isPresentPlanToolName(p.name)) continue;
|
|
6657
|
-
const input =
|
|
6870
|
+
const input = asRecord4(p.input) ?? {};
|
|
6658
6871
|
const content = typeof input.content === "string" ? input.content : typeof input.plan === "string" ? input.plan : typeof input.markdown === "string" ? input.markdown : "";
|
|
6659
6872
|
if (!content.trim()) continue;
|
|
6660
6873
|
const title = typeof input.title === "string" && input.title.trim() ? input.title.trim() : "Plan";
|
|
@@ -7136,6 +7349,7 @@ __export(index_exports, {
|
|
|
7136
7349
|
resolveFilesToCopy: () => resolveFilesToCopy,
|
|
7137
7350
|
resolveGhAuthToken: () => resolveGhAuthToken,
|
|
7138
7351
|
resolveGithubRepoSlug: () => resolveGithubRepoSlug,
|
|
7352
|
+
resolveNewThreadOptions: () => resolveNewThreadOptions,
|
|
7139
7353
|
resolvePlanMarkdown: () => resolvePlanMarkdown,
|
|
7140
7354
|
resolvePrSelector: () => resolvePrSelector,
|
|
7141
7355
|
resolveQuotaFallbackAgent: () => resolveQuotaFallbackAgent,
|
|
@@ -7414,7 +7628,7 @@ init_agents();
|
|
|
7414
7628
|
init_orchestrator_capable();
|
|
7415
7629
|
|
|
7416
7630
|
// src/agents/message-parts.ts
|
|
7417
|
-
function
|
|
7631
|
+
function asRecord3(input) {
|
|
7418
7632
|
if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
7419
7633
|
return input;
|
|
7420
7634
|
}
|
|
@@ -7549,7 +7763,7 @@ function applyAgentEvent(parts, event) {
|
|
|
7549
7763
|
return next;
|
|
7550
7764
|
}
|
|
7551
7765
|
if (event.type === "tool_use") {
|
|
7552
|
-
const input =
|
|
7766
|
+
const input = asRecord3(event.input);
|
|
7553
7767
|
const diff = diffFromInput(input);
|
|
7554
7768
|
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
7555
7769
|
if (existing >= 0) {
|
|
@@ -7583,9 +7797,25 @@ function applyAgentEvent(parts, event) {
|
|
|
7583
7797
|
];
|
|
7584
7798
|
}
|
|
7585
7799
|
if (event.type === "tool_result") {
|
|
7586
|
-
const
|
|
7587
|
-
|
|
7588
|
-
|
|
7800
|
+
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
7801
|
+
const fromResult = parseDiffStat(event.content);
|
|
7802
|
+
if (existing < 0) {
|
|
7803
|
+
return [
|
|
7804
|
+
...parts,
|
|
7805
|
+
{
|
|
7806
|
+
type: "tool",
|
|
7807
|
+
id: event.id,
|
|
7808
|
+
name: "tool",
|
|
7809
|
+
description: "tool",
|
|
7810
|
+
status: event.isError ? "error" : "done",
|
|
7811
|
+
result: event.content,
|
|
7812
|
+
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
7813
|
+
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
7814
|
+
}
|
|
7815
|
+
];
|
|
7816
|
+
}
|
|
7817
|
+
return parts.map((p, i) => {
|
|
7818
|
+
if (i !== existing || p.type !== "tool") return p;
|
|
7589
7819
|
return {
|
|
7590
7820
|
...p,
|
|
7591
7821
|
status: event.isError ? "error" : "done",
|
|
@@ -7594,7 +7824,6 @@ function applyAgentEvent(parts, event) {
|
|
|
7594
7824
|
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
7595
7825
|
};
|
|
7596
7826
|
});
|
|
7597
|
-
return next;
|
|
7598
7827
|
}
|
|
7599
7828
|
return parts;
|
|
7600
7829
|
}
|
|
@@ -9862,10 +10091,17 @@ async function confirmLand(thread, opts) {
|
|
|
9862
10091
|
// src/threads/create.ts
|
|
9863
10092
|
var import_node_fs20 = require("fs");
|
|
9864
10093
|
init_worktree();
|
|
10094
|
+
init_app_settings();
|
|
9865
10095
|
init_thread_store();
|
|
9866
10096
|
init_workspaces();
|
|
9867
10097
|
async function createThread(input, _onSetupLine) {
|
|
9868
|
-
|
|
10098
|
+
const resolved = resolveNewThreadOptions({
|
|
10099
|
+
agent: input.agent,
|
|
10100
|
+
model: input.model,
|
|
10101
|
+
effort: input.effort,
|
|
10102
|
+
fast: input.fast
|
|
10103
|
+
});
|
|
10104
|
+
await requireAgent(resolved.agent);
|
|
9869
10105
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
9870
10106
|
if (!(0, import_node_fs20.existsSync)(repoPath)) {
|
|
9871
10107
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
@@ -9908,11 +10144,11 @@ async function createThread(input, _onSetupLine) {
|
|
|
9908
10144
|
branchName,
|
|
9909
10145
|
worktreePath,
|
|
9910
10146
|
repoPath,
|
|
9911
|
-
agent:
|
|
10147
|
+
agent: resolved.agent,
|
|
9912
10148
|
autonomy: input.autonomy ?? "default",
|
|
9913
|
-
model:
|
|
9914
|
-
effort:
|
|
9915
|
-
fast:
|
|
10149
|
+
model: resolved.model,
|
|
10150
|
+
effort: resolved.effort,
|
|
10151
|
+
fast: resolved.fast,
|
|
9916
10152
|
planMode: Boolean(input.planMode),
|
|
9917
10153
|
attachments: input.attachments ?? [],
|
|
9918
10154
|
sourceIsFork,
|
|
@@ -11570,21 +11806,30 @@ var Orchestrator = class {
|
|
|
11570
11806
|
return findThreadByRef(idOrRef) ?? readThread(idOrRef);
|
|
11571
11807
|
}
|
|
11572
11808
|
async createThread(input) {
|
|
11573
|
-
|
|
11809
|
+
const thread = await createThread(input);
|
|
11574
11810
|
this.emit({ type: "status_changed", threadId: thread.id, status: thread.status });
|
|
11575
|
-
|
|
11811
|
+
void this.finishCreateThread(thread.id, input.prompt?.trim() || void 0);
|
|
11812
|
+
return thread;
|
|
11813
|
+
}
|
|
11814
|
+
async finishCreateThread(threadId, prompt) {
|
|
11815
|
+
await this.runSetupAfterCreate(threadId);
|
|
11576
11816
|
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
11577
11817
|
if (autoRunAfterSetupEnabled2()) {
|
|
11578
11818
|
try {
|
|
11579
|
-
await this.startDev(
|
|
11819
|
+
await this.startDev(threadId);
|
|
11580
11820
|
} catch {
|
|
11581
11821
|
}
|
|
11582
11822
|
}
|
|
11583
|
-
const prompt = input.prompt?.trim();
|
|
11584
11823
|
if (prompt) {
|
|
11585
|
-
|
|
11824
|
+
try {
|
|
11825
|
+
await this.send(threadId, prompt);
|
|
11826
|
+
} catch (err) {
|
|
11827
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
11828
|
+
updateThread(threadId, {
|
|
11829
|
+
lastError: `First prompt failed: ${message}`
|
|
11830
|
+
});
|
|
11831
|
+
}
|
|
11586
11832
|
}
|
|
11587
|
-
return thread;
|
|
11588
11833
|
}
|
|
11589
11834
|
/** Run workspace setup after a new worktree is created (no-op if none configured). */
|
|
11590
11835
|
async runSetupAfterCreate(threadId) {
|
|
@@ -11600,7 +11845,7 @@ var Orchestrator = class {
|
|
|
11600
11845
|
}
|
|
11601
11846
|
}
|
|
11602
11847
|
listWorkspaces() {
|
|
11603
|
-
const fromThreads = listThreads({ includeArchived:
|
|
11848
|
+
const fromThreads = listThreads({ includeArchived: true }).map((t) => t.repoPath);
|
|
11604
11849
|
return syncWorkspacesFromThreads(fromThreads);
|
|
11605
11850
|
}
|
|
11606
11851
|
async addWorkspace(repoPath) {
|
|
@@ -11930,8 +12175,73 @@ var Orchestrator = class {
|
|
|
11930
12175
|
}
|
|
11931
12176
|
}
|
|
11932
12177
|
}
|
|
11933
|
-
|
|
11934
|
-
|
|
12178
|
+
let lastStderr = summarizeTurnStderr(stderrTail);
|
|
12179
|
+
let detail = lastStderr || (exitCode !== 0 ? fallbackTurnFailDetail(assistantText) : "");
|
|
12180
|
+
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") {
|
|
12181
|
+
updateThread(threadId, { sessionId: null });
|
|
12182
|
+
pushTurnStderr(
|
|
12183
|
+
stderrTail,
|
|
12184
|
+
"Agent session missing \u2014 starting a fresh session"
|
|
12185
|
+
);
|
|
12186
|
+
this.emit({
|
|
12187
|
+
type: "turn_output",
|
|
12188
|
+
threadId,
|
|
12189
|
+
event: {
|
|
12190
|
+
type: "stderr",
|
|
12191
|
+
data: "Agent session missing \u2014 starting a fresh session"
|
|
12192
|
+
}
|
|
12193
|
+
});
|
|
12194
|
+
const retryThread = this.requireThread(threadId);
|
|
12195
|
+
const prior = retryThread.messages.slice(0, -1);
|
|
12196
|
+
const retrySeed = buildSessionSeed(prior);
|
|
12197
|
+
const retryInstructions = retryThread.agent === "claude" ? null : formatAgentInstructions(
|
|
12198
|
+
loadAgentInstructions(retryThread.worktreePath, retryThread.agent)
|
|
12199
|
+
);
|
|
12200
|
+
const retryPrefix = [
|
|
12201
|
+
coordinatorDirective,
|
|
12202
|
+
worktreeDirective,
|
|
12203
|
+
artifactDirective,
|
|
12204
|
+
renameBranchDirective,
|
|
12205
|
+
retryInstructions,
|
|
12206
|
+
retrySeed
|
|
12207
|
+
].filter(Boolean).join("\n\n---\n\n");
|
|
12208
|
+
const retryHandle = await spawnAgentTurn(
|
|
12209
|
+
retryThread,
|
|
12210
|
+
{ cachedPrefix: retryPrefix, prompt: agentPrompt },
|
|
12211
|
+
(event) => {
|
|
12212
|
+
this.emit({ type: "turn_output", threadId, event });
|
|
12213
|
+
if (event.type === "session_id") {
|
|
12214
|
+
updateThread(threadId, { sessionId: event.data });
|
|
12215
|
+
}
|
|
12216
|
+
if (event.type === "stderr" && typeof event.data === "string") {
|
|
12217
|
+
pushTurnStderr(stderrTail, event.data);
|
|
12218
|
+
}
|
|
12219
|
+
}
|
|
12220
|
+
);
|
|
12221
|
+
this.activeTurns.set(threadId, retryHandle);
|
|
12222
|
+
if (typeof retryHandle.pid === "number" && retryHandle.pid > 0) {
|
|
12223
|
+
updateThread(threadId, { agentPid: retryHandle.pid });
|
|
12224
|
+
}
|
|
12225
|
+
this.processes.set(`${threadId}:agent`, {
|
|
12226
|
+
kind: "agent",
|
|
12227
|
+
pid: retryHandle.pid,
|
|
12228
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12229
|
+
kill: retryHandle.kill
|
|
12230
|
+
});
|
|
12231
|
+
if (this.stoppedTurns.has(threadId)) {
|
|
12232
|
+
retryHandle.kill();
|
|
12233
|
+
}
|
|
12234
|
+
const retryResult = await retryHandle.done;
|
|
12235
|
+
if (retryResult.sessionId) {
|
|
12236
|
+
updateThread(threadId, { sessionId: retryResult.sessionId });
|
|
12237
|
+
}
|
|
12238
|
+
assistantText = retryResult.assistantText.trim();
|
|
12239
|
+
parts = retryResult.parts;
|
|
12240
|
+
usage = retryResult.usage ?? void 0;
|
|
12241
|
+
exitCode = retryResult.exitCode;
|
|
12242
|
+
lastStderr = summarizeTurnStderr(stderrTail);
|
|
12243
|
+
detail = lastStderr || (exitCode !== 0 ? fallbackTurnFailDetail(assistantText) : "");
|
|
12244
|
+
}
|
|
11935
12245
|
let chatText = assistantText;
|
|
11936
12246
|
if (exitCode !== 0 && !chatText && looksLikeAgentFailureMessage(detail)) {
|
|
11937
12247
|
chatText = humanizeAgentFailDetail(detail);
|
|
@@ -12635,7 +12945,15 @@ var Orchestrator = class {
|
|
|
12635
12945
|
}
|
|
12636
12946
|
await removeWorktree(thread.repoPath, thread.worktreePath);
|
|
12637
12947
|
}
|
|
12638
|
-
|
|
12948
|
+
const archived = setStatus(thread.id, "archived");
|
|
12949
|
+
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
12950
|
+
try {
|
|
12951
|
+
const { ensureWorkspace: ensureWorkspace2 } = await Promise.resolve().then(() => (init_workspaces(), workspaces_exports));
|
|
12952
|
+
await ensureWorkspace2(thread.repoPath);
|
|
12953
|
+
} catch {
|
|
12954
|
+
}
|
|
12955
|
+
}
|
|
12956
|
+
return archived;
|
|
12639
12957
|
}
|
|
12640
12958
|
async purge(threadRef, opts) {
|
|
12641
12959
|
const thread = this.requireThread(threadRef);
|
|
@@ -12780,7 +13098,7 @@ async function startOrchestration(opts) {
|
|
|
12780
13098
|
init_workspace_scratch();
|
|
12781
13099
|
|
|
12782
13100
|
// src/plan/ask-user.ts
|
|
12783
|
-
function
|
|
13101
|
+
function asRecord5(v) {
|
|
12784
13102
|
return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
12785
13103
|
}
|
|
12786
13104
|
function parseOptions(raw) {
|
|
@@ -12791,7 +13109,7 @@ function parseOptions(raw) {
|
|
|
12791
13109
|
out.push({ label: item.trim() });
|
|
12792
13110
|
continue;
|
|
12793
13111
|
}
|
|
12794
|
-
const o =
|
|
13112
|
+
const o = asRecord5(item);
|
|
12795
13113
|
if (!o) continue;
|
|
12796
13114
|
const label = typeof o.label === "string" ? o.label.trim() : typeof o.text === "string" ? o.text.trim() : typeof o.title === "string" ? o.title.trim() : "";
|
|
12797
13115
|
if (!label) continue;
|
|
@@ -12801,7 +13119,7 @@ function parseOptions(raw) {
|
|
|
12801
13119
|
return out;
|
|
12802
13120
|
}
|
|
12803
13121
|
function parseOneQuestion(raw) {
|
|
12804
|
-
const o =
|
|
13122
|
+
const o = asRecord5(raw);
|
|
12805
13123
|
if (!o) return null;
|
|
12806
13124
|
const question = typeof o.question === "string" ? o.question.trim() : typeof o.text === "string" ? o.text.trim() : typeof o.prompt === "string" ? o.prompt.trim() : "";
|
|
12807
13125
|
if (!question) return null;
|
|
@@ -12812,7 +13130,7 @@ function parseOneQuestion(raw) {
|
|
|
12812
13130
|
return { question, header, multiSelect, options };
|
|
12813
13131
|
}
|
|
12814
13132
|
function parsePlanQuestionsInput(input) {
|
|
12815
|
-
const root =
|
|
13133
|
+
const root = asRecord5(input);
|
|
12816
13134
|
if (!root) return [];
|
|
12817
13135
|
const list = Array.isArray(root.questions) ? root.questions : Array.isArray(root.question) ? root.question : root.question || root.prompt ? [root] : [];
|
|
12818
13136
|
const out = [];
|
|
@@ -13104,13 +13422,19 @@ async function startMcpServer() {
|
|
|
13104
13422
|
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
13105
13423
|
}
|
|
13106
13424
|
);
|
|
13425
|
+
const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
13426
|
+
const accountDefaults = resolveThreadDefaults2();
|
|
13427
|
+
const accountDefaultsHint = `Account defaults: agent=${accountDefaults.agent}, model=${accountDefaults.model?.trim() || "Auto"}, effort=${accountDefaults.effort}`;
|
|
13107
13428
|
server.tool(
|
|
13108
13429
|
"create_thread",
|
|
13109
|
-
|
|
13430
|
+
`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.`,
|
|
13110
13431
|
{
|
|
13111
13432
|
sourceType: import_zod.z.enum(["branch", "pr", "ticket"]),
|
|
13112
13433
|
sourceRef: import_zod.z.string(),
|
|
13113
|
-
agent: import_zod.z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]),
|
|
13434
|
+
agent: import_zod.z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]).optional().describe(`Omit to use Account default agent (${accountDefaults.agent})`),
|
|
13435
|
+
model: import_zod.z.string().nullable().optional().describe(
|
|
13436
|
+
`Usually omit to use Account default model (${accountDefaults.model?.trim() || "Auto"}). Pass null only to force Auto / agent-default.`
|
|
13437
|
+
),
|
|
13114
13438
|
repoPath: import_zod.z.string(),
|
|
13115
13439
|
title: import_zod.z.string().optional(),
|
|
13116
13440
|
parentThreadId: import_zod.z.string().optional()
|
|
@@ -13130,10 +13454,17 @@ async function startMcpServer() {
|
|
|
13130
13454
|
};
|
|
13131
13455
|
}
|
|
13132
13456
|
}
|
|
13457
|
+
const opts = resolveNewThreadOptions2({
|
|
13458
|
+
agent: args.agent,
|
|
13459
|
+
model: args.model
|
|
13460
|
+
});
|
|
13133
13461
|
const thread = await orch.createThread({
|
|
13134
13462
|
sourceType: args.sourceType,
|
|
13135
13463
|
sourceRef: args.sourceRef,
|
|
13136
|
-
agent:
|
|
13464
|
+
agent: opts.agent,
|
|
13465
|
+
model: opts.model,
|
|
13466
|
+
effort: opts.effort,
|
|
13467
|
+
fast: opts.fast,
|
|
13137
13468
|
repoPath: args.repoPath,
|
|
13138
13469
|
title: args.title,
|
|
13139
13470
|
parentThreadId: args.parentThreadId ?? null
|
|
@@ -13147,6 +13478,8 @@ async function startMcpServer() {
|
|
|
13147
13478
|
title: thread.title,
|
|
13148
13479
|
branchName: thread.branchName,
|
|
13149
13480
|
worktreePath: thread.worktreePath,
|
|
13481
|
+
agent: thread.agent,
|
|
13482
|
+
model: thread.model,
|
|
13150
13483
|
status: thread.status,
|
|
13151
13484
|
link: `sideboard://thread/${thread.id}`
|
|
13152
13485
|
})
|
|
@@ -14421,6 +14754,7 @@ init_injected_mcp();
|
|
|
14421
14754
|
resolveFilesToCopy,
|
|
14422
14755
|
resolveGhAuthToken,
|
|
14423
14756
|
resolveGithubRepoSlug,
|
|
14757
|
+
resolveNewThreadOptions,
|
|
14424
14758
|
resolvePlanMarkdown,
|
|
14425
14759
|
resolvePrSelector,
|
|
14426
14760
|
resolveQuotaFallbackAgent,
|