@sideboard-ai/core 0.1.193 → 0.1.195

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 (51) hide show
  1. package/dist/{abletime-UX53JTIH.js → abletime-HR6P4GJH.js} +3 -3
  2. package/dist/{abletime-QHKWGTBY.js → abletime-JINF5KJV.js} +3 -3
  3. package/dist/agents/cursor-runner.js +2 -2
  4. package/dist/{agents-MN4GSQTL.js → agents-OXDDPH2O.js} +16 -17
  5. package/dist/{agents-OK5VD25T.js → agents-WQL7SZY6.js} +6 -7
  6. package/dist/{app-settings-LO7UFHQ6.js → app-settings-5KHVKJKO.js} +2 -2
  7. package/dist/{app-settings-QYLNKRK4.js → app-settings-J775CYOO.js} +2 -2
  8. package/dist/{branch-prefix-EVW2KHGQ.js → branch-prefix-7DTIUJT2.js} +1 -1
  9. package/dist/{branch-prefix-7F37FIPX.js → branch-prefix-N3KTCRCE.js} +1 -1
  10. package/dist/{chunk-MQC2VA5U.js → chunk-2X6RGKLI.js} +13 -13
  11. package/dist/{chunk-EBPBGQ4P.js → chunk-6H2XPPPR.js} +9 -9
  12. package/dist/{chunk-HIX2VDRE.js → chunk-6YTI2HBG.js} +6 -8
  13. package/dist/{chunk-KORE4WOF.js → chunk-AH6WIBLY.js} +1 -1
  14. package/dist/{chunk-XPKKCFRT.js → chunk-DP4TKAMZ.js} +864 -7
  15. package/dist/{chunk-O4BMPY5Y.js → chunk-E37JHCO3.js} +1 -1
  16. package/dist/{chunk-JTWKGOFI.js → chunk-FJZWM2ON.js} +1 -1
  17. package/dist/{chunk-3DX2T2KR.js → chunk-GFH3QVAV.js} +188 -95
  18. package/dist/{chunk-EQXXGOMD.js → chunk-HAVI6AY3.js} +197 -104
  19. package/dist/{chunk-4OVCJPVI.js → chunk-HZTHWU6A.js} +6 -8
  20. package/dist/{chunk-4QJRH5DL.js → chunk-KTHRWHA3.js} +1 -1
  21. package/dist/{chunk-BIKCWYRP.js → chunk-S4QCBBXS.js} +873 -16
  22. package/dist/{chunk-BWRS6GAS.js → chunk-S5GLSRLP.js} +1 -1
  23. package/dist/{chunk-PE337IM2.js → chunk-SALM35KD.js} +7 -7
  24. package/dist/{chunk-7SNJMKD6.js → chunk-WDRMZKVB.js} +1 -1
  25. package/dist/{connected-teams-SYQQGCXD.js → connected-teams-WK47ATT7.js} +2 -2
  26. package/dist/{coordinator-prompt-WB65HIZ3.js → coordinator-prompt-IX66YUJ2.js} +5 -6
  27. package/dist/{coordinator-prompt-GXJIPWNA.js → coordinator-prompt-LYKS3YNG.js} +4 -5
  28. package/dist/{global-workspace-MMK5UFUZ.js → global-workspace-4QX6UEOY.js} +5 -6
  29. package/dist/{global-workspace-BZ6V6TEX.js → global-workspace-SNJ2Z6SL.js} +4 -5
  30. package/dist/index.cjs +1051 -971
  31. package/dist/index.d.cts +7 -5
  32. package/dist/index.d.ts +7 -5
  33. package/dist/index.js +95 -54
  34. package/dist/mcp/run-stdio.cjs +218 -140
  35. package/dist/mcp/run-stdio.js +67 -26
  36. package/dist/{orchestrator-4KI6VIFG.js → orchestrator-6ESBGMDN.js} +9 -10
  37. package/dist/{orchestrator-SFOT6Q6F.js → orchestrator-EHRFN3Q6.js} +8 -9
  38. package/dist/{workspaces-KPJS7GLY.js → workspaces-URMUVGAQ.js} +5 -6
  39. package/dist/{workspaces-ACMZMKPD.js → workspaces-UTOYGBYB.js} +4 -5
  40. package/dist/{worktree-6IEVF3GN.js → worktree-R43JOR4V.js} +12 -14
  41. package/dist/{worktree-UW6DNBIE.js → worktree-RM6UWNGZ.js} +17 -19
  42. package/package.json +1 -1
  43. package/dist/chunk-64QSHOKV.js +0 -869
  44. package/dist/chunk-ILWQT2UN.js +0 -55
  45. package/dist/chunk-PBEPPXMY.js +0 -57
  46. package/dist/chunk-RCWHL4TK.js +0 -866
  47. package/dist/github-DWROJOB7.js +0 -11
  48. package/dist/github-IIF7AQNO.js +0 -9
  49. package/dist/worktree-labels-3XDS6O3U.js +0 -22
  50. package/dist/worktree-labels-PEDOJBMD.js +0 -24
  51. package/dist/{chunk-7AJ7OZZF.js → chunk-NLHFAMC2.js} +3 -3
@@ -6,7 +6,7 @@ import {
6
6
  getAbleTimeHost,
7
7
  isAbleTimeConnected,
8
8
  saveAbleTimeConnection
9
- } from "./chunk-BWRS6GAS.js";
9
+ } from "./chunk-S5GLSRLP.js";
10
10
 
11
11
  // src/integrations/abletime-mcp.ts
12
12
  var DEFAULT_ABLETIME_HOST = "https://track.abletime.com";
@@ -8,7 +8,7 @@ function sanitizeGitBranchPrefix(raw) {
8
8
  return slug || null;
9
9
  }
10
10
  function resolveGitBranchPrefix(opts) {
11
- return sanitizeGitBranchPrefix(opts.setting) ?? sanitizeGitBranchPrefix(opts.githubLogin);
11
+ return sanitizeGitBranchPrefix(opts.setting);
12
12
  }
13
13
  function examplePrefixedBranch(prefix, ticket) {
14
14
  const head = sanitizeGitBranchPrefix(prefix);
@@ -1,10 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import {
4
- extractPresentedPlan,
5
- readPlanFile,
6
- writePlanFile
7
- } from "./chunk-JFOPOMK7.js";
8
3
  import {
9
4
  releaseCaffeinateHoldForThread
10
5
  } from "./chunk-YWI3IBP2.js";
@@ -41,7 +36,7 @@ import {
41
36
  summarizeTurnStderr,
42
37
  toolDescription,
43
38
  turnFailChatText
44
- } from "./chunk-EBPBGQ4P.js";
39
+ } from "./chunk-6H2XPPPR.js";
45
40
  import {
46
41
  SLACK_REPLY_FORMATTING,
47
42
  addWorkspace,
@@ -64,9 +59,15 @@ import {
64
59
  stageAbsolutePathsAsAttachments,
65
60
  stageBuffersAsAttachments,
66
61
  syncWorkspacesFromThreads
67
- } from "./chunk-HIX2VDRE.js";
62
+ } from "./chunk-6YTI2HBG.js";
63
+ import {
64
+ extractPresentedPlan,
65
+ readPlanFile,
66
+ writePlanFile
67
+ } from "./chunk-JFOPOMK7.js";
68
68
  import {
69
69
  addPrStackLayer,
70
+ allocateTeamName,
70
71
  allocateTeamSlug,
71
72
  canonicalizeRepoPath,
72
73
  commitAll,
@@ -89,11 +90,13 @@ import {
89
90
  getPrStack,
90
91
  initPrStack,
91
92
  isDirty,
93
+ isPlaceholderBranch,
92
94
  isSideboardScratchPath,
93
95
  listWorktrees,
94
96
  markPrReady,
95
97
  mergeAgentGitAuthEnv,
96
98
  mergePr,
99
+ normalizeWorktreePath,
97
100
  originGhRepoEnv,
98
101
  pushBranch,
99
102
  removeWorktree,
@@ -104,8 +107,14 @@ import {
104
107
  resolvePrSelector,
105
108
  resolvePrSelectors,
106
109
  resolveRepoRoot,
107
- withRepoGitLock
108
- } from "./chunk-XPKKCFRT.js";
110
+ takenSlugsFromThread,
111
+ threadDisplayLabel,
112
+ ticketSlugForBranch,
113
+ withRepoGitLock,
114
+ worktreeDisplayLabelForGroup,
115
+ worktreeNameFromPath,
116
+ worktreeSlugForTicket
117
+ } from "./chunk-DP4TKAMZ.js";
109
118
  import {
110
119
  ATTACHMENTS_DIR,
111
120
  DETACHED_JOBS_DIR,
@@ -124,17 +133,6 @@ import {
124
133
  withThreadLock,
125
134
  writeThread
126
135
  } from "./chunk-CJFBSQIB.js";
127
- import {
128
- allocateTeamName,
129
- isPlaceholderBranch,
130
- normalizeWorktreePath,
131
- takenSlugsFromThread,
132
- threadDisplayLabel,
133
- ticketSlugForBranch,
134
- worktreeDisplayLabelForGroup,
135
- worktreeNameFromPath,
136
- worktreeSlugForTicket
137
- } from "./chunk-64QSHOKV.js";
138
136
  import {
139
137
  ensureWorktreeSideboardIgnored
140
138
  } from "./chunk-SYFVUF2C.js";
@@ -170,7 +168,7 @@ import {
170
168
  stripNestedElectronEnv,
171
169
  updateAdvancedSettings,
172
170
  writeSecureJson
173
- } from "./chunk-KORE4WOF.js";
171
+ } from "./chunk-AH6WIBLY.js";
174
172
  import {
175
173
  writePrivateFile
176
174
  } from "./chunk-NSTQ6QKD.js";
@@ -190,7 +188,7 @@ import {
190
188
  import {
191
189
  examplePrefixedBranch,
192
190
  sanitizeGitBranchPrefix
193
- } from "./chunk-JTWKGOFI.js";
191
+ } from "./chunk-FJZWM2ON.js";
194
192
 
195
193
  // src/orchestrator/orchestrator.ts
196
194
  import { EventEmitter } from "events";
@@ -408,7 +406,7 @@ async function continueSourceThread(threadId, prompt) {
408
406
  await continueOnReply(threadId, prompt);
409
407
  return;
410
408
  }
411
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-SFOT6Q6F.js");
409
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-EHRFN3Q6.js");
412
410
  await getOrchestrator2().send(threadId, prompt);
413
411
  } catch {
414
412
  }
@@ -801,9 +799,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
801
799
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
802
800
  );
803
801
  }
804
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-BZ6V6TEX.js");
802
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-SNJ2Z6SL.js");
805
803
  if (isGlobalThread2(thread)) {
806
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-GXJIPWNA.js");
804
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-LYKS3YNG.js");
807
805
  ensureGlobalCoordinatorCwd2(
808
806
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
809
807
  );
@@ -1446,6 +1444,53 @@ async function maybeCompactContext(thread, thresholds = {}, summarize = summariz
1446
1444
  };
1447
1445
  }
1448
1446
 
1447
+ // src/threads/worktree-runtime.ts
1448
+ function worktreeProcessPrefix(worktreePath) {
1449
+ return `wt:${normalizeWorktreePath(worktreePath)}`;
1450
+ }
1451
+ function worktreeSetupProcessKey(worktreePath) {
1452
+ return `${worktreeProcessPrefix(worktreePath)}:setup`;
1453
+ }
1454
+ function worktreeRunProcessKey(worktreePath, scriptName) {
1455
+ return `${worktreeProcessPrefix(worktreePath)}:run:${scriptName}`;
1456
+ }
1457
+ function worktreeDevProcessKey(worktreePath) {
1458
+ return `${worktreeProcessPrefix(worktreePath)}:dev`;
1459
+ }
1460
+ function isWorktreeRunProcessKey(key, worktreePath) {
1461
+ const prefix = worktreeProcessPrefix(worktreePath);
1462
+ return key.startsWith(`${prefix}:run:`) || key === `${prefix}:dev`;
1463
+ }
1464
+ function pickRichestSetupLog(snaps) {
1465
+ let best;
1466
+ for (const snap of snaps) {
1467
+ if (!snap.output && !snap.running && snap.exitCode == null) continue;
1468
+ if (!best) {
1469
+ best = snap;
1470
+ continue;
1471
+ }
1472
+ if (snap.running && !best.running) {
1473
+ best = snap;
1474
+ continue;
1475
+ }
1476
+ if (snap.running === best.running && snap.output.length > best.output.length) {
1477
+ best = snap;
1478
+ }
1479
+ }
1480
+ return best;
1481
+ }
1482
+ function mergeWorktreeActiveRuns(threads) {
1483
+ const byName = /* @__PURE__ */ new Map();
1484
+ let devPort = null;
1485
+ for (const thread of threads) {
1486
+ if (thread.devPort != null && devPort == null) devPort = thread.devPort;
1487
+ for (const run2 of thread.activeRuns ?? []) {
1488
+ if (!byName.has(run2.scriptName)) byName.set(run2.scriptName, run2);
1489
+ }
1490
+ }
1491
+ return { activeRuns: [...byName.values()], devPort };
1492
+ }
1493
+
1449
1494
  // src/threads/chat-tabs.ts
1450
1495
  function sameWorktreePath(a, b) {
1451
1496
  return normalizeWorktreePath(a) === normalizeWorktreePath(b);
@@ -1542,7 +1587,8 @@ function createChatTab(input) {
1542
1587
  planMode: from.planMode,
1543
1588
  autonomy: input.autonomy ?? from.autonomy,
1544
1589
  attachments: input.attachments ?? [],
1545
- status: "idle"
1590
+ status: "idle",
1591
+ ...mergeWorktreeActiveRuns(threadsSharingWorktree(binding.worktreePath))
1546
1592
  });
1547
1593
  writeThread(thread);
1548
1594
  return thread;
@@ -2187,6 +2233,7 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
2187
2233
  }
2188
2234
 
2189
2235
  // src/store/setup-log.ts
2236
+ import { createHash } from "crypto";
2190
2237
  import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
2191
2238
  import { join as join7 } from "path";
2192
2239
  var EMPTY = {
@@ -2200,6 +2247,10 @@ var persistTimers = /* @__PURE__ */ new Map();
2200
2247
  function setupLogPath(threadId) {
2201
2248
  return join7(threadsDir(), `${threadId}.setup.log.json`);
2202
2249
  }
2250
+ function setupLogKeyForWorktree(worktreePath) {
2251
+ const norm = normalizeWorktreePath(worktreePath);
2252
+ return `wt-${createHash("sha1").update(norm).digest("hex").slice(0, 16)}`;
2253
+ }
2203
2254
  function emptySetupLog() {
2204
2255
  return { ...EMPTY };
2205
2256
  }
@@ -3530,7 +3581,7 @@ async function createThread(input, _onSetupLine) {
3530
3581
  });
3531
3582
  await requireAgent(resolved.agent);
3532
3583
  if (input.cowboy) {
3533
- const { cowboyModeEnabled } = await import("./app-settings-QYLNKRK4.js");
3584
+ const { cowboyModeEnabled } = await import("./app-settings-J775CYOO.js");
3534
3585
  if (!cowboyModeEnabled()) {
3535
3586
  throw new Error(
3536
3587
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -3588,7 +3639,7 @@ async function createThread(input, _onSetupLine) {
3588
3639
  let sourceIsFork = false;
3589
3640
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
3590
3641
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
3591
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-UX53JTIH.js");
3642
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-HR6P4GJH.js");
3592
3643
  const task = await ensureAbleTimeTask({
3593
3644
  title: title?.trim() || "Untitled work",
3594
3645
  description: input.prompt?.trim() || void 0
@@ -4100,7 +4151,7 @@ async function adoptThread(input) {
4100
4151
  messages: input.messages ?? []
4101
4152
  });
4102
4153
  writeThread(thread);
4103
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ACMZMKPD.js");
4154
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-UTOYGBYB.js");
4104
4155
  await ensureWorkspace2(repoPath);
4105
4156
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
4106
4157
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -6478,7 +6529,7 @@ function formatScheduledPrompt(name, prompt) {
6478
6529
  ${prompt}`;
6479
6530
  }
6480
6531
  async function defaultDeps() {
6481
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-SFOT6Q6F.js");
6532
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-EHRFN3Q6.js");
6482
6533
  const orch = getOrchestrator2();
6483
6534
  return {
6484
6535
  findThread: (id) => findThreadByRef(id),
@@ -6753,7 +6804,7 @@ var Orchestrator = class {
6753
6804
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
6754
6805
  });
6755
6806
  }
6756
- const { autoCleanupOrphansEnabled } = await import("./app-settings-QYLNKRK4.js");
6807
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-J775CYOO.js");
6757
6808
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
6758
6809
  await cleanupOrphanWorktrees({ repoPaths });
6759
6810
  }
@@ -7032,7 +7083,7 @@ var Orchestrator = class {
7032
7083
  }
7033
7084
  await setup;
7034
7085
  if (skipSetup) return;
7035
- const { autoRunAfterSetupEnabled } = await import("./app-settings-QYLNKRK4.js");
7086
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-J775CYOO.js");
7036
7087
  if (autoRunAfterSetupEnabled()) {
7037
7088
  try {
7038
7089
  await this.startDev(threadId);
@@ -7355,7 +7406,7 @@ var Orchestrator = class {
7355
7406
  }
7356
7407
  const isBrightsy = fresh.agent === "brightsy";
7357
7408
  const isOrchestration = isOrchestratorThread(fresh);
7358
- const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-QYLNKRK4.js");
7409
+ const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-J775CYOO.js");
7359
7410
  const gitAuthMode = getGithubGitAuthMode();
7360
7411
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
7361
7412
  githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
@@ -7393,21 +7444,11 @@ var Orchestrator = class {
7393
7444
  const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
7394
7445
  let renameBranchDirective = null;
7395
7446
  if (!isBrightsy && !isOrchestration && autoRenameBranchEnabled()) {
7396
- const { isPlaceholderBranch: isPlaceholderBranch2 } = await import("./worktree-labels-PEDOJBMD.js");
7397
- let githubLogin = null;
7398
- if (isPlaceholderBranch2(fresh.branchName, fresh.worktreePath) && !gitBranchPrefixSetting()) {
7399
- try {
7400
- const { getGitHubStatus } = await import("./github-DWROJOB7.js");
7401
- githubLogin = (await getGitHubStatus()).login;
7402
- } catch {
7403
- }
7404
- }
7405
- const { resolveGitBranchPrefix } = await import("./branch-prefix-EVW2KHGQ.js");
7447
+ const { resolveGitBranchPrefix } = await import("./branch-prefix-7DTIUJT2.js");
7406
7448
  renameBranchDirective = formatRenameBranchDirective(fresh, {
7407
7449
  customPrompt: settings?.prompts?.renameBranch,
7408
7450
  branchPrefix: resolveGitBranchPrefix({
7409
- setting: gitBranchPrefixSetting(),
7410
- githubLogin
7451
+ setting: gitBranchPrefixSetting()
7411
7452
  })
7412
7453
  });
7413
7454
  }
@@ -7770,22 +7811,25 @@ var Orchestrator = class {
7770
7811
  "No run script found for this worktree. Add [scripts.run.*] in the worktree\u2019s .sideboard/settings.toml or .conductor/settings.toml (or settings.local.toml on the main repo)."
7771
7812
  );
7772
7813
  }
7773
- const runKey = `${thread.id}:run:${resolvedName}`;
7774
- const existing = this.processes.get(runKey);
7775
- const active = (thread.activeRuns ?? []).find((r) => r.scriptName === resolvedName);
7814
+ const siblings = threadsSharingWorktree(thread.worktreePath);
7815
+ const shared = mergeWorktreeActiveRuns(siblings);
7816
+ const runKey = worktreeRunProcessKey(thread.worktreePath, resolvedName);
7817
+ const existing = this.processes.get(runKey) ?? siblings.map((t) => this.processes.get(`${t.id}:run:${resolvedName}`)).find(Boolean);
7818
+ const active = shared.activeRuns.find((r) => r.scriptName === resolvedName);
7776
7819
  if (existing && active) {
7777
7820
  return { port: active.port, scriptName: resolvedName, ports: active.ports };
7778
7821
  }
7779
7822
  if (!scriptName) {
7780
- const legacy = this.processes.get(`${thread.id}:dev`);
7781
- if (legacy && thread.devPort) {
7782
- return { port: thread.devPort, scriptName: resolvedName, ports: [thread.devPort] };
7823
+ const legacy = this.processes.get(worktreeDevProcessKey(thread.worktreePath)) ?? siblings.map((t) => this.processes.get(`${t.id}:dev`)).find(Boolean);
7824
+ if (legacy && shared.devPort) {
7825
+ return { port: shared.devPort, scriptName: resolvedName, ports: [shared.devPort] };
7783
7826
  }
7784
7827
  }
7785
7828
  const mode = getRunMode(thread.worktreePath, thread.repoPath);
7786
7829
  if (mode === "nonconcurrent") {
7830
+ const here = normalizeWorktreePath(thread.worktreePath);
7787
7831
  for (const t of listThreads()) {
7788
- if (t.id === thread.id) continue;
7832
+ if (normalizeWorktreePath(t.worktreePath) === here) continue;
7789
7833
  const runs = t.activeRuns ?? [];
7790
7834
  if (runs.length > 0 || t.devPort) {
7791
7835
  throw new Error(
@@ -7820,7 +7864,7 @@ var Orchestrator = class {
7820
7864
  });
7821
7865
  const isDefault = scripts.find((s) => s.default)?.name === resolvedName || !scripts.some((s) => s.default) && (resolvedName === "dev" || resolvedName === scripts[0]?.name);
7822
7866
  if (isDefault) {
7823
- this.processes.set(`${thread.id}:dev`, {
7867
+ this.processes.set(worktreeDevProcessKey(thread.worktreePath), {
7824
7868
  kind: "dev",
7825
7869
  pid: handle.pid,
7826
7870
  startedAt,
@@ -7835,13 +7879,14 @@ var Orchestrator = class {
7835
7879
  startedAt
7836
7880
  };
7837
7881
  const nextRuns = [
7838
- ...(thread.activeRuns ?? []).filter((r) => r.scriptName !== resolvedName),
7882
+ ...shared.activeRuns.filter((r) => r.scriptName !== resolvedName),
7839
7883
  run2
7840
7884
  ];
7841
- updateThread(thread.id, {
7842
- activeRuns: nextRuns,
7843
- devPort: isDefault ? handle.port : thread.devPort
7844
- });
7885
+ this.syncWorktreeRuns(
7886
+ thread.worktreePath,
7887
+ nextRuns,
7888
+ isDefault ? handle.port : shared.devPort
7889
+ );
7845
7890
  this.emit({
7846
7891
  type: "dev_server_started",
7847
7892
  threadId: thread.id,
@@ -7850,15 +7895,14 @@ var Orchestrator = class {
7850
7895
  });
7851
7896
  void handle.done.then(() => {
7852
7897
  this.processes.delete(runKey);
7853
- if (isDefault) this.processes.delete(`${thread.id}:dev`);
7854
- const latest = readThread(thread.id);
7855
- const remaining = (latest?.activeRuns ?? []).filter(
7856
- (r) => r.scriptName !== resolvedName
7898
+ if (isDefault) this.processes.delete(worktreeDevProcessKey(thread.worktreePath));
7899
+ const latest = mergeWorktreeActiveRuns(threadsSharingWorktree(thread.worktreePath));
7900
+ const remaining = latest.activeRuns.filter((r) => r.scriptName !== resolvedName);
7901
+ this.syncWorktreeRuns(
7902
+ thread.worktreePath,
7903
+ remaining,
7904
+ isDefault ? null : latest.devPort
7857
7905
  );
7858
- updateThread(thread.id, {
7859
- activeRuns: remaining,
7860
- devPort: isDefault ? null : latest?.devPort ?? null
7861
- });
7862
7906
  this.emit({
7863
7907
  type: "dev_server_stopped",
7864
7908
  threadId: thread.id,
@@ -7869,51 +7913,82 @@ var Orchestrator = class {
7869
7913
  }
7870
7914
  stopDev(threadRef, scriptName) {
7871
7915
  const thread = this.requireThread(threadRef);
7916
+ const siblings = threadsSharingWorktree(thread.worktreePath);
7917
+ const shared = mergeWorktreeActiveRuns(siblings);
7872
7918
  if (scriptName) {
7873
- const runKey = `${thread.id}:run:${scriptName}`;
7874
- const proc = this.processes.get(runKey);
7875
- if (proc) proc.kill();
7876
- this.processes.delete(runKey);
7877
- const remaining = (thread.activeRuns ?? []).filter((r) => r.scriptName !== scriptName);
7878
- const isPrimary = thread.devPort != null && thread.activeRuns?.find((r) => r.scriptName === scriptName)?.port === thread.devPort;
7879
- updateThread(thread.id, {
7880
- activeRuns: remaining,
7881
- devPort: isPrimary ? null : thread.devPort
7882
- });
7919
+ const keys = [
7920
+ worktreeRunProcessKey(thread.worktreePath, scriptName),
7921
+ ...siblings.map((t) => `${t.id}:run:${scriptName}`)
7922
+ ];
7923
+ for (const key of keys) {
7924
+ const proc = this.processes.get(key);
7925
+ if (proc) proc.kill();
7926
+ this.processes.delete(key);
7927
+ }
7928
+ const remaining = shared.activeRuns.filter((r) => r.scriptName !== scriptName);
7929
+ const isPrimary = shared.devPort != null && shared.activeRuns.find((r) => r.scriptName === scriptName)?.port === shared.devPort;
7930
+ this.syncWorktreeRuns(
7931
+ thread.worktreePath,
7932
+ remaining,
7933
+ isPrimary ? null : shared.devPort
7934
+ );
7883
7935
  this.emit({ type: "dev_server_stopped", threadId: thread.id, scriptName });
7884
7936
  return;
7885
7937
  }
7886
7938
  for (const [key, proc] of [...this.processes.entries()]) {
7887
- if (key.startsWith(`${thread.id}:run:`) || key === `${thread.id}:dev`) {
7939
+ if (isWorktreeRunProcessKey(key, thread.worktreePath) || siblings.some((t) => key.startsWith(`${t.id}:run:`) || key === `${t.id}:dev`)) {
7888
7940
  proc.kill();
7889
7941
  this.processes.delete(key);
7890
7942
  }
7891
7943
  }
7892
- updateThread(thread.id, { activeRuns: [], devPort: null });
7944
+ this.syncWorktreeRuns(thread.worktreePath, [], null);
7893
7945
  this.emit({ type: "dev_server_stopped", threadId: thread.id });
7894
7946
  }
7947
+ syncWorktreeRuns(worktreePath, activeRuns, devPort) {
7948
+ for (const sibling of threadsSharingWorktree(worktreePath)) {
7949
+ updateThread(sibling.id, { activeRuns, devPort });
7950
+ }
7951
+ }
7895
7952
  listThreadRunScripts(threadRef) {
7896
7953
  const thread = this.requireThread(threadRef);
7897
7954
  return listRunScripts(thread.worktreePath, thread.repoPath);
7898
7955
  }
7899
7956
  getActiveRuns(threadRef) {
7900
- return this.requireThread(threadRef).activeRuns ?? [];
7957
+ const thread = this.requireThread(threadRef);
7958
+ return mergeWorktreeActiveRuns(threadsSharingWorktree(thread.worktreePath)).activeRuns;
7901
7959
  }
7902
7960
  getSetupLog(threadRef) {
7903
7961
  const thread = this.getThread(threadRef);
7904
7962
  if (!thread) return readSetupLog(threadRef);
7905
- const snap = readSetupLog(thread.id);
7906
- if (snap.running && !this.processes.has(`${thread.id}:setup`)) {
7963
+ const siblingIds = [
7964
+ thread.id,
7965
+ ...threadsSharingWorktree(thread.worktreePath).map((t) => t.id)
7966
+ ];
7967
+ const snap = pickRichestSetupLog([
7968
+ readSetupLog(setupLogKeyForWorktree(thread.worktreePath)),
7969
+ ...[...new Set(siblingIds)].map((id) => readSetupLog(id))
7970
+ ]) ?? readSetupLog(thread.id);
7971
+ if (snap.running && !this.hasWorktreeSetupProcess(thread.worktreePath)) {
7907
7972
  return { ...snap, running: false };
7908
7973
  }
7909
7974
  return snap;
7910
7975
  }
7976
+ hasWorktreeSetupProcess(worktreePath) {
7977
+ if (this.processes.has(worktreeSetupProcessKey(worktreePath))) return true;
7978
+ return threadsSharingWorktree(worktreePath).some(
7979
+ (t) => this.processes.has(`${t.id}:setup`)
7980
+ );
7981
+ }
7982
+ writeSetupLog(threadId, worktreePath, fn) {
7983
+ fn(setupLogKeyForWorktree(worktreePath));
7984
+ fn(threadId);
7985
+ }
7911
7986
  async runSetup(threadRef, opts) {
7912
7987
  const thread = this.requireThread(threadRef);
7913
7988
  this.assertNotGlobal(thread, "Setup");
7914
- const key = `${thread.id}:setup`;
7915
- if (this.processes.has(key)) {
7916
- throw new Error("Setup already running for this thread");
7989
+ const key = worktreeSetupProcessKey(thread.worktreePath);
7990
+ if (this.hasWorktreeSetupProcess(thread.worktreePath)) {
7991
+ throw new Error("Setup already running for this worktree");
7917
7992
  }
7918
7993
  const abort = new AbortController();
7919
7994
  this.processes.set(key, {
@@ -7921,13 +7996,17 @@ var Orchestrator = class {
7921
7996
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
7922
7997
  kill: () => abort.abort()
7923
7998
  });
7924
- beginSetupLog(thread.id);
7999
+ this.writeSetupLog(thread.id, thread.worktreePath, beginSetupLog);
7925
8000
  this.emit({ type: "setup_started", threadId: thread.id });
7926
8001
  let finished = false;
7927
8002
  const finish = (exitCode, source) => {
7928
8003
  if (finished) return;
7929
8004
  finished = true;
7930
- finishSetupLog(thread.id, exitCode, source);
8005
+ this.writeSetupLog(
8006
+ thread.id,
8007
+ thread.worktreePath,
8008
+ (logKey) => finishSetupLog(logKey, exitCode, source)
8009
+ );
7931
8010
  this.emit({ type: "setup_finished", threadId: thread.id, exitCode });
7932
8011
  };
7933
8012
  try {
@@ -7935,14 +8014,22 @@ var Orchestrator = class {
7935
8014
  thread.repoPath,
7936
8015
  thread.worktreePath,
7937
8016
  (line) => {
7938
- appendSetupLog(thread.id, line);
8017
+ this.writeSetupLog(
8018
+ thread.id,
8019
+ thread.worktreePath,
8020
+ (logKey) => appendSetupLog(logKey, line)
8021
+ );
7939
8022
  this.emit({ type: "setup_output", threadId: thread.id, line });
7940
8023
  },
7941
8024
  { signal: abort.signal }
7942
8025
  );
7943
8026
  if (!setup.ran) {
7944
8027
  const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
7945
- appendSetupLog(thread.id, line);
8028
+ this.writeSetupLog(
8029
+ thread.id,
8030
+ thread.worktreePath,
8031
+ (logKey) => appendSetupLog(logKey, line)
8032
+ );
7946
8033
  this.emit({ type: "setup_output", threadId: thread.id, line });
7947
8034
  finish(null, null);
7948
8035
  throw new Error(line);
@@ -7970,8 +8057,14 @@ var Orchestrator = class {
7970
8057
  }
7971
8058
  cancelSetup(threadRef) {
7972
8059
  const thread = this.requireThread(threadRef);
7973
- const proc = this.processes.get(`${thread.id}:setup`);
7974
- if (proc) proc.kill();
8060
+ const keys = [
8061
+ worktreeSetupProcessKey(thread.worktreePath),
8062
+ ...threadsSharingWorktree(thread.worktreePath).map((t) => `${t.id}:setup`)
8063
+ ];
8064
+ for (const key of [...new Set(keys)]) {
8065
+ const proc = this.processes.get(key);
8066
+ if (proc) proc.kill();
8067
+ }
7975
8068
  }
7976
8069
  async applyIntoMain(threadRef, opts) {
7977
8070
  const thread = this.requireThread(threadRef);
@@ -8298,7 +8391,7 @@ var Orchestrator = class {
8298
8391
  updateThread(thread.id, { title: meta.title });
8299
8392
  }
8300
8393
  }
8301
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-QYLNKRK4.js");
8394
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-J775CYOO.js");
8302
8395
  const latest = this.requireThread(thread.id);
8303
8396
  if (!shouldAutoArchiveOnPrMerge({
8304
8397
  previousPrState: prevState || null,
@@ -8590,7 +8683,7 @@ var Orchestrator = class {
8590
8683
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
8591
8684
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
8592
8685
  try {
8593
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ACMZMKPD.js");
8686
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-UTOYGBYB.js");
8594
8687
  await ensureWorkspace2(thread.repoPath);
8595
8688
  } catch {
8596
8689
  }
@@ -8617,7 +8710,7 @@ var Orchestrator = class {
8617
8710
  await runArchiveScript(thread.repoPath, thread.worktreePath);
8618
8711
  } catch {
8619
8712
  }
8620
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-QYLNKRK4.js");
8713
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-J775CYOO.js");
8621
8714
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
8622
8715
  await removeWorktree(thread.repoPath, thread.worktreePath, {
8623
8716
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -8644,7 +8737,7 @@ var Orchestrator = class {
8644
8737
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
8645
8738
  );
8646
8739
  }
8647
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-6IEVF3GN.js");
8740
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-R43JOR4V.js");
8648
8741
  const slug = thread.worktreePath.split("/").pop();
8649
8742
  const dest = thread.worktreePath;
8650
8743
  await withRepoGitLock(thread.repoPath, async () => {
@@ -8754,7 +8847,7 @@ async function startOrchestration(opts) {
8754
8847
  sourceRef: "default",
8755
8848
  ...createOpts
8756
8849
  }).catch(async () => {
8757
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-6IEVF3GN.js");
8850
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-R43JOR4V.js");
8758
8851
  const repo = await resolveRepoRoot2(repoPath);
8759
8852
  const def = await resolveDefaultBranch2(repo);
8760
8853
  return orch.createThread({