@sideboard-ai/core 0.1.202 → 0.1.204

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 (46) hide show
  1. package/dist/{abletime-KGPD3UUJ.js → abletime-S3UHQZVW.js} +4 -2
  2. package/dist/{abletime-345SE3B4.js → abletime-TONBQP4O.js} +4 -2
  3. package/dist/abletime-oauth-AVCEO2DY.js +314 -0
  4. package/dist/abletime-oauth-SD4SZY5U.js +52 -0
  5. package/dist/abletime-rest-6ODSXV7G.js +25 -0
  6. package/dist/abletime-rest-J2OBB4VA.js +24 -0
  7. package/dist/agents/cursor-runner.js +1 -1
  8. package/dist/{agents-573ZDIX6.js → agents-67K4BQFJ.js} +4 -4
  9. package/dist/{agents-OXX3ONVY.js → agents-BVOJNHV6.js} +5 -5
  10. package/dist/{app-settings-V6IHESEQ.js → app-settings-LGHMNHSP.js} +1 -1
  11. package/dist/{app-settings-AXCURTZJ.js → app-settings-YEPF46IJ.js} +1 -1
  12. package/dist/chunk-3K257PCS.js +393 -0
  13. package/dist/{chunk-54RSAMBH.js → chunk-5SMS6QTO.js} +2 -2
  14. package/dist/chunk-6Q7DFVDQ.js +309 -0
  15. package/dist/chunk-CYLDJWRK.js +391 -0
  16. package/dist/{chunk-PGQGP4FD.js → chunk-FO2NTJ7L.js} +37 -219
  17. package/dist/{chunk-7NKY2OX7.js → chunk-FO45DMJ5.js} +125 -109
  18. package/dist/{chunk-CQ5R3VPP.js → chunk-KZ7PI7FE.js} +18 -0
  19. package/dist/{chunk-7AHAABKN.js → chunk-QAVWH2RQ.js} +37 -229
  20. package/dist/{chunk-CXFW5LIH.js → chunk-QFBBUFD4.js} +38 -3
  21. package/dist/{chunk-RPX6VDW7.js → chunk-QUW5D62C.js} +34 -20
  22. package/dist/chunk-SGUVAK66.js +262 -0
  23. package/dist/{chunk-27GGXX27.js → chunk-ULZLWQBS.js} +128 -112
  24. package/dist/{chunk-LJHC62LZ.js → chunk-VIPA75ZA.js} +2 -2
  25. package/dist/chunk-W6VM36YO.js +272 -0
  26. package/dist/{chunk-NIVF5NDN.js → chunk-WF33LOP4.js} +44 -6
  27. package/dist/{chunk-STPZQR5B.js → chunk-WVATAIF4.js} +34 -20
  28. package/dist/{chunk-ISV5IFH3.js → chunk-X743YN5Y.js} +38 -3
  29. package/dist/{chunk-A2TAKYSG.js → chunk-YOSTWSNC.js} +27 -7
  30. package/dist/{coordinator-prompt-BH4EHFOO.js → coordinator-prompt-NPT555BO.js} +3 -3
  31. package/dist/{coordinator-prompt-TY5FHAXC.js → coordinator-prompt-WEPXXLLX.js} +3 -3
  32. package/dist/{global-workspace-NLLAPQJI.js → global-workspace-2I2T7FL5.js} +3 -3
  33. package/dist/{global-workspace-5AZEEQRU.js → global-workspace-NSILADOM.js} +3 -3
  34. package/dist/index.cjs +1137 -213
  35. package/dist/index.d.cts +87 -13
  36. package/dist/index.d.ts +87 -13
  37. package/dist/index.js +94 -19
  38. package/dist/mcp/run-stdio.cjs +1023 -180
  39. package/dist/mcp/run-stdio.js +22 -20
  40. package/dist/{orchestrator-JNSQDRZI.js → orchestrator-CMAVNELS.js} +6 -6
  41. package/dist/{orchestrator-NCYKEI3E.js → orchestrator-I7GFXLHF.js} +6 -6
  42. package/dist/{workspaces-RP76JH3J.js → workspaces-BOC6M7BW.js} +3 -3
  43. package/dist/{workspaces-PEWYWVHZ.js → workspaces-RFGZBUAR.js} +3 -3
  44. package/dist/{worktree-72TZWUSH.js → worktree-G3ZLM4DC.js} +4 -2
  45. package/dist/{worktree-ZQEUKSNE.js → worktree-WSUQMMK4.js} +4 -2
  46. package/package.json +1 -1
@@ -26,7 +26,7 @@ import {
26
26
  stripBrightsyNdjsonNoise,
27
27
  sumUsageList,
28
28
  toolDescription
29
- } from "./chunk-A2TAKYSG.js";
29
+ } from "./chunk-YOSTWSNC.js";
30
30
  import {
31
31
  SLACK_REPLY_FORMATTING,
32
32
  addWorkspace,
@@ -49,13 +49,14 @@ import {
49
49
  stageAbsolutePathsAsAttachments,
50
50
  stageBuffersAsAttachments,
51
51
  syncWorkspacesFromThreads
52
- } from "./chunk-LJHC62LZ.js";
52
+ } from "./chunk-VIPA75ZA.js";
53
53
  import {
54
54
  addPrStackLayer,
55
55
  allocateTeamName,
56
56
  allocateTeamSlug,
57
57
  canonicalizeRepoPath,
58
58
  commitAll,
59
+ connectedPrSelectors,
59
60
  createExistingBranchWorktree,
60
61
  createOrUpdatePr,
61
62
  createThreadWorktree,
@@ -90,7 +91,6 @@ import {
90
91
  resolveDiffBaseRef,
91
92
  resolveGithubRepoSlug,
92
93
  resolvePrSelector,
93
- resolvePrSelectors,
94
94
  resolveRepoRoot,
95
95
  takenSlugsFromThread,
96
96
  threadDisplayLabel,
@@ -99,7 +99,7 @@ import {
99
99
  worktreeDisplayLabelForGroup,
100
100
  worktreeNameFromPath,
101
101
  worktreeSlugForTicket
102
- } from "./chunk-STPZQR5B.js";
102
+ } from "./chunk-WVATAIF4.js";
103
103
  import {
104
104
  ATTACHMENTS_DIR,
105
105
  DETACHED_JOBS_DIR,
@@ -130,7 +130,7 @@ import {
130
130
  shouldRetryFailedAgentTurn,
131
131
  summarizeTurnStderr,
132
132
  turnFailChatText
133
- } from "./chunk-CQ5R3VPP.js";
133
+ } from "./chunk-KZ7PI7FE.js";
134
134
  import {
135
135
  assertOrchestratorCapableAgent,
136
136
  childEnvWithAppSettings,
@@ -155,7 +155,7 @@ import {
155
155
  updateAdvancedSettings,
156
156
  usageOnLimit,
157
157
  writeSecureJson
158
- } from "./chunk-CXFW5LIH.js";
158
+ } from "./chunk-QFBBUFD4.js";
159
159
  import {
160
160
  stripNestedElectronEnv
161
161
  } from "./chunk-4TR3HZFT.js";
@@ -474,7 +474,7 @@ async function continueSourceThread(threadId, prompt) {
474
474
  await continueOnReply(threadId, prompt);
475
475
  return;
476
476
  }
477
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-JNSQDRZI.js");
477
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-CMAVNELS.js");
478
478
  await getOrchestrator2().send(threadId, prompt);
479
479
  } catch {
480
480
  }
@@ -808,9 +808,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
808
808
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
809
809
  );
810
810
  }
811
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-5AZEEQRU.js");
811
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-NSILADOM.js");
812
812
  if (isGlobalThread2(thread)) {
813
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-TY5FHAXC.js");
813
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-WEPXXLLX.js");
814
814
  ensureGlobalCoordinatorCwd2(
815
815
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
816
816
  );
@@ -1018,6 +1018,33 @@ var FIX_CI_RE = /^Fix CI: .+\.$/;
1018
1018
  function normalizePrState(state) {
1019
1019
  return (state ?? "").trim().toUpperCase();
1020
1020
  }
1021
+ function sameLoginList(a, b) {
1022
+ const left = [...a ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
1023
+ const right = [...b ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
1024
+ return left.length === right.length && left.every((login, i) => login === right[i]);
1025
+ }
1026
+ function threadPrMetaPatch(thread, meta) {
1027
+ const prevState = normalizePrState(thread.prState);
1028
+ const nextState = normalizePrState(meta.state);
1029
+ const patch = {};
1030
+ if (meta.url && meta.url !== thread.prUrl) patch.prUrl = meta.url;
1031
+ if (meta.title && meta.title !== thread.prTitle) patch.prTitle = meta.title;
1032
+ if (nextState && nextState !== prevState) patch.prState = nextState;
1033
+ const nextDraft = Boolean(meta.isDraft) && nextState !== "MERGED" && nextState !== "CLOSED";
1034
+ if (nextDraft !== Boolean(thread.prIsDraft)) patch.prIsDraft = nextDraft;
1035
+ const nextAuthor = meta.authorLogin?.trim() || "";
1036
+ if (nextAuthor && nextAuthor !== (thread.prAuthorLogin ?? "").trim()) {
1037
+ patch.prAuthorLogin = nextAuthor;
1038
+ }
1039
+ const nextReviewers = meta.reviewerLogins ?? [];
1040
+ if (!sameLoginList(nextReviewers, thread.prReviewerLogins)) {
1041
+ patch.prReviewerLogins = nextReviewers;
1042
+ }
1043
+ if (thread.skipAutoArchiveOnMerge && nextState && nextState !== "MERGED" && nextState !== "CLOSED") {
1044
+ patch.skipAutoArchiveOnMerge = false;
1045
+ }
1046
+ return patch;
1047
+ }
1021
1048
  function shouldAutoArchiveOnPrMerge(opts) {
1022
1049
  if (!opts.autoArchiveEnabled) return false;
1023
1050
  if (opts.isGlobal) return false;
@@ -3761,7 +3788,7 @@ async function createThread(input, _onSetupLine) {
3761
3788
  });
3762
3789
  await requireAgent(resolved.agent);
3763
3790
  if (input.cowboy) {
3764
- const { cowboyModeEnabled } = await import("./app-settings-AXCURTZJ.js");
3791
+ const { cowboyModeEnabled } = await import("./app-settings-YEPF46IJ.js");
3765
3792
  if (!cowboyModeEnabled()) {
3766
3793
  throw new Error(
3767
3794
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -3819,7 +3846,7 @@ async function createThread(input, _onSetupLine) {
3819
3846
  let sourceIsFork = false;
3820
3847
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
3821
3848
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
3822
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-345SE3B4.js");
3849
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-TONBQP4O.js");
3823
3850
  const task = await ensureAbleTimeTask({
3824
3851
  title: title?.trim() || "Untitled work",
3825
3852
  description: input.prompt?.trim() || void 0
@@ -3921,7 +3948,7 @@ async function createThread(input, _onSetupLine) {
3921
3948
  return readThread(thread.id) ?? thread;
3922
3949
  }
3923
3950
  async function listLinearIssues(agent, repoPath) {
3924
- const { getAdapter: getAdapter2 } = await import("./agents-OXX3ONVY.js");
3951
+ const { getAdapter: getAdapter2 } = await import("./agents-BVOJNHV6.js");
3925
3952
  await requireAgent(agent, { requireLinear: true });
3926
3953
  const adapter = getAdapter2(agent);
3927
3954
  if (!adapter.listLinearIssues) {
@@ -4243,6 +4270,13 @@ var QUOTA_CONTINUE_PROMPT = (fromAgent, fallback) => [
4243
4270
  "Proceed with the goal. Leave model Auto unless needed."
4244
4271
  ].join(" ");
4245
4272
  var QUOTA_RESUME_PROMPT = "Session/usage limit window should have reset. Continue this chat from where you left off.";
4273
+ async function isolateQuotaFailover(run2) {
4274
+ try {
4275
+ return await run2();
4276
+ } catch {
4277
+ return true;
4278
+ }
4279
+ }
4246
4280
  function createQuotaFailoverChat(from, fallbackAgent, limitText) {
4247
4281
  const handoff = buildQuotaHandoffAttachment(from, limitText, fallbackAgent);
4248
4282
  const tab = createChatTab({
@@ -4360,7 +4394,7 @@ async function adoptThread(input) {
4360
4394
  messages: input.messages ?? []
4361
4395
  });
4362
4396
  writeThread(thread);
4363
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-RP76JH3J.js");
4397
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-BOC6M7BW.js");
4364
4398
  await ensureWorkspace2(repoPath);
4365
4399
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-X54WSOXM.js");
4366
4400
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -6944,7 +6978,7 @@ function formatScheduledPrompt(name, prompt) {
6944
6978
  ${prompt}`;
6945
6979
  }
6946
6980
  async function defaultDeps() {
6947
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-JNSQDRZI.js");
6981
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-CMAVNELS.js");
6948
6982
  const orch = getOrchestrator2();
6949
6983
  return {
6950
6984
  findThread: (id) => findThreadByRef(id),
@@ -7058,11 +7092,6 @@ function isPidAlive(pid) {
7058
7092
  return false;
7059
7093
  }
7060
7094
  }
7061
- function sameLoginList(a, b) {
7062
- const left = [...a ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
7063
- const right = [...b ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
7064
- return left.length === right.length && left.every((login, i) => login === right[i]);
7065
- }
7066
7095
  async function waitForPidExit(pid, timeoutMs) {
7067
7096
  const start = Date.now();
7068
7097
  while (isPidAlive(pid)) {
@@ -7219,7 +7248,7 @@ var Orchestrator = class {
7219
7248
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
7220
7249
  });
7221
7250
  }
7222
- const { autoCleanupOrphansEnabled } = await import("./app-settings-AXCURTZJ.js");
7251
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-YEPF46IJ.js");
7223
7252
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
7224
7253
  await cleanupOrphanWorktrees({ repoPaths });
7225
7254
  }
@@ -7341,51 +7370,62 @@ var Orchestrator = class {
7341
7370
  if (plan.action === "wait_reset" && plan.resumeAt) {
7342
7371
  this.haltDrain.add(threadId);
7343
7372
  this.scheduleQuotaResume(threadId, plan.resumeAt);
7344
- setStatus(threadId, "idle", null);
7345
- appendMessage(threadId, {
7346
- role: "agent",
7347
- text: `Sideboard will auto-retry this chat around ${plan.resumeAt.toLocaleString()} when the session limit resets.`,
7348
- ts: (/* @__PURE__ */ new Date()).toISOString()
7349
- });
7350
- this.emit({
7351
- type: "quota_failover",
7352
- threadId,
7353
- action: "wait_reset",
7354
- message: plan.reason,
7355
- resumeAt: plan.resumeAt.toISOString()
7356
- });
7357
- this.emit({ type: "status_changed", threadId, status: "idle" });
7373
+ try {
7374
+ setStatus(threadId, "idle", null);
7375
+ appendMessage(threadId, {
7376
+ role: "agent",
7377
+ text: `Sideboard will auto-retry this chat around ${plan.resumeAt.toLocaleString()} when the session limit resets.`,
7378
+ ts: (/* @__PURE__ */ new Date()).toISOString()
7379
+ });
7380
+ this.emit({
7381
+ type: "quota_failover",
7382
+ threadId,
7383
+ action: "wait_reset",
7384
+ message: plan.reason,
7385
+ resumeAt: plan.resumeAt.toISOString()
7386
+ });
7387
+ this.emit({ type: "status_changed", threadId, status: "idle" });
7388
+ } catch {
7389
+ }
7358
7390
  return true;
7359
7391
  }
7360
7392
  if (plan.action === "switch_agent" && plan.fallbackAgent) {
7361
7393
  this.haltDrain.add(threadId);
7362
- const next = createQuotaFailoverChat(
7363
- thread,
7364
- plan.fallbackAgent,
7365
- plan.limitText
7366
- );
7394
+ let next;
7395
+ try {
7396
+ next = createQuotaFailoverChat(
7397
+ thread,
7398
+ plan.fallbackAgent,
7399
+ plan.limitText
7400
+ );
7401
+ } catch {
7402
+ return false;
7403
+ }
7367
7404
  this.clearQuotaResumeTimer(threadId);
7368
7405
  try {
7369
7406
  updateThread(threadId, { quotaResumeAt: null });
7370
7407
  } catch {
7371
7408
  }
7372
- appendMessage(threadId, {
7373
- role: "agent",
7374
- text: `Session limit on ${thread.agent}. Sideboard continued on ${plan.fallbackAgent} (Auto) in [${next.title}](sideboard://thread/${next.id}).`,
7375
- ts: (/* @__PURE__ */ new Date()).toISOString()
7376
- });
7377
- this.emit({
7378
- type: "quota_failover",
7379
- threadId,
7380
- action: "switch_agent",
7381
- toThreadId: next.id,
7382
- message: plan.reason
7383
- });
7384
- this.emit({
7385
- type: "status_changed",
7386
- threadId: next.id,
7387
- status: next.status
7388
- });
7409
+ try {
7410
+ appendMessage(threadId, {
7411
+ role: "agent",
7412
+ text: `Session limit on ${thread.agent}. Sideboard continued on ${plan.fallbackAgent} (Auto) in [${next.title}](sideboard://thread/${next.id}).`,
7413
+ ts: (/* @__PURE__ */ new Date()).toISOString()
7414
+ });
7415
+ this.emit({
7416
+ type: "quota_failover",
7417
+ threadId,
7418
+ action: "switch_agent",
7419
+ toThreadId: next.id,
7420
+ message: plan.reason
7421
+ });
7422
+ this.emit({
7423
+ type: "status_changed",
7424
+ threadId: next.id,
7425
+ status: next.status
7426
+ });
7427
+ } catch {
7428
+ }
7389
7429
  void this.send(
7390
7430
  next.id,
7391
7431
  QUOTA_CONTINUE_PROMPT(thread.agent, plan.fallbackAgent)
@@ -7500,7 +7540,7 @@ var Orchestrator = class {
7500
7540
  }
7501
7541
  await setup;
7502
7542
  if (skipSetup) return;
7503
- const { autoRunAfterSetupEnabled } = await import("./app-settings-AXCURTZJ.js");
7543
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-YEPF46IJ.js");
7504
7544
  if (autoRunAfterSetupEnabled()) {
7505
7545
  try {
7506
7546
  await this.startDev(threadId);
@@ -7824,7 +7864,7 @@ var Orchestrator = class {
7824
7864
  }
7825
7865
  const isBrightsy = fresh.agent === "brightsy";
7826
7866
  const isOrchestration = isOrchestratorThread(fresh);
7827
- const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-AXCURTZJ.js");
7867
+ const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-YEPF46IJ.js");
7828
7868
  const gitAuthMode = getGithubGitAuthMode();
7829
7869
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
7830
7870
  githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
@@ -8116,9 +8156,8 @@ var Orchestrator = class {
8116
8156
  this.maybeEnqueueJobContinue(threadId, chatText, parts);
8117
8157
  } else {
8118
8158
  const blob = [chatText, detail].filter(Boolean).join("\n");
8119
- const failedOver = await this.maybeHandleOrchestrationQuotaFailover(
8120
- threadId,
8121
- blob
8159
+ const failedOver = await isolateQuotaFailover(
8160
+ () => this.maybeHandleOrchestrationQuotaFailover(threadId, blob)
8122
8161
  );
8123
8162
  this.maybeEnqueueCrashContinue(threadId, {
8124
8163
  detail: detail || failDetail,
@@ -8152,9 +8191,8 @@ var Orchestrator = class {
8152
8191
  this.emit({ type: "status_changed", threadId, status: "error" });
8153
8192
  }
8154
8193
  this.emit({ type: "turn_finished", threadId, exitCode: 1 });
8155
- const failedOver = await this.maybeHandleOrchestrationQuotaFailover(
8156
- threadId,
8157
- message
8194
+ const failedOver = await isolateQuotaFailover(
8195
+ () => this.maybeHandleOrchestrationQuotaFailover(threadId, message)
8158
8196
  );
8159
8197
  this.maybeEnqueueCrashContinue(threadId, {
8160
8198
  detail: message,
@@ -8764,12 +8802,18 @@ var Orchestrator = class {
8764
8802
  /** Resolve PR selectors and optionally persist `prUrl` when found. */
8765
8803
  async withPrSelector(threadRef) {
8766
8804
  const thread = this.requireThread(threadRef);
8767
- const selectors = resolvePrSelectors(thread);
8768
8805
  const cwd = thread.worktreePath;
8769
8806
  if (!cwd?.trim()) {
8770
8807
  throw new Error(`Thread ${threadRef} has no worktreePath`);
8771
8808
  }
8772
- return { thread, selectors, cwd };
8809
+ let headUrl = null;
8810
+ try {
8811
+ const head = await getPrForHeadBranch(cwd, thread.branchName);
8812
+ headUrl = head?.url?.trim() || null;
8813
+ } catch {
8814
+ headUrl = null;
8815
+ }
8816
+ return { thread, selectors: connectedPrSelectors(thread, headUrl), cwd };
8773
8817
  }
8774
8818
  async getPrChecks(threadRef) {
8775
8819
  const { selectors, cwd } = await this.withPrSelector(threadRef);
@@ -8797,31 +8841,18 @@ var Orchestrator = class {
8797
8841
  async persistPrMetaAndMaybeArchive(thread, meta) {
8798
8842
  const prevState = normalizePrState(thread.prState);
8799
8843
  const nextState = normalizePrState(meta.state);
8800
- const patch = {};
8801
- if (meta.url && meta.url !== thread.prUrl) patch.prUrl = meta.url;
8802
- if (meta.title && meta.title !== thread.prTitle) patch.prTitle = meta.title;
8803
- if (nextState && nextState !== prevState) patch.prState = nextState;
8804
- const nextDraft = Boolean(meta.isDraft) && nextState !== "MERGED" && nextState !== "CLOSED";
8805
- if (nextDraft !== Boolean(thread.prIsDraft)) patch.prIsDraft = nextDraft;
8806
- const nextAuthor = meta.authorLogin?.trim() || "";
8807
- if (nextAuthor && nextAuthor !== (thread.prAuthorLogin ?? "").trim()) {
8808
- patch.prAuthorLogin = nextAuthor;
8809
- }
8810
- const nextReviewers = meta.reviewerLogins ?? [];
8811
- if (!sameLoginList(nextReviewers, thread.prReviewerLogins)) {
8812
- patch.prReviewerLogins = nextReviewers;
8813
- }
8814
- if (thread.skipAutoArchiveOnMerge && nextState && nextState !== "MERGED" && nextState !== "CLOSED") {
8815
- patch.skipAutoArchiveOnMerge = false;
8844
+ const siblings = threadsSharingWorktree(thread.worktreePath);
8845
+ const targets = siblings.length > 0 ? siblings : [thread];
8846
+ for (const t of targets) {
8847
+ const patch = threadPrMetaPatch(t, meta);
8848
+ if (Object.keys(patch).length === 0) continue;
8849
+ updateThread(t.id, patch);
8816
8850
  }
8817
- if (Object.keys(patch).length > 0) {
8818
- updateThread(thread.id, patch);
8819
- const latest2 = this.requireThread(thread.id);
8820
- if (!latest2.userSetTitle && meta.title && latest2.title !== meta.title) {
8821
- updateThread(thread.id, { title: meta.title });
8822
- }
8851
+ const titled = this.requireThread(thread.id);
8852
+ if (!titled.userSetTitle && meta.title && titled.title !== meta.title) {
8853
+ updateThread(thread.id, { title: meta.title });
8823
8854
  }
8824
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-AXCURTZJ.js");
8855
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-YEPF46IJ.js");
8825
8856
  const latest = this.requireThread(thread.id);
8826
8857
  if (!shouldAutoArchiveOnPrMerge({
8827
8858
  previousPrState: prevState || null,
@@ -8833,22 +8864,7 @@ var Orchestrator = class {
8833
8864
  })) {
8834
8865
  return;
8835
8866
  }
8836
- const siblings = threadsSharingWorktree(latest.worktreePath);
8837
- for (const t of siblings) {
8838
- const sibPatch = { prState: "MERGED", prIsDraft: false };
8839
- if (meta.url && meta.url !== t.prUrl) sibPatch.prUrl = meta.url;
8840
- if (meta.title && meta.title !== t.prTitle) sibPatch.prTitle = meta.title;
8841
- const sibAuthor = meta.authorLogin?.trim() || "";
8842
- if (sibAuthor && sibAuthor !== (t.prAuthorLogin ?? "").trim()) {
8843
- sibPatch.prAuthorLogin = sibAuthor;
8844
- }
8845
- const sibReviewers = meta.reviewerLogins ?? [];
8846
- if (!sameLoginList(sibReviewers, t.prReviewerLogins)) {
8847
- sibPatch.prReviewerLogins = sibReviewers;
8848
- }
8849
- if (Object.keys(sibPatch).length > 0) updateThread(t.id, sibPatch);
8850
- }
8851
- for (const t of siblings) {
8867
+ for (const t of threadsSharingWorktree(latest.worktreePath)) {
8852
8868
  if (this.requireThread(t.id).status === "archived") continue;
8853
8869
  await this.archive(t.id);
8854
8870
  }
@@ -9113,7 +9129,7 @@ var Orchestrator = class {
9113
9129
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
9114
9130
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
9115
9131
  try {
9116
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-RP76JH3J.js");
9132
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-BOC6M7BW.js");
9117
9133
  await ensureWorkspace2(thread.repoPath);
9118
9134
  } catch {
9119
9135
  }
@@ -9140,7 +9156,7 @@ var Orchestrator = class {
9140
9156
  await runArchiveScript(thread.repoPath, thread.worktreePath);
9141
9157
  } catch {
9142
9158
  }
9143
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-AXCURTZJ.js");
9159
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-YEPF46IJ.js");
9144
9160
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
9145
9161
  await removeWorktree(thread.repoPath, thread.worktreePath, {
9146
9162
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -9167,7 +9183,7 @@ var Orchestrator = class {
9167
9183
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
9168
9184
  );
9169
9185
  }
9170
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-72TZWUSH.js");
9186
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-G3ZLM4DC.js");
9171
9187
  const slug = thread.worktreePath.split("/").pop();
9172
9188
  const dest = thread.worktreePath;
9173
9189
  await withRepoGitLock(thread.repoPath, async () => {
@@ -9277,7 +9293,7 @@ async function startOrchestration(opts) {
9277
9293
  sourceRef: "default",
9278
9294
  ...createOpts
9279
9295
  }).catch(async () => {
9280
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-72TZWUSH.js");
9296
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-G3ZLM4DC.js");
9281
9297
  const repo = await resolveRepoRoot2(repoPath);
9282
9298
  const def = await resolveDefaultBranch2(repo);
9283
9299
  return orch.createThread({
@@ -264,6 +264,9 @@ function humanizeAgentFailDetail(detail) {
264
264
  if (/\[resource_exhausted\]|resource_exhausted|findfileswithripgrep/.test(lower)) {
265
265
  return "Cursor local file search failed (ripgrep / resource_exhausted). Wait a minute and retry; if it keeps happening, check Cursor usage.";
266
266
  }
267
+ if (looksLikeCodexMcpError(raw)) {
268
+ return `${raw} \u2014 skip that vendor MCP and continue (PostHog: Settings \u2192 Connectors + HTTP API).`;
269
+ }
267
270
  if (/invalid user api key|invalid api key|not logged in|not authenticated|unauthorized|authentication|please run.*login|codex login|claude auth|cursor api/.test(
268
271
  lower
269
272
  )) {
@@ -321,9 +324,24 @@ function turnFailChatText(opts) {
321
324
 
322
325
  ${fail}`;
323
326
  }
327
+ function looksLikeCodexMcpError(text) {
328
+ const t = text.trim().toLowerCase();
329
+ if (!t) return false;
330
+ if (/authrequired|authorization required/.test(t) && /mcp|posthog|rmcp|connector|plugin/.test(t)) {
331
+ return true;
332
+ }
333
+ if (/\bposthog\b/.test(t) && /mcp|oauth|auth|unauthorized|401|plugin|app/.test(t)) {
334
+ return true;
335
+ }
336
+ if (/\brmcp\b/.test(t) && /fatal|quit|transport|error|died|kill|auth/.test(t)) {
337
+ return true;
338
+ }
339
+ return /mcp[_ -]?(server|tool|error|transport|client)/.test(t) && /fail|error|timeout|disconnect|auth|unauthorized/.test(t);
340
+ }
324
341
  function shouldFeedErrorBackToAgent(opts) {
325
342
  const detail = opts.detail.trim();
326
343
  const chat = (opts.assistantText ?? "").trim();
344
+ if (looksLikeCodexMcpError(detail)) return true;
327
345
  if (looksLikeAgentFailureMessage(detail) || looksLikeAgentFailureMessage(chat)) {
328
346
  return false;
329
347
  }