@sideboard-ai/core 0.1.57 → 0.1.59

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 (39) hide show
  1. package/dist/{agents-2YYWW723.js → agents-B2723EOF.js} +4 -4
  2. package/dist/{agents-AQFEFKBL.js → agents-EADRAAPG.js} +4 -4
  3. package/dist/{app-settings-2LQNRTBE.js → app-settings-TBHTJWLQ.js} +1 -1
  4. package/dist/{app-settings-73DI4B6T.js → app-settings-YBNZ4XSR.js} +1 -1
  5. package/dist/{chunk-5DMYULLC.js → chunk-2P2UK7E7.js} +2 -2
  6. package/dist/{chunk-7LNGIP3X.js → chunk-73AT5K4A.js} +15 -3
  7. package/dist/{chunk-DIOF73S2.js → chunk-75QR74KM.js} +7 -2
  8. package/dist/{chunk-EBWEKG52.js → chunk-CHGOMFTA.js} +3 -3
  9. package/dist/{chunk-C4BCC5X5.js → chunk-FGNBTFRD.js} +7 -2
  10. package/dist/{chunk-H6GGDLYS.js → chunk-JB2H7E7V.js} +1 -1
  11. package/dist/{chunk-BXJ76RHF.js → chunk-MBAL5FE6.js} +4 -4
  12. package/dist/{chunk-XOU6HNQJ.js → chunk-MFGGIRUA.js} +39 -13
  13. package/dist/{chunk-S42XDFKF.js → chunk-MLAST5BB.js} +3 -3
  14. package/dist/{chunk-C3J4GDW4.js → chunk-MX7UH5AT.js} +76 -60
  15. package/dist/{chunk-DQJ5D42H.js → chunk-NTYRBRE7.js} +44 -13
  16. package/dist/{chunk-DZFH2KLT.js → chunk-P7EQUFB6.js} +39 -13
  17. package/dist/{chunk-V2DUTUNC.js → chunk-QJBC4BRK.js} +2 -2
  18. package/dist/{chunk-ZNM4MAN4.js → chunk-RIWUU7FO.js} +15 -3
  19. package/dist/{chunk-UA5NDAHL.js → chunk-XWPKLRB3.js} +44 -13
  20. package/dist/{chunk-7F454EE2.js → chunk-ZXDOI6IH.js} +76 -53
  21. package/dist/{connected-teams-ONC4666A.js → connected-teams-MKIYKOYA.js} +2 -2
  22. package/dist/{connected-teams-2ANNZCP5.js → connected-teams-RSL4VB3X.js} +2 -2
  23. package/dist/{coordinator-prompt-RBKUNRPR.js → coordinator-prompt-4P23VVFC.js} +4 -4
  24. package/dist/{coordinator-prompt-ICF36NUQ.js → coordinator-prompt-LNWHZ64D.js} +4 -4
  25. package/dist/{global-workspace-667XLBW6.js → global-workspace-BHT4XUAA.js} +5 -5
  26. package/dist/{global-workspace-S7VLWPWG.js → global-workspace-TMMAVRVW.js} +5 -5
  27. package/dist/index.cjs +303 -115
  28. package/dist/index.d.cts +15 -6
  29. package/dist/index.d.ts +15 -6
  30. package/dist/index.js +157 -64
  31. package/dist/mcp/run-stdio.cjs +303 -126
  32. package/dist/mcp/run-stdio.js +156 -68
  33. package/dist/{run-ZJKYHXGN.js → run-GPSVV5OH.js} +1 -1
  34. package/dist/{run-H3IMNOYN.js → run-HZTBWGQR.js} +1 -1
  35. package/dist/{workspaces-FPJJXXAE.js → workspaces-3GO3EDQG.js} +6 -6
  36. package/dist/{workspaces-LYIDE2VR.js → workspaces-GFPGDGCS.js} +6 -6
  37. package/dist/{worktree-5KEQWSAF.js → worktree-3L2G6PCM.js} +2 -2
  38. package/dist/{worktree-RWGL7FUV.js → worktree-GBLHEFHR.js} +2 -2
  39. package/package.json +1 -1
@@ -2,7 +2,6 @@
2
2
 
3
3
  import {
4
4
  PLAN_MODE_INSTRUCTION,
5
- allAdapters,
6
5
  fallbackTurnFailDetail,
7
6
  formatTurnExitError,
8
7
  getAdapter,
@@ -16,14 +15,14 @@ import {
16
15
  pushTurnStderr,
17
16
  resolveQuotaFallbackAgent,
18
17
  summarizeTurnStderr
19
- } from "../chunk-C3J4GDW4.js";
20
- import "../chunk-H6GGDLYS.js";
18
+ } from "../chunk-MX7UH5AT.js";
19
+ import "../chunk-JB2H7E7V.js";
21
20
  import {
22
21
  addWorkspace,
23
22
  ensureWorkspace,
24
23
  removeWorkspace,
25
24
  syncWorkspacesFromThreads
26
- } from "../chunk-V2DUTUNC.js";
25
+ } from "../chunk-QJBC4BRK.js";
27
26
  import {
28
27
  extractPresentedPlan,
29
28
  readPlanFile,
@@ -37,7 +36,7 @@ import {
37
36
  isGlobalThread,
38
37
  isOrchestratorThread,
39
38
  orchestratorSessionPoisonedByBuiltins
40
- } from "../chunk-EBWEKG52.js";
39
+ } from "../chunk-CHGOMFTA.js";
41
40
  import {
42
41
  assertOrchestratorCapableAgent
43
42
  } from "../chunk-S2LL5HA4.js";
@@ -46,7 +45,7 @@ import {
46
45
  coordinatorTurnReminder,
47
46
  enrichWorkspacesWithGithub,
48
47
  ensureGlobalCoordinatorCwd
49
- } from "../chunk-DQJ5D42H.js";
48
+ } from "../chunk-NTYRBRE7.js";
50
49
  import {
51
50
  addPrStackLayer,
52
51
  allocateTeamName,
@@ -83,7 +82,7 @@ import {
83
82
  takenSlugsFromThread,
84
83
  threadDisplayLabel,
85
84
  worktreeNameFromPath
86
- } from "../chunk-XOU6HNQJ.js";
85
+ } from "../chunk-MFGGIRUA.js";
87
86
  import {
88
87
  ATTACHMENTS_DIR,
89
88
  LEGACY_ATTACHMENTS_DIR,
@@ -106,7 +105,7 @@ import {
106
105
  gh,
107
106
  git,
108
107
  run
109
- } from "../chunk-ZNM4MAN4.js";
108
+ } from "../chunk-RIWUU7FO.js";
110
109
  import {
111
110
  childEnvWithAppSettings,
112
111
  getLinearApiKey,
@@ -117,7 +116,7 @@ import {
117
116
  resolveEffectiveIssueSource,
118
117
  resolveNewThreadOptions,
119
118
  updateAdvancedSettings
120
- } from "../chunk-C4BCC5X5.js";
119
+ } from "../chunk-FGNBTFRD.js";
121
120
  import "../chunk-KGZBYWZ3.js";
122
121
  import {
123
122
  loadRepoSettings,
@@ -392,10 +391,12 @@ async function spawnAgentTurn(thread, input, onEvent) {
392
391
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
393
392
  );
394
393
  }
395
- const { isGlobalThread: isGlobalThread2 } = await import("../global-workspace-667XLBW6.js");
394
+ const { isGlobalThread: isGlobalThread2 } = await import("../global-workspace-BHT4XUAA.js");
396
395
  if (isGlobalThread2(thread)) {
397
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("../coordinator-prompt-RBKUNRPR.js");
398
- ensureGlobalCoordinatorCwd2();
396
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("../coordinator-prompt-4P23VVFC.js");
397
+ ensureGlobalCoordinatorCwd2(
398
+ isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
399
+ );
399
400
  }
400
401
  if (isOrchestratorThread(thread)) {
401
402
  assertOrchestratorCapableAgent(thread.agent);
@@ -1099,13 +1100,21 @@ async function cloneRepoIntoSideboard(opts) {
1099
1100
  import { existsSync as existsSync5 } from "fs";
1100
1101
 
1101
1102
  // src/detect/detect.ts
1102
- async function detectAgents() {
1103
- ensureAgentPath();
1104
- return Promise.all(allAdapters().map((a) => a.detect()));
1105
- }
1103
+ var REQUIRE_AGENT_TIMEOUT_MS = 8e3;
1106
1104
  async function requireAgent(agent, opts) {
1107
- const status = (await detectAgents()).find((s) => s.agent === agent);
1108
- if (!status) throw new Error(`Unknown agent: ${agent}`);
1105
+ ensureAgentPath();
1106
+ const status = await Promise.race([
1107
+ getAdapter(agent).detect(),
1108
+ new Promise((_, reject) => {
1109
+ setTimeout(() => {
1110
+ reject(
1111
+ new Error(
1112
+ `${agent} detect timed out after ${REQUIRE_AGENT_TIMEOUT_MS / 1e3}s`
1113
+ )
1114
+ );
1115
+ }, REQUIRE_AGENT_TIMEOUT_MS);
1116
+ })
1117
+ ]);
1109
1118
  if (!status.installed || !status.authenticated) {
1110
1119
  throw new Error(status.reason ?? `${agent} is not available`);
1111
1120
  }
@@ -1185,7 +1194,7 @@ async function createThread(input, _onSetupLine) {
1185
1194
  return readThread(thread.id) ?? thread;
1186
1195
  }
1187
1196
  async function listLinearIssues(agent, repoPath) {
1188
- const { getAdapter: getAdapter2 } = await import("../agents-AQFEFKBL.js");
1197
+ const { getAdapter: getAdapter2 } = await import("../agents-EADRAAPG.js");
1189
1198
  await requireAgent(agent, { requireLinear: true });
1190
1199
  const adapter = getAdapter2(agent);
1191
1200
  if (!adapter.listLinearIssues) {
@@ -1705,7 +1714,7 @@ var REPO_REVIEW_NAME = "review.md";
1705
1714
  var REVIEW_REQUEST_PATH = `${ATTACHMENTS_DIR}/Review request.md`;
1706
1715
  var LEGACY_REVIEW_REQUEST_PATH = `${LEGACY_ATTACHMENTS_DIR}/Review request.md`;
1707
1716
  var REVIEW_REQUEST_NAME = "Review request.md";
1708
- var REVIEW_REQUEST_PREFILL = "Review.";
1717
+ var REVIEW_REQUEST_PREFILL = "Review changes in this workspace.";
1709
1718
  var LEGACY_REVIEW_TEMPLATE_MARKERS = [
1710
1719
  "You are acting as a reviewer for a proposed code change made by another engineer.",
1711
1720
  "HOW MANY FINDINGS TO RETURN:"
@@ -2032,7 +2041,7 @@ async function adoptThread(input) {
2032
2041
  throw new Error(`Worktree not found: ${input.worktreePath}`);
2033
2042
  }
2034
2043
  const repoPath = await resolveRepoRoot(input.worktreePath);
2035
- const { stdout: branch } = await import("../run-H3IMNOYN.js").then(
2044
+ const { stdout: branch } = await import("../run-HZTBWGQR.js").then(
2036
2045
  ({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], input.worktreePath)
2037
2046
  );
2038
2047
  const thread = createEmptyThread({
@@ -2047,7 +2056,7 @@ async function adoptThread(input) {
2047
2056
  messages: input.messages ?? []
2048
2057
  });
2049
2058
  writeThread(thread);
2050
- const { ensureWorkspace: ensureWorkspace2 } = await import("../workspaces-LYIDE2VR.js");
2059
+ const { ensureWorkspace: ensureWorkspace2 } = await import("../workspaces-GFPGDGCS.js");
2051
2060
  await ensureWorkspace2(repoPath);
2052
2061
  return thread;
2053
2062
  }
@@ -3153,7 +3162,7 @@ async function previewLand(thread) {
3153
3162
  const target = await resolveDefaultBranch(thread.repoPath);
3154
3163
  if (thread.branchName === target || thread.branchName === "main" || thread.branchName === "master") {
3155
3164
  }
3156
- const { stdout: head } = await import("../run-H3IMNOYN.js").then(
3165
+ const { stdout: head } = await import("../run-HZTBWGQR.js").then(
3157
3166
  ({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], thread.worktreePath)
3158
3167
  );
3159
3168
  const current = head.trim();
@@ -3192,7 +3201,7 @@ async function confirmLand(thread, opts) {
3192
3201
  if (preview.dirty) {
3193
3202
  committed = await commitAll(thread.worktreePath, meta.commitMessage);
3194
3203
  }
3195
- const { git: git2 } = await import("../run-H3IMNOYN.js");
3204
+ const { git: git2 } = await import("../run-HZTBWGQR.js");
3196
3205
  const { stdout: headOut } = await git2(
3197
3206
  ["rev-parse", "--abbrev-ref", "HEAD"],
3198
3207
  thread.worktreePath,
@@ -3935,7 +3944,7 @@ var Orchestrator = class {
3935
3944
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
3936
3945
  });
3937
3946
  }
3938
- const { autoCleanupOrphansEnabled } = await import("../app-settings-73DI4B6T.js");
3947
+ const { autoCleanupOrphansEnabled } = await import("../app-settings-YBNZ4XSR.js");
3939
3948
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
3940
3949
  await cleanupOrphanWorktrees({ repoPaths });
3941
3950
  }
@@ -4092,7 +4101,7 @@ var Orchestrator = class {
4092
4101
  }
4093
4102
  async finishCreateThread(threadId, prompt) {
4094
4103
  await this.runSetupAfterCreate(threadId);
4095
- const { autoRunAfterSetupEnabled } = await import("../app-settings-73DI4B6T.js");
4104
+ const { autoRunAfterSetupEnabled } = await import("../app-settings-YBNZ4XSR.js");
4096
4105
  if (autoRunAfterSetupEnabled()) {
4097
4106
  try {
4098
4107
  await this.startDev(threadId);
@@ -4363,7 +4372,7 @@ var Orchestrator = class {
4363
4372
  });
4364
4373
  const artifactDirective = isBrightsy ? null : formatArtifactDirective();
4365
4374
  const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
4366
- const { autoRenameBranchEnabled } = await import("../app-settings-73DI4B6T.js");
4375
+ const { autoRenameBranchEnabled } = await import("../app-settings-YBNZ4XSR.js");
4367
4376
  const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled() ? formatRenameBranchDirective(fresh, {
4368
4377
  customPrompt: settings?.prompts?.renameBranch
4369
4378
  }) : null;
@@ -4375,7 +4384,9 @@ var Orchestrator = class {
4375
4384
  }
4376
4385
  let coordinatorDirective = null;
4377
4386
  if (isOrchestration) {
4378
- if (isGlobalThread(fresh)) ensureGlobalCoordinatorCwd();
4387
+ if (isGlobalThread(fresh)) {
4388
+ ensureGlobalCoordinatorCwd({ orchestratorThreadId: fresh.id });
4389
+ }
4379
4390
  if (!fresh.sessionId) {
4380
4391
  const inventory = await enrichWorkspacesWithGithub(this.listWorkspaces());
4381
4392
  coordinatorDirective = coordinatorSystemPrompt({
@@ -5232,7 +5243,7 @@ var Orchestrator = class {
5232
5243
  const archived = setStatus(thread.id, "archived");
5233
5244
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
5234
5245
  try {
5235
- const { ensureWorkspace: ensureWorkspace2 } = await import("../workspaces-LYIDE2VR.js");
5246
+ const { ensureWorkspace: ensureWorkspace2 } = await import("../workspaces-GFPGDGCS.js");
5236
5247
  await ensureWorkspace2(thread.repoPath);
5237
5248
  } catch {
5238
5249
  }
@@ -5253,7 +5264,7 @@ var Orchestrator = class {
5253
5264
  await runArchiveScript(thread.repoPath, thread.worktreePath);
5254
5265
  } catch {
5255
5266
  }
5256
- const { deleteBranchOnPurgeEnabled } = await import("../app-settings-73DI4B6T.js");
5267
+ const { deleteBranchOnPurgeEnabled } = await import("../app-settings-YBNZ4XSR.js");
5257
5268
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
5258
5269
  await removeWorktree(thread.repoPath, thread.worktreePath, {
5259
5270
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -5272,7 +5283,7 @@ var Orchestrator = class {
5272
5283
  return setStatus(thread.id, "idle");
5273
5284
  }
5274
5285
  if (!existsSync13(thread.worktreePath)) {
5275
- const { createThreadWorktree: createThreadWorktree2 } = await import("../worktree-5KEQWSAF.js");
5286
+ const { createThreadWorktree: createThreadWorktree2 } = await import("../worktree-3L2G6PCM.js");
5276
5287
  const { execa: execa6 } = await import("execa");
5277
5288
  const slug = thread.worktreePath.split("/").pop();
5278
5289
  const dest = thread.worktreePath;
@@ -5443,14 +5454,39 @@ function mcpArchiveBlockedReason(thread) {
5443
5454
 
5444
5455
  // src/mcp/server.ts
5445
5456
  var MAX_ORCH_THREADS = 5;
5457
+ var CREATE_THREAD_TIMEOUT_MS = 9e4;
5458
+ function withTimeout(promise, ms, label) {
5459
+ return new Promise((resolve, reject) => {
5460
+ const timer = setTimeout(() => {
5461
+ reject(new Error(`${label} timed out after ${Math.round(ms / 1e3)}s`));
5462
+ }, ms);
5463
+ promise.then(
5464
+ (value) => {
5465
+ clearTimeout(timer);
5466
+ resolve(value);
5467
+ },
5468
+ (err) => {
5469
+ clearTimeout(timer);
5470
+ reject(err);
5471
+ }
5472
+ );
5473
+ });
5474
+ }
5446
5475
  async function startMcpServer() {
5447
5476
  const orch = getOrchestrator();
5448
5477
  try {
5449
- const { maxConcurrentAgents } = await import("../app-settings-73DI4B6T.js");
5478
+ const { maxConcurrentAgents } = await import("../app-settings-YBNZ4XSR.js");
5450
5479
  orch.setMaxConcurrent(maxConcurrentAgents());
5451
5480
  } catch {
5452
5481
  }
5453
- await orch.reconcile(void 0, { reclaimStaleTurns: false, drainQueues: false });
5482
+ try {
5483
+ await orch.reconcile(void 0, { reclaimStaleTurns: false, drainQueues: false });
5484
+ } catch (err) {
5485
+ console.error(
5486
+ "[sideboard-mcp] reconcile on boot failed (continuing):",
5487
+ err instanceof Error ? err.message : err
5488
+ );
5489
+ }
5454
5490
  const server = new McpServer({
5455
5491
  name: "sideboard",
5456
5492
  version: "0.1.0"
@@ -5650,12 +5686,12 @@ async function startMcpServer() {
5650
5686
  return { content: [{ type: "text", text: JSON.stringify(payload) }] };
5651
5687
  }
5652
5688
  );
5653
- const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults } = await import("../app-settings-73DI4B6T.js");
5689
+ const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults } = await import("../app-settings-YBNZ4XSR.js");
5654
5690
  const accountDefaults = resolveThreadDefaults();
5655
5691
  const accountDefaultsHint = `Account defaults: agent=${accountDefaults.agent}, model=${accountDefaults.model?.trim() || "Auto"}, effort=${accountDefaults.effort}`;
5656
5692
  server.tool(
5657
5693
  "create_thread",
5658
- `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.`,
5694
+ `Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces. From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Then use send_to_thread to chat.`,
5659
5695
  {
5660
5696
  sourceType: z.enum(["branch", "pr", "ticket"]),
5661
5697
  sourceRef: z.string(),
@@ -5665,11 +5701,31 @@ async function startMcpServer() {
5665
5701
  ),
5666
5702
  repoPath: z.string(),
5667
5703
  title: z.string().optional(),
5668
- parentThreadId: z.string().optional()
5704
+ parentThreadId: z.string().optional().describe(
5705
+ "Orchestration: omit (preferred) or pass YOUR chat id from the turn reminder / AGENTS.md. Do not invent uuids."
5706
+ )
5669
5707
  },
5670
5708
  async (args) => {
5671
- if (args.parentThreadId) {
5672
- const children = orch.getThreads(true).filter((t) => t.parentThreadId === args.parentThreadId);
5709
+ const envParentId = process.env.SIDEBOARD_ORCHESTRATOR_THREAD_ID?.trim() || "";
5710
+ let parentId = args.parentThreadId?.trim() || "";
5711
+ let parent = parentId ? orch.getThread(parentId) : null;
5712
+ let parentCorrectedFrom;
5713
+ if (envParentId) {
5714
+ const envParent = orch.getThread(envParentId);
5715
+ if (envParent) {
5716
+ if (parentId && parentId !== envParentId) parentCorrectedFrom = parentId;
5717
+ else if (!parentId) parentCorrectedFrom = void 0;
5718
+ parentId = envParentId;
5719
+ parent = envParent;
5720
+ }
5721
+ }
5722
+ if (parentId && !parent) {
5723
+ parentCorrectedFrom = parentId;
5724
+ parentId = "";
5725
+ parent = null;
5726
+ }
5727
+ if (parentId) {
5728
+ const children = orch.getThreads(true).filter((t) => t.parentThreadId === parentId);
5673
5729
  if (children.length >= MAX_ORCH_THREADS) {
5674
5730
  return {
5675
5731
  content: [
@@ -5682,38 +5738,70 @@ async function startMcpServer() {
5682
5738
  };
5683
5739
  }
5684
5740
  }
5741
+ let agentArg = args.agent;
5742
+ let agentCoercedFrom;
5743
+ const resolvedProbe = resolveNewThreadOptions2({ agent: agentArg }).agent;
5744
+ if (resolvedProbe === "codex") {
5745
+ agentCoercedFrom = agentArg ?? "codex";
5746
+ const accountAgent = resolveNewThreadOptions2({}).agent;
5747
+ agentArg = accountAgent !== "codex" ? accountAgent : "cursor";
5748
+ }
5685
5749
  const opts = resolveNewThreadOptions2({
5686
- agent: args.agent,
5750
+ agent: agentArg,
5687
5751
  model: args.model
5688
5752
  });
5689
- const thread = await orch.createThread({
5690
- sourceType: args.sourceType,
5691
- sourceRef: args.sourceRef,
5692
- agent: opts.agent,
5693
- model: opts.model,
5694
- effort: opts.effort,
5695
- fast: opts.fast,
5696
- repoPath: args.repoPath,
5697
- title: args.title,
5698
- parentThreadId: args.parentThreadId ?? null
5699
- });
5700
- return {
5701
- content: [
5702
- {
5703
- type: "text",
5704
- text: JSON.stringify({
5705
- id: thread.id,
5706
- title: thread.title,
5707
- branchName: thread.branchName,
5708
- worktreePath: thread.worktreePath,
5709
- agent: thread.agent,
5710
- model: thread.model,
5711
- status: thread.status,
5712
- link: `sideboard://thread/${thread.id}`
5713
- })
5714
- }
5715
- ]
5716
- };
5753
+ try {
5754
+ const thread = await withTimeout(
5755
+ orch.createThread({
5756
+ sourceType: args.sourceType,
5757
+ sourceRef: args.sourceRef,
5758
+ agent: opts.agent,
5759
+ model: opts.model,
5760
+ effort: opts.effort,
5761
+ fast: opts.fast,
5762
+ repoPath: args.repoPath,
5763
+ title: args.title,
5764
+ parentThreadId: parentId || null
5765
+ }),
5766
+ CREATE_THREAD_TIMEOUT_MS,
5767
+ "create_thread"
5768
+ );
5769
+ const parentNote = parentCorrectedFrom ? parentId ? `Ignored unknown/stale parentThreadId ${parentCorrectedFrom}; nested under ${parentId}` : `Ignored unknown/stale parentThreadId ${parentCorrectedFrom}; created without parent` : void 0;
5770
+ return {
5771
+ content: [
5772
+ {
5773
+ type: "text",
5774
+ text: JSON.stringify({
5775
+ id: thread.id,
5776
+ title: thread.title,
5777
+ branchName: thread.branchName,
5778
+ worktreePath: thread.worktreePath,
5779
+ agent: thread.agent,
5780
+ model: thread.model,
5781
+ status: thread.status,
5782
+ link: `sideboard://thread/${thread.id}`,
5783
+ parentThreadId: thread.parentThreadId,
5784
+ ...agentCoercedFrom ? {
5785
+ agentCoercedFrom,
5786
+ note: `Avoid nested Codex under a Codex orchestrator \u2014 used Account default agent=${thread.agent}`
5787
+ } : {},
5788
+ ...parentCorrectedFrom ? { parentCorrectedFrom, parentNote } : {}
5789
+ })
5790
+ }
5791
+ ]
5792
+ };
5793
+ } catch (err) {
5794
+ const message = err instanceof Error ? err.message : String(err);
5795
+ return {
5796
+ content: [
5797
+ {
5798
+ type: "text",
5799
+ text: `create_thread failed: ${message}`
5800
+ }
5801
+ ],
5802
+ isError: true
5803
+ };
5804
+ }
5717
5805
  }
5718
5806
  );
5719
5807
  server.tool(
@@ -5894,7 +5982,7 @@ async function startMcpServer() {
5894
5982
  );
5895
5983
  server.tool(
5896
5984
  "request_review",
5897
- 'Start a merge-readiness Review on a worktree agent thread (same as the desktop Review button). Opens a new Review chat tab, attaches .sideboard/review.md when present (else local Review request.md / stock template), and sends "Review." Expect Approve / Approve with nits / Request changes / Needs more information. Pass a worktree thread ref \u2014 not the orchestrator. Then wait_for_turn / get_turn_result on the returned review tab id.',
5985
+ 'Start a merge-readiness Review on a worktree agent thread (same as the desktop Review button). Opens a new Review chat tab, attaches .sideboard/review.md when present (else local Review request.md / stock template), and sends "Review changes in this workspace." Expect Approve / Approve with nits / Request changes / Needs more information. Pass a worktree thread ref \u2014 not the orchestrator. Then wait_for_turn / get_turn_result on the returned review tab id.',
5898
5986
  { ref: z.string().describe("Worktree thread id/ref to review") },
5899
5987
  async ({ ref }) => {
5900
5988
  try {
@@ -3,7 +3,7 @@ import {
3
3
  git,
4
4
  resolveGhAuthToken,
5
5
  run
6
- } from "./chunk-7LNGIP3X.js";
6
+ } from "./chunk-73AT5K4A.js";
7
7
  export {
8
8
  gh,
9
9
  git,
@@ -5,7 +5,7 @@ import {
5
5
  git,
6
6
  resolveGhAuthToken,
7
7
  run
8
- } from "./chunk-ZNM4MAN4.js";
8
+ } from "./chunk-RIWUU7FO.js";
9
9
  export {
10
10
  gh,
11
11
  git,
@@ -4,17 +4,17 @@ import {
4
4
  listWorkspaces,
5
5
  removeWorkspace,
6
6
  syncWorkspacesFromThreads
7
- } from "./chunk-5DMYULLC.js";
8
- import "./chunk-S42XDFKF.js";
7
+ } from "./chunk-2P2UK7E7.js";
8
+ import "./chunk-MLAST5BB.js";
9
9
  import "./chunk-GI7E5733.js";
10
- import "./chunk-UA5NDAHL.js";
11
- import "./chunk-DIOF73S2.js";
12
- import "./chunk-DZFH2KLT.js";
10
+ import "./chunk-XWPKLRB3.js";
11
+ import "./chunk-75QR74KM.js";
12
+ import "./chunk-P7EQUFB6.js";
13
13
  import "./chunk-FKOIHGKV.js";
14
14
  import "./chunk-TSRXOSVD.js";
15
15
  import "./chunk-77WWLBCI.js";
16
16
  import "./chunk-M37RITA6.js";
17
- import "./chunk-7LNGIP3X.js";
17
+ import "./chunk-73AT5K4A.js";
18
18
  export {
19
19
  addWorkspace,
20
20
  ensureWorkspace,
@@ -6,15 +6,15 @@ import {
6
6
  listWorkspaces,
7
7
  removeWorkspace,
8
8
  syncWorkspacesFromThreads
9
- } from "./chunk-V2DUTUNC.js";
10
- import "./chunk-EBWEKG52.js";
9
+ } from "./chunk-QJBC4BRK.js";
10
+ import "./chunk-CHGOMFTA.js";
11
11
  import "./chunk-S2LL5HA4.js";
12
- import "./chunk-DQJ5D42H.js";
13
- import "./chunk-XOU6HNQJ.js";
12
+ import "./chunk-NTYRBRE7.js";
13
+ import "./chunk-MFGGIRUA.js";
14
14
  import "./chunk-B3SJXYIJ.js";
15
15
  import "./chunk-HLEX5AQ6.js";
16
- import "./chunk-ZNM4MAN4.js";
17
- import "./chunk-C4BCC5X5.js";
16
+ import "./chunk-RIWUU7FO.js";
17
+ import "./chunk-FGNBTFRD.js";
18
18
  import "./chunk-KGZBYWZ3.js";
19
19
  import "./chunk-7MV3RXSC.js";
20
20
  export {
@@ -45,10 +45,10 @@ import {
45
45
  worktreeDisplayLabel,
46
46
  worktreeDisplayLabelForGroup,
47
47
  worktreeNameFromPath
48
- } from "./chunk-XOU6HNQJ.js";
48
+ } from "./chunk-MFGGIRUA.js";
49
49
  import "./chunk-B3SJXYIJ.js";
50
50
  import "./chunk-HLEX5AQ6.js";
51
- import "./chunk-ZNM4MAN4.js";
51
+ import "./chunk-RIWUU7FO.js";
52
52
  import "./chunk-KGZBYWZ3.js";
53
53
  import "./chunk-7MV3RXSC.js";
54
54
  export {
@@ -43,12 +43,12 @@ import {
43
43
  worktreeDisplayLabel,
44
44
  worktreeDisplayLabelForGroup,
45
45
  worktreeNameFromPath
46
- } from "./chunk-DZFH2KLT.js";
46
+ } from "./chunk-P7EQUFB6.js";
47
47
  import "./chunk-FKOIHGKV.js";
48
48
  import "./chunk-TSRXOSVD.js";
49
49
  import "./chunk-77WWLBCI.js";
50
50
  import "./chunk-M37RITA6.js";
51
- import "./chunk-7LNGIP3X.js";
51
+ import "./chunk-73AT5K4A.js";
52
52
  export {
53
53
  FAMOUS_SOCCER_TEAMS,
54
54
  allocateTeamName,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sideboard-ai/core",
3
- "version": "0.1.57",
3
+ "version": "0.1.59",
4
4
  "description": "Sideboard core — orchestration, agents, git worktrees, MCP server",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",