@sideboard-ai/core 0.1.53 → 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.
Files changed (30) hide show
  1. package/dist/agents/cursor-runner.cjs +83 -7
  2. package/dist/agents/cursor-runner.js +1 -1
  3. package/dist/{agents-KYACODJ3.js → agents-2YYWW723.js} +3 -3
  4. package/dist/{agents-KP7UJEHJ.js → agents-AQFEFKBL.js} +2 -2
  5. package/dist/{app-settings-LZP632KI.js → app-settings-2LQNRTBE.js} +3 -1
  6. package/dist/{app-settings-7XVDQJ7F.js → app-settings-73DI4B6T.js} +3 -1
  7. package/dist/{chunk-VG22SETP.js → chunk-3WJAUKIL.js} +83 -7
  8. package/dist/{chunk-GNML24AW.js → chunk-5DMYULLC.js} +1 -1
  9. package/dist/{chunk-A6HVEMIB.js → chunk-7F454EE2.js} +86 -11
  10. package/dist/{chunk-BZST4HMJ.js → chunk-C3J4GDW4.js} +172 -21
  11. package/dist/{chunk-HBJSHRY2.js → chunk-C4BCC5X5.js} +17 -1
  12. package/dist/{chunk-T5QQVXK3.js → chunk-DIOF73S2.js} +17 -1
  13. package/dist/{chunk-UEAHMGHW.js → chunk-DQJ5D42H.js} +16 -2
  14. package/dist/{chunk-YOWIYAVA.js → chunk-EBWEKG52.js} +36 -11
  15. package/dist/{chunk-XX5BB7NV.js → chunk-S42XDFKF.js} +36 -11
  16. package/dist/{chunk-LRLKJM3O.js → chunk-UA5NDAHL.js} +16 -2
  17. package/dist/{chunk-YDXQ72MD.js → chunk-V2DUTUNC.js} +1 -1
  18. package/dist/{coordinator-prompt-S6JZD5EF.js → coordinator-prompt-ICF36NUQ.js} +2 -1
  19. package/dist/{coordinator-prompt-6FXVTSFN.js → coordinator-prompt-RBKUNRPR.js} +2 -1
  20. package/dist/{global-workspace-EV4G2WMQ.js → global-workspace-667XLBW6.js} +3 -2
  21. package/dist/{global-workspace-MSX2K27Y.js → global-workspace-S7VLWPWG.js} +3 -2
  22. package/dist/index.cjs +298 -50
  23. package/dist/index.d.cts +24 -2
  24. package/dist/index.d.ts +24 -2
  25. package/dist/index.js +81 -35
  26. package/dist/mcp/run-stdio.cjs +292 -46
  27. package/dist/mcp/run-stdio.js +81 -36
  28. package/dist/{workspaces-AYTBR6KQ.js → workspaces-FPJJXXAE.js} +4 -3
  29. package/dist/{workspaces-3RQQZQRO.js → workspaces-LYIDE2VR.js} +4 -3
  30. 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
- return settings.brightsy.cloudConnectAgent ?? "claude";
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 leave model unset = Auto",
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 agent = assertOrchestratorCapableAgent(opts.agent);
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: opts.model ?? null,
3717
- effort: opts.effort ?? "high",
3718
- fast: Boolean(opts.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
- return updateThread(existing.id, {
3755
- repoPath: GLOBAL_WORKSPACE_ID,
3756
- worktreePath: globalAgentCwd(),
3757
- branchName: "global"
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__";
@@ -4958,6 +5008,7 @@ function toCodexMcpConfigArgs(servers) {
4958
5008
  args.push("-c", `${prefix}.env.${key}=${JSON.stringify(value)}`);
4959
5009
  }
4960
5010
  }
5011
+ args.push("-c", `${prefix}.default_tools_approval_mode=${JSON.stringify("approve")}`);
4961
5012
  }
4962
5013
  return args;
4963
5014
  }
@@ -5473,6 +5524,32 @@ function codexConfigHasNetworkAccess() {
5473
5524
  }
5474
5525
  return false;
5475
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
+ }
5476
5553
  var import_node_fs12, import_node_os7, import_node_path12, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
5477
5554
  var init_codex = __esm({
5478
5555
  "src/agents/codex.ts"() {
@@ -5585,15 +5662,49 @@ var init_codex = __esm({
5585
5662
  }
5586
5663
  if (typeof obj.item === "object" && obj.item !== null) {
5587
5664
  const item = obj.item;
5588
- if (item.type === "error") {
5665
+ const itemType = item.type ?? item.item_type;
5666
+ if (itemType === "error") {
5589
5667
  const detail = item.message?.trim() || extractJsonErrorMessage(obj) || "Codex item error";
5590
5668
  return { type: "stderr", data: detail };
5591
5669
  }
5592
- if (item.type === "agent_message" && item.text) {
5670
+ if (itemType === "agent_message" && item.text) {
5593
5671
  return { type: "stdout", data: item.text };
5594
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
+ }
5595
5706
  if (item.status === "failed") {
5596
- const detail = item.message?.trim() || extractJsonErrorMessage(item) || `Codex ${item.type ?? "item"} failed`;
5707
+ const detail = item.message?.trim() || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
5597
5708
  return { type: "stderr", data: detail };
5598
5709
  }
5599
5710
  }
@@ -5679,6 +5790,75 @@ function usageFromCursor(usage) {
5679
5790
  cacheWriteTokens: usage.cacheWriteTokens ? Number(usage.cacheWriteTokens) : void 0
5680
5791
  };
5681
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
+ }
5682
5862
  function cursorSdkMessageToEvents(msg) {
5683
5863
  if (!msg?.type) return [];
5684
5864
  if (msg.type === "system" && msg.agent_id) {
@@ -5693,35 +5873,42 @@ function cursorSdkMessageToEvents(msg) {
5693
5873
  if (block?.type === "text" && block.text) {
5694
5874
  out.push({ type: "stdout", data: block.text });
5695
5875
  } else if (block?.type === "tool_use" && block.id && block.name) {
5876
+ const normalized = normalizeCursorToolCall(block.name, block.input);
5696
5877
  out.push({
5697
5878
  type: "tool_use",
5698
5879
  id: block.id,
5699
- name: block.name,
5700
- input: block.input && typeof block.input === "object" ? block.input : void 0
5880
+ name: normalized.name,
5881
+ input: normalized.input
5701
5882
  });
5702
5883
  }
5703
5884
  }
5704
5885
  return out;
5705
5886
  }
5706
5887
  if (msg.type === "tool_call" && msg.call_id && msg.name) {
5888
+ const normalized = normalizeCursorToolCall(msg.name, msg.args);
5707
5889
  if (msg.status === "running") {
5708
5890
  return [
5709
5891
  {
5710
5892
  type: "tool_use",
5711
5893
  id: msg.call_id,
5712
- name: msg.name,
5713
- input: msg.args && typeof msg.args === "object" ? msg.args : void 0
5894
+ name: normalized.name,
5895
+ input: normalized.input
5714
5896
  }
5715
5897
  ];
5716
5898
  }
5717
5899
  if (msg.status === "completed" || msg.status === "error") {
5718
- const content = typeof msg.result === "string" ? msg.result : msg.result != null ? JSON.stringify(msg.result) : void 0;
5719
5900
  return [
5901
+ {
5902
+ type: "tool_use",
5903
+ id: msg.call_id,
5904
+ name: normalized.name,
5905
+ input: normalized.input
5906
+ },
5720
5907
  {
5721
5908
  type: "tool_result",
5722
5909
  id: msg.call_id,
5723
- content,
5724
- isError: msg.status === "error"
5910
+ content: unwrapCursorToolResult(msg.result),
5911
+ isError: cursorToolResultIsError(msg.status, msg.result)
5725
5912
  }
5726
5913
  ];
5727
5914
  }
@@ -6091,17 +6278,31 @@ var init_opencode = __esm({
6091
6278
  return { type: "stderr", data: detail };
6092
6279
  }
6093
6280
  const sid = typeof obj.sessionID === "string" && obj.sessionID || typeof obj.sessionId === "string" && obj.sessionId || typeof obj.session_id === "string" && obj.session_id;
6094
- if (sid) return { type: "session_id", data: sid };
6281
+ if (sid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
6282
+ return { type: "session_id", data: sid };
6283
+ }
6095
6284
  if (obj.type === "text") {
6096
6285
  const text = obj.part?.text ?? obj.text;
6097
6286
  if (text) return { type: "stdout", data: text };
6098
6287
  }
6099
6288
  if (obj.type === "tool_use") {
6100
6289
  const part = obj.part;
6101
- const id = part?.id ?? obj.id ?? `tool-${Date.now()}`;
6102
- const name = part?.name ?? part?.tool ?? obj.name ?? obj.tool ?? "tool";
6103
- const input = part?.input ?? obj.input;
6104
- return { type: "tool_use", id, name, input };
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;
6105
6306
  }
6106
6307
  if (obj.type === "tool_result") {
6107
6308
  const part = obj.part;
@@ -6654,7 +6855,7 @@ var init_agents = __esm({
6654
6855
  });
6655
6856
 
6656
6857
  // src/plan/plan-present.ts
6657
- function asRecord2(v) {
6858
+ function asRecord4(v) {
6658
6859
  return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
6659
6860
  }
6660
6861
  function isPresentPlanToolName(name) {
@@ -6666,7 +6867,7 @@ function extractPresentedPlan(parts) {
6666
6867
  for (let i = parts.length - 1; i >= 0; i--) {
6667
6868
  const p = parts[i];
6668
6869
  if (p.type !== "tool" || !isPresentPlanToolName(p.name)) continue;
6669
- const input = asRecord2(p.input) ?? {};
6870
+ const input = asRecord4(p.input) ?? {};
6670
6871
  const content = typeof input.content === "string" ? input.content : typeof input.plan === "string" ? input.plan : typeof input.markdown === "string" ? input.markdown : "";
6671
6872
  if (!content.trim()) continue;
6672
6873
  const title = typeof input.title === "string" && input.title.trim() ? input.title.trim() : "Plan";
@@ -7148,6 +7349,7 @@ __export(index_exports, {
7148
7349
  resolveFilesToCopy: () => resolveFilesToCopy,
7149
7350
  resolveGhAuthToken: () => resolveGhAuthToken,
7150
7351
  resolveGithubRepoSlug: () => resolveGithubRepoSlug,
7352
+ resolveNewThreadOptions: () => resolveNewThreadOptions,
7151
7353
  resolvePlanMarkdown: () => resolvePlanMarkdown,
7152
7354
  resolvePrSelector: () => resolvePrSelector,
7153
7355
  resolveQuotaFallbackAgent: () => resolveQuotaFallbackAgent,
@@ -7426,7 +7628,7 @@ init_agents();
7426
7628
  init_orchestrator_capable();
7427
7629
 
7428
7630
  // src/agents/message-parts.ts
7429
- function asRecord(input) {
7631
+ function asRecord3(input) {
7430
7632
  if (input && typeof input === "object" && !Array.isArray(input)) {
7431
7633
  return input;
7432
7634
  }
@@ -7561,7 +7763,7 @@ function applyAgentEvent(parts, event) {
7561
7763
  return next;
7562
7764
  }
7563
7765
  if (event.type === "tool_use") {
7564
- const input = asRecord(event.input);
7766
+ const input = asRecord3(event.input);
7565
7767
  const diff = diffFromInput(input);
7566
7768
  const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
7567
7769
  if (existing >= 0) {
@@ -7595,9 +7797,25 @@ function applyAgentEvent(parts, event) {
7595
7797
  ];
7596
7798
  }
7597
7799
  if (event.type === "tool_result") {
7598
- const next = parts.map((p) => {
7599
- if (p.type !== "tool" || p.id !== event.id) return p;
7600
- const fromResult = parseDiffStat(event.content);
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;
7601
7819
  return {
7602
7820
  ...p,
7603
7821
  status: event.isError ? "error" : "done",
@@ -7606,7 +7824,6 @@ function applyAgentEvent(parts, event) {
7606
7824
  ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
7607
7825
  };
7608
7826
  });
7609
- return next;
7610
7827
  }
7611
7828
  return parts;
7612
7829
  }
@@ -9874,10 +10091,17 @@ async function confirmLand(thread, opts) {
9874
10091
  // src/threads/create.ts
9875
10092
  var import_node_fs20 = require("fs");
9876
10093
  init_worktree();
10094
+ init_app_settings();
9877
10095
  init_thread_store();
9878
10096
  init_workspaces();
9879
10097
  async function createThread(input, _onSetupLine) {
9880
- await requireAgent(input.agent);
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);
9881
10105
  const repoPath = await resolveRepoRoot(input.repoPath);
9882
10106
  if (!(0, import_node_fs20.existsSync)(repoPath)) {
9883
10107
  throw new Error(`Repo not found: ${repoPath}`);
@@ -9920,11 +10144,11 @@ async function createThread(input, _onSetupLine) {
9920
10144
  branchName,
9921
10145
  worktreePath,
9922
10146
  repoPath,
9923
- agent: input.agent,
10147
+ agent: resolved.agent,
9924
10148
  autonomy: input.autonomy ?? "default",
9925
- model: input.model ?? null,
9926
- effort: input.effort ?? "high",
9927
- fast: Boolean(input.fast),
10149
+ model: resolved.model,
10150
+ effort: resolved.effort,
10151
+ fast: resolved.fast,
9928
10152
  planMode: Boolean(input.planMode),
9929
10153
  attachments: input.attachments ?? [],
9930
10154
  sourceIsFork,
@@ -11621,7 +11845,7 @@ var Orchestrator = class {
11621
11845
  }
11622
11846
  }
11623
11847
  listWorkspaces() {
11624
- const fromThreads = listThreads({ includeArchived: false }).map((t) => t.repoPath);
11848
+ const fromThreads = listThreads({ includeArchived: true }).map((t) => t.repoPath);
11625
11849
  return syncWorkspacesFromThreads(fromThreads);
11626
11850
  }
11627
11851
  async addWorkspace(repoPath) {
@@ -12721,7 +12945,15 @@ var Orchestrator = class {
12721
12945
  }
12722
12946
  await removeWorktree(thread.repoPath, thread.worktreePath);
12723
12947
  }
12724
- return setStatus(thread.id, "archived");
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;
12725
12957
  }
12726
12958
  async purge(threadRef, opts) {
12727
12959
  const thread = this.requireThread(threadRef);
@@ -12866,7 +13098,7 @@ async function startOrchestration(opts) {
12866
13098
  init_workspace_scratch();
12867
13099
 
12868
13100
  // src/plan/ask-user.ts
12869
- function asRecord3(v) {
13101
+ function asRecord5(v) {
12870
13102
  return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
12871
13103
  }
12872
13104
  function parseOptions(raw) {
@@ -12877,7 +13109,7 @@ function parseOptions(raw) {
12877
13109
  out.push({ label: item.trim() });
12878
13110
  continue;
12879
13111
  }
12880
- const o = asRecord3(item);
13112
+ const o = asRecord5(item);
12881
13113
  if (!o) continue;
12882
13114
  const label = typeof o.label === "string" ? o.label.trim() : typeof o.text === "string" ? o.text.trim() : typeof o.title === "string" ? o.title.trim() : "";
12883
13115
  if (!label) continue;
@@ -12887,7 +13119,7 @@ function parseOptions(raw) {
12887
13119
  return out;
12888
13120
  }
12889
13121
  function parseOneQuestion(raw) {
12890
- const o = asRecord3(raw);
13122
+ const o = asRecord5(raw);
12891
13123
  if (!o) return null;
12892
13124
  const question = typeof o.question === "string" ? o.question.trim() : typeof o.text === "string" ? o.text.trim() : typeof o.prompt === "string" ? o.prompt.trim() : "";
12893
13125
  if (!question) return null;
@@ -12898,7 +13130,7 @@ function parseOneQuestion(raw) {
12898
13130
  return { question, header, multiSelect, options };
12899
13131
  }
12900
13132
  function parsePlanQuestionsInput(input) {
12901
- const root = asRecord3(input);
13133
+ const root = asRecord5(input);
12902
13134
  if (!root) return [];
12903
13135
  const list = Array.isArray(root.questions) ? root.questions : Array.isArray(root.question) ? root.question : root.question || root.prompt ? [root] : [];
12904
13136
  const out = [];
@@ -13190,13 +13422,19 @@ async function startMcpServer() {
13190
13422
  return { content: [{ type: "text", text: JSON.stringify(payload) }] };
13191
13423
  }
13192
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}`;
13193
13428
  server.tool(
13194
13429
  "create_thread",
13195
- "Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces and parentThreadId when spawning from an orchestrator. Then use send_to_thread to chat.",
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.`,
13196
13431
  {
13197
13432
  sourceType: import_zod.z.enum(["branch", "pr", "ticket"]),
13198
13433
  sourceRef: import_zod.z.string(),
13199
- 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
+ ),
13200
13438
  repoPath: import_zod.z.string(),
13201
13439
  title: import_zod.z.string().optional(),
13202
13440
  parentThreadId: import_zod.z.string().optional()
@@ -13216,10 +13454,17 @@ async function startMcpServer() {
13216
13454
  };
13217
13455
  }
13218
13456
  }
13457
+ const opts = resolveNewThreadOptions2({
13458
+ agent: args.agent,
13459
+ model: args.model
13460
+ });
13219
13461
  const thread = await orch.createThread({
13220
13462
  sourceType: args.sourceType,
13221
13463
  sourceRef: args.sourceRef,
13222
- agent: args.agent,
13464
+ agent: opts.agent,
13465
+ model: opts.model,
13466
+ effort: opts.effort,
13467
+ fast: opts.fast,
13223
13468
  repoPath: args.repoPath,
13224
13469
  title: args.title,
13225
13470
  parentThreadId: args.parentThreadId ?? null
@@ -13233,6 +13478,8 @@ async function startMcpServer() {
13233
13478
  title: thread.title,
13234
13479
  branchName: thread.branchName,
13235
13480
  worktreePath: thread.worktreePath,
13481
+ agent: thread.agent,
13482
+ model: thread.model,
13236
13483
  status: thread.status,
13237
13484
  link: `sideboard://thread/${thread.id}`
13238
13485
  })
@@ -14507,6 +14754,7 @@ init_injected_mcp();
14507
14754
  resolveFilesToCopy,
14508
14755
  resolveGhAuthToken,
14509
14756
  resolveGithubRepoSlug,
14757
+ resolveNewThreadOptions,
14510
14758
  resolvePlanMarkdown,
14511
14759
  resolvePrSelector,
14512
14760
  resolveQuotaFallbackAgent,