@sideboard-ai/core 0.1.284 → 0.1.286

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 (54) hide show
  1. package/dist/{abletime-WLDBJJUI.js → abletime-4CH2IOX5.js} +4 -4
  2. package/dist/{abletime-X64E3GUJ.js → abletime-I4RODUKT.js} +4 -4
  3. package/dist/{abletime-oauth-AXR676W5.js → abletime-oauth-7OZZ3ABX.js} +3 -3
  4. package/dist/{abletime-oauth-UWOCEICP.js → abletime-oauth-C2HN2Q6F.js} +3 -3
  5. package/dist/{abletime-rest-S4XWEXV2.js → abletime-rest-E4LBRFLM.js} +3 -3
  6. package/dist/{abletime-rest-LPUDJUEP.js → abletime-rest-WFI2HWBU.js} +3 -3
  7. package/dist/agents/cursor-runner.cjs +48 -11
  8. package/dist/agents/cursor-runner.js +48 -11
  9. package/dist/{agents-6U2RQK7P.js → agents-BHUXZ7XO.js} +5 -5
  10. package/dist/{agents-PM5ICSO3.js → agents-QNIFTZPN.js} +5 -5
  11. package/dist/chunk-2GPQZZLY.js +59 -0
  12. package/dist/{chunk-ROPGQRPU.js → chunk-33KDPEK4.js} +1 -1
  13. package/dist/{chunk-BSN6DJ4L.js → chunk-3H5U4QLD.js} +5 -5
  14. package/dist/{chunk-I6HSGKMZ.js → chunk-5T4YWFLD.js} +2 -2
  15. package/dist/{chunk-U7HAVAGJ.js → chunk-6CVVNAIU.js} +2 -2
  16. package/dist/{chunk-TQRSVE7D.js → chunk-7IAMHN2N.js} +1 -1
  17. package/dist/{chunk-BMUVNTT4.js → chunk-ABOH7GBG.js} +2 -2
  18. package/dist/{chunk-OEJQK7CY.js → chunk-CBIUGGPI.js} +14 -13
  19. package/dist/{chunk-VA55JG2I.js → chunk-DEJALWKM.js} +5 -5
  20. package/dist/{chunk-LMWPVC5L.js → chunk-ETZPTOK7.js} +2 -2
  21. package/dist/{chunk-WQ4M2L44.js → chunk-HJNFK5SP.js} +16 -15
  22. package/dist/{chunk-XTPQEZZA.js → chunk-IJMUYHPT.js} +3 -3
  23. package/dist/chunk-JAT3JFOS.js +61 -0
  24. package/dist/{chunk-DGPROCE5.js → chunk-LS4FFCPL.js} +3 -3
  25. package/dist/{chunk-WY2IAB7J.js → chunk-MGJ7R7UX.js} +45 -1
  26. package/dist/{chunk-COQLZNKQ.js → chunk-PCNH74SF.js} +5 -5
  27. package/dist/{chunk-P2BSMNHB.js → chunk-PXMLMBMI.js} +1 -1
  28. package/dist/{chunk-BS3QLVPL.js → chunk-TMM4FEZ5.js} +3 -3
  29. package/dist/{chunk-2SJXQ4UX.js → chunk-ULSY2BJF.js} +45 -1
  30. package/dist/{chunk-GWFVCCJZ.js → chunk-VGNLMGBK.js} +6 -6
  31. package/dist/{chunk-PY4UCMRI.js → chunk-VQEARG5H.js} +5 -5
  32. package/dist/{conductor-MU3TYVCD.js → conductor-RBJYEF7L.js} +2 -2
  33. package/dist/{conductor-GBX6LSP2.js → conductor-WYOWFB7I.js} +2 -2
  34. package/dist/{connected-teams-JIUOSZ6C.js → connected-teams-AB7ZHJVO.js} +3 -3
  35. package/dist/{connected-teams-RU6VATCM.js → connected-teams-BJ6PMIST.js} +3 -3
  36. package/dist/{coordinator-prompt-SVVGU6AZ.js → coordinator-prompt-5DE3XBNT.js} +1 -1
  37. package/dist/{coordinator-prompt-4DJIHSE6.js → coordinator-prompt-R42WEL3T.js} +1 -1
  38. package/dist/{global-workspace-XON4YZXE.js → global-workspace-IPIEC6FM.js} +1 -1
  39. package/dist/{global-workspace-UPUDWIS6.js → global-workspace-NXMYLS34.js} +1 -1
  40. package/dist/index.cjs +300 -155
  41. package/dist/index.d.cts +16 -3
  42. package/dist/index.d.ts +16 -3
  43. package/dist/index.js +177 -98
  44. package/dist/mcp/run-stdio.cjs +121 -58
  45. package/dist/mcp/run-stdio.js +10 -10
  46. package/dist/{oauth-S3M7B475.js → oauth-DP4ZV2M2.js} +2 -2
  47. package/dist/{oauth-K6CWZEQO.js → oauth-WCUZ6Z5G.js} +2 -2
  48. package/dist/{orchestrator-6YVY6T5I.js → orchestrator-65QGA6BB.js} +7 -7
  49. package/dist/{orchestrator-CRBIW2RG.js → orchestrator-YEZV35G7.js} +7 -7
  50. package/dist/{workspaces-F76BWCSI.js → workspaces-5C5ESWPU.js} +5 -1
  51. package/dist/{workspaces-7AJ5RZ3P.js → workspaces-LIFFWK23.js} +5 -1
  52. package/package.json +1 -1
  53. package/dist/chunk-N7WZ6NIN.js +0 -41
  54. package/dist/chunk-VKQGAWHY.js +0 -40
package/dist/index.js CHANGED
@@ -198,7 +198,7 @@ import {
198
198
  worktreeBoardStatus,
199
199
  worktreeCleanupSettings,
200
200
  writeWorktreeFile
201
- } from "./chunk-WQ4M2L44.js";
201
+ } from "./chunk-HJNFK5SP.js";
202
202
  import {
203
203
  BASE_ALLOWED_TOOLS,
204
204
  BRIGHTSY_MCP_ALLOWED_TOOLS,
@@ -288,7 +288,7 @@ import {
288
288
  whichOnPath,
289
289
  worktreeMcpToolNames,
290
290
  writeInjectedMcpConfig
291
- } from "./chunk-COQLZNKQ.js";
291
+ } from "./chunk-PCNH74SF.js";
292
292
  import {
293
293
  brightsyMcpServerName,
294
294
  connectBrightsyTeam,
@@ -298,7 +298,7 @@ import {
298
298
  listBrightsyAccounts,
299
299
  listConnectedBrightsyTeams,
300
300
  switchBrightsyAccount
301
- } from "./chunk-GWFVCCJZ.js";
301
+ } from "./chunk-VGNLMGBK.js";
302
302
  import {
303
303
  BRIGHTSY_SUMMARIZE_CONTEXT_TOOL,
304
304
  CHARS_PER_CONTEXT_TOKEN,
@@ -415,7 +415,7 @@ import {
415
415
  workspaceAgentChatSummaries,
416
416
  worktreeRunPortsPath,
417
417
  wrapReviewSkillMarkdown
418
- } from "./chunk-BMUVNTT4.js";
418
+ } from "./chunk-ABOH7GBG.js";
419
419
  import {
420
420
  STDERR_EVENT_MAX_CHARS,
421
421
  STDOUT_EVENT_MAX_CHARS,
@@ -481,7 +481,7 @@ import {
481
481
  parseAbleTimeOAuthCallbackUrl,
482
482
  resolveAbleTimeOAuthHost,
483
483
  startAbleTimeOAuth
484
- } from "./chunk-XTPQEZZA.js";
484
+ } from "./chunk-IJMUYHPT.js";
485
485
  import {
486
486
  ableTimeDependencyTarget,
487
487
  commentAbleTimeTask,
@@ -506,8 +506,8 @@ import {
506
506
  toAbleTimeIssueInfo,
507
507
  updateAbleTimeTask,
508
508
  verifyAbleTimeConnection
509
- } from "./chunk-DGPROCE5.js";
510
- import "./chunk-U7HAVAGJ.js";
509
+ } from "./chunk-LS4FFCPL.js";
510
+ import "./chunk-6CVVNAIU.js";
511
511
  import {
512
512
  ABLETIME_MCP_PATH,
513
513
  ABLETIME_MCP_PM_PATH,
@@ -528,7 +528,7 @@ import {
528
528
  normalizeAbleTimeCredential,
529
529
  normalizeAbleTimeHost,
530
530
  rewriteAbleTimeError
531
- } from "./chunk-VA55JG2I.js";
531
+ } from "./chunk-DEJALWKM.js";
532
532
  import {
533
533
  LEGACY_PLAN_FILE_REL,
534
534
  PLAN_FILE_NAME,
@@ -556,6 +556,8 @@ import {
556
556
  SIDEBOARD_FORCE_STOP,
557
557
  SLACK_REPLY_FORMATTING,
558
558
  addWorkspace,
559
+ archiveRemovedWorkspaceChats,
560
+ archivesWithRemovedWorkspace,
559
561
  attachmentFromAbsolutePath,
560
562
  attachmentsFromBuffers,
561
563
  attachmentsFromWorktreePaths,
@@ -594,7 +596,7 @@ import {
594
596
  stageBuffersAsAttachments,
595
597
  syncWorkspacesFromThreads,
596
598
  takenTeamSlugsForOrchestration
597
- } from "./chunk-WY2IAB7J.js";
599
+ } from "./chunk-MGJ7R7UX.js";
598
600
  import {
599
601
  GITHUB_PR_BODY_MAX_CHARS,
600
602
  GITHUB_PR_BODY_SAFE_CHARS,
@@ -728,12 +730,13 @@ import {
728
730
  refreshBrightsyAccessToken,
729
731
  registerBrightsyOAuthClient,
730
732
  saveBrightsyConfig
731
- } from "./chunk-ROPGQRPU.js";
733
+ } from "./chunk-33KDPEK4.js";
732
734
  import {
735
+ currentHttpFetch,
733
736
  formatFetchError,
734
737
  httpFetch,
735
738
  setHttpFetchImpl
736
- } from "./chunk-N7WZ6NIN.js";
739
+ } from "./chunk-JAT3JFOS.js";
737
740
  import {
738
741
  clipMcpToolResult
739
742
  } from "./chunk-S2OOM7AU.js";
@@ -5015,7 +5018,7 @@ async function handleJobStop(params, _ctx) {
5015
5018
  return stopDetachedJob(jobCwd(rec), id, reason ? { reason } : void 0);
5016
5019
  }
5017
5020
  async function defaultTurnWait(ref, timeoutMs) {
5018
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-6YVY6T5I.js");
5021
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-65QGA6BB.js");
5019
5022
  const orch = getOrchestrator2();
5020
5023
  const thread = await orch.waitForTurn(ref, timeoutMs, {
5021
5024
  resolveIfStillRunning: true
@@ -10113,7 +10116,7 @@ function deliverPhoneTurn(opts, chatId) {
10113
10116
  });
10114
10117
  }
10115
10118
 
10116
- // src/remote/listen.ts
10119
+ // src/remote/phone-turn.ts
10117
10120
  function formatRemotePrompt(text5) {
10118
10121
  return `Phone
10119
10122
 
@@ -10122,6 +10125,29 @@ ${text5.trim()}`;
10122
10125
  function isRemoteStopCommand(text5) {
10123
10126
  return text5.trim().toLowerCase() === "stop";
10124
10127
  }
10128
+ function phoneFollowUpQueues(status) {
10129
+ return followUpBehavior() === "queue" && (status === "running" || status === "queued");
10130
+ }
10131
+ var PHONE_TURN_MS = 14 * 60 * 1e3;
10132
+ function delay(ms) {
10133
+ return new Promise((resolve) => setTimeout(resolve, ms));
10134
+ }
10135
+ async function waitForPhoneTurn(threadId, stillCurrent) {
10136
+ const deadline = Date.now() + PHONE_TURN_MS;
10137
+ while (stillCurrent() && Date.now() < deadline) {
10138
+ const thread2 = readPhoneThread(threadId) ?? readThread(threadId);
10139
+ if (!thread2) return;
10140
+ if (thread2.status === "stopped" && thread2.queue.length > 0) {
10141
+ await delay(40);
10142
+ continue;
10143
+ }
10144
+ break;
10145
+ }
10146
+ if (!stillCurrent()) return;
10147
+ const thread = readPhoneThread(threadId) ?? readThread(threadId);
10148
+ if (!thread || thread.status !== "running" && thread.status !== "queued") return;
10149
+ await getOrchestrator().waitForTurn(threadId, Math.max(1, deadline - Date.now()));
10150
+ }
10125
10151
  var handleChain2 = Promise.resolve();
10126
10152
  var inboundGeneration = 0;
10127
10153
  function enqueue(fn) {
@@ -10145,6 +10171,77 @@ function interruptRemoteCoordinator(deviceId, log = () => void 0) {
10145
10171
  return false;
10146
10172
  }
10147
10173
  }
10174
+ function runCoordinatorPrompt(opts, body, generation) {
10175
+ const current = () => generation === inboundGeneration;
10176
+ return (async () => {
10177
+ if (!current()) return;
10178
+ const agent = coerceOrchestratorAgent(opts.agent ?? resolveOrchestratorDefaults().agent);
10179
+ if (!body) return;
10180
+ if (isRemoteStopCommand(body)) {
10181
+ if (!current()) return;
10182
+ opts.onOutbound({ type: "assistant", text: REMOTE_STOPPED_REPLY });
10183
+ return;
10184
+ }
10185
+ let thread = ensureRemoteCoordinator(opts.deviceId, agent);
10186
+ thread = readThread(thread.id) ?? thread;
10187
+ const followUp = followUpBehavior();
10188
+ const orch = getOrchestrator();
10189
+ try {
10190
+ await orch.send(thread.id, formatRemotePrompt(body), { followUp });
10191
+ if (!current()) return;
10192
+ await waitForPhoneTurn(thread.id, current);
10193
+ } catch (err) {
10194
+ if (!current()) return;
10195
+ const message = err instanceof Error ? err.message : String(err);
10196
+ opts.onOutbound({ type: "assistant", text: `Sideboard failed: ${message}` });
10197
+ return;
10198
+ }
10199
+ if (!current()) return;
10200
+ thread = readThread(thread.id) ?? thread;
10201
+ if (thread.status === "stopped") return;
10202
+ const result = orch.getTurnResult(thread.id);
10203
+ const pending = extractPendingPlanQuestions(
10204
+ [...thread.messages].reverse().find((m) => m.role === "agent")?.parts
10205
+ );
10206
+ if (result.taskState === "input-required" && pending) {
10207
+ opts.onOutbound({
10208
+ type: "ask_user",
10209
+ text: result.text.trim(),
10210
+ questions: pending.questions.map((q) => ({
10211
+ question: q.question,
10212
+ options: q.options.map(
10213
+ (o) => o.description ? { label: o.label, description: o.description } : { label: o.label }
10214
+ )
10215
+ }))
10216
+ });
10217
+ return;
10218
+ }
10219
+ const reply = outboundReplyFromTurn(result, {
10220
+ inputRequired: "Sideboard is waiting for an answer.",
10221
+ canceled: REMOTE_STOPPED_REPLY,
10222
+ completedEmpty: () => "",
10223
+ failed: (detail) => detail ? `Sideboard failed: ${detail}` : "Sideboard failed before producing a result."
10224
+ });
10225
+ if (reply.trim()) opts.onOutbound({ type: "assistant", text: reply.trim() });
10226
+ })();
10227
+ }
10228
+ function beginCoordinatorPrompt(body, opts) {
10229
+ const live = body ? findRemoteCoordinator(opts.deviceId) : null;
10230
+ const fresh = live ? readThread(live.id) ?? live : null;
10231
+ if (body && !isRemoteStopCommand(body) && phoneFollowUpQueues(fresh?.status)) {
10232
+ const generation2 = inboundGeneration;
10233
+ enqueue(() => runCoordinatorPrompt(opts, body, generation2));
10234
+ return;
10235
+ }
10236
+ const generation = ++inboundGeneration;
10237
+ if (body && isRemoteStopCommand(body)) {
10238
+ interruptRemoteCoordinator(opts.deviceId, opts.onLog ?? (() => void 0));
10239
+ }
10240
+ const task = runCoordinatorPrompt(opts, body, generation);
10241
+ enqueue(() => task);
10242
+ }
10243
+
10244
+ // src/remote/listen.ts
10148
10245
  function emitOpened(opts, opened) {
10149
10246
  setPhoneOpenChat(opened.chat.id);
10150
10247
  emitControl(opts, { op: "opened", ...opened });
@@ -10414,23 +10511,27 @@ function handlePhoneControl(cmd, opts) {
10414
10511
  return;
10415
10512
  }
10416
10513
  const chatId = cmd.chatId;
10514
+ const existing = readPhoneThread(chatId);
10515
+ if (phoneFollowUpQueues(existing?.status)) {
10516
+ deliverPhoneTurn(opts, chatId);
10517
+ const generation2 = chatGeneration.get(chatId) ?? bumpChat(chatId);
10518
+ enqueueChat(chatId, () => runPhonePrompt(opts, cmd, chatId, generation2));
10519
+ return;
10520
+ }
10417
10521
  const generation = bumpChat(chatId);
10418
10522
  phoneTurnGen.set(chatId, generation);
10419
- interruptChat(chatId, log);
10420
- enqueueChat(chatId, async () => {
10421
- if (chatGeneration.get(chatId) !== generation) return;
10523
+ const task = runPhonePrompt(opts, cmd, chatId, generation);
10524
+ enqueueChat(chatId, () => task);
10525
+ }
10526
+ function runPhonePrompt(opts, cmd, chatId, generation) {
10527
+ const current = () => chatGeneration.get(chatId) === generation;
10528
+ return (async () => {
10529
+ if (!current()) return;
10422
10530
  const thread = readPhoneThread(chatId);
10423
10531
  if (!thread) {
10424
10532
  emitControl(opts, { op: "error", chatId, message: "That agent is not on this Mac." });
10425
10533
  return;
10426
10534
  }
10427
- if (thread.status === "running" || thread.status === "queued") {
10428
- try {
10429
- getOrchestrator().stop(thread.id, { clearQueue: true });
10430
- } catch {
10431
- }
10432
- }
10433
- if (chatGeneration.get(chatId) !== generation) return;
10434
10535
  const stopStream = watchPhoneStream(opts, chatId, thread.id, generation);
10435
10536
  try {
10436
10537
  try {
@@ -10438,14 +10539,19 @@ function handlePhoneControl(cmd, opts) {
10438
10539
  } catch (err) {
10439
10540
  emitControl(opts, { op: "error", chatId, message: phoneError(err) });
10440
10541
  }
10542
+ if (!current()) return;
10441
10543
  const live = readPhoneThread(thread.id) ?? thread;
10544
+ const followUp = followUpBehavior();
10442
10545
  const staged = stagePhoneTurnFiles(live.worktreePath, cmd);
10443
10546
  const text5 = cmd.text.trim() || (staged.length ? "See the attached files." : "");
10444
- const formatted = formatRemotePrompt(text5);
10445
- await getOrchestrator().send(thread.id, formatted, { attachments: staged });
10446
- await getOrchestrator().waitForTurn(thread.id, 14 * 60 * 1e3);
10547
+ await getOrchestrator().send(thread.id, formatRemotePrompt(text5), {
10548
+ attachments: staged,
10549
+ followUp
10550
+ });
10551
+ if (!current()) return;
10552
+ await waitForPhoneTurn(thread.id, current);
10447
10553
  } catch (err) {
10448
- if (chatGeneration.get(chatId) !== generation) return;
10554
+ if (!current()) return;
10449
10555
  const message = err instanceof Error ? err.message : String(err);
10450
10556
  emitControl(opts, { op: "error", chatId, message: `Sideboard failed: ${message}` });
10451
10557
  return;
@@ -10453,12 +10559,11 @@ function handlePhoneControl(cmd, opts) {
10453
10559
  stopStream();
10454
10560
  finishPhoneTurn(chatId, generation);
10455
10561
  }
10456
- if (chatGeneration.get(chatId) !== generation) return;
10562
+ if (!current()) return;
10457
10563
  emitChatTurn(opts, chatId, thread.id);
10458
- });
10564
+ })();
10459
10565
  }
10460
10566
  function handleRemoteInbound(text5, opts) {
10461
- const log = opts.onLog ?? (() => void 0);
10462
10567
  const body = text5.trim();
10463
10568
  const control = takePhoneControl(body);
10464
10569
  if (control) {
@@ -10469,64 +10574,7 @@ function handleRemoteInbound(text5, opts) {
10469
10574
  handlePhoneControl(control, opts);
10470
10575
  return;
10471
10576
  }
10472
- const generation = ++inboundGeneration;
10473
- if (body) interruptRemoteCoordinator(opts.deviceId, log);
10474
- enqueue(async () => {
10475
- if (generation !== inboundGeneration) return;
10476
- const agent = coerceOrchestratorAgent(opts.agent ?? resolveOrchestratorDefaults().agent);
10477
- if (!body) return;
10478
- if (isRemoteStopCommand(body)) {
10479
- if (generation !== inboundGeneration) return;
10480
- opts.onOutbound({ type: "assistant", text: REMOTE_STOPPED_REPLY });
10481
- return;
10482
- }
10483
- let thread = ensureRemoteCoordinator(opts.deviceId, agent);
10484
- const fresh = readThread(thread.id) ?? thread;
10485
- if (fresh.status === "running" || fresh.status === "queued") {
10486
- try {
10487
- getOrchestrator().stop(fresh.id, { clearQueue: true });
10488
- } catch {
10489
- }
10490
- }
10491
- if (generation !== inboundGeneration) return;
10492
- const orch = getOrchestrator();
10493
- try {
10494
- await orch.send(thread.id, formatRemotePrompt(body));
10495
- await orch.waitForTurn(thread.id, 14 * 60 * 1e3);
10496
- } catch (err) {
10497
- if (generation !== inboundGeneration) return;
10498
- const message = err instanceof Error ? err.message : String(err);
10499
- opts.onOutbound({ type: "assistant", text: `Sideboard failed: ${message}` });
10500
- return;
10501
- }
10502
- if (generation !== inboundGeneration) return;
10503
- thread = readThread(thread.id) ?? thread;
10504
- if (thread.status === "stopped") return;
10505
- const result = orch.getTurnResult(thread.id);
10506
- const pending = extractPendingPlanQuestions(
10507
- [...thread.messages].reverse().find((m) => m.role === "agent")?.parts
10508
- );
10509
- if (result.taskState === "input-required" && pending) {
10510
- opts.onOutbound({
10511
- type: "ask_user",
10512
- text: result.text.trim(),
10513
- questions: pending.questions.map((q) => ({
10514
- question: q.question,
10515
- options: q.options.map(
10516
- (o) => o.description ? { label: o.label, description: o.description } : { label: o.label }
10517
- )
10518
- }))
10519
- });
10520
- return;
10521
- }
10522
- const reply = outboundReplyFromTurn(result, {
10523
- inputRequired: "Sideboard is waiting for an answer.",
10524
- canceled: REMOTE_STOPPED_REPLY,
10525
- completedEmpty: () => "",
10526
- failed: (detail) => detail ? `Sideboard failed: ${detail}` : "Sideboard failed before producing a result."
10527
- });
10528
- if (reply.trim()) opts.onOutbound({ type: "assistant", text: reply.trim() });
10529
- });
10577
+ beginCoordinatorPrompt(body, opts);
10530
10578
  }
10531
10579
 
10532
10580
  // src/remote/phone-board-sync.ts
@@ -11463,15 +11511,43 @@ function sleep2(ms, signal) {
11463
11511
  signal?.addEventListener("abort", onAbort, { once: true });
11464
11512
  });
11465
11513
  }
11514
+ var RELAY_TLS_HINT = " \u2014 the TLS certificate was rejected. A work proxy often does this when Sideboard is not allowlisted, or when the app does not trust the corporate CA.";
11515
+ var RELAY_NETWORK_HINT = " Sideboard could not reach the relay. On a work computer this is often a VPN, a proxy, or an allowlist that does not include Sideboard.";
11516
+ var RELAY_NETWORK_RE = /fetch failed|Failed to fetch|ENOTFOUND|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EHOSTUNREACH|ENETUNREACH|EAI_AGAIN|EPERM|UND_ERR_|ERR_CONNECTION|ERR_NETWORK|ERR_PROXY|ERR_TUNNEL|ERR_INTERNET|ERR_BLOCKED|ERR_NAME_NOT_RESOLVED|ERR_ADDRESS_UNREACHABLE|ERR_CERT|CERT_|UNABLE_TO_GET_ISSUER|SELF_SIGNED/i;
11517
+ function relayFetchError(err, url) {
11518
+ const formatted = formatFetchError(err, url, { tlsHint: RELAY_TLS_HINT });
11519
+ if (formatted.includes(RELAY_TLS_HINT) || !RELAY_NETWORK_RE.test(formatted)) {
11520
+ return new Error(formatted);
11521
+ }
11522
+ return new Error(`${formatted}${RELAY_NETWORK_HINT}`);
11523
+ }
11524
+ async function relayFetch(fetchImpl, url, init) {
11525
+ const fn = fetchImpl ?? currentHttpFetch();
11526
+ try {
11527
+ return await fn(url, init);
11528
+ } catch (err) {
11529
+ throw relayFetchError(err, url);
11530
+ }
11531
+ }
11532
+ async function readJson2(res, url) {
11533
+ try {
11534
+ return await res.json();
11535
+ } catch {
11536
+ const kind = (res.headers.get("content-type") ?? "").includes("html") ? "an HTML page" : "a non-JSON body";
11537
+ throw new Error(
11538
+ `Relay sign-in returned HTTP ${res.status} with ${kind} (${url}). A work proxy or allowlist often answers with a block page instead of the relay.`
11539
+ );
11540
+ }
11541
+ }
11466
11542
  async function startRemoteAccountLogin(opts) {
11467
11543
  if (opts.signal?.aborted) throw new RemoteAccountLoginCancelled();
11468
11544
  const origin = (opts.origin ?? remoteAccountHttpOrigin()).replace(/\/+$/, "");
11469
- const fetchImpl = opts.fetchImpl ?? fetch;
11470
11545
  const state = randomBytes7(16).toString("hex");
11471
11546
  const timeoutMs = opts.timeoutMs ?? 5 * 6e4;
11472
11547
  const pollIntervalMs = opts.pollIntervalMs ?? 400;
11473
11548
  const linkToken = opts.linkToken?.trim() ?? "";
11474
- const started = await fetchImpl(`${origin}${REMOTE_LOGIN_PATH}`, {
11549
+ const startUrl = `${origin}${REMOTE_LOGIN_PATH}`;
11550
+ const started = await relayFetch(opts.fetchImpl, startUrl, {
11475
11551
  method: "POST",
11476
11552
  headers: { "Content-Type": "application/json" },
11477
11553
  body: JSON.stringify({
@@ -11480,9 +11556,9 @@ async function startRemoteAccountLogin(opts) {
11480
11556
  ...linkToken ? { accountToken: linkToken } : {}
11481
11557
  })
11482
11558
  });
11483
- const startBody = await started.json();
11559
+ const startBody = await readJson2(started, startUrl);
11484
11560
  if (!started.ok || !startBody.url) {
11485
- throw new Error(startBody.error || "Could not start sign-in.");
11561
+ throw new Error(startBody.error || `Could not start sign-in (HTTP ${started.status}).`);
11486
11562
  }
11487
11563
  await Promise.resolve(opts.openUrl?.(startBody.url));
11488
11564
  const deadline = Date.now() + timeoutMs;
@@ -11491,9 +11567,11 @@ async function startRemoteAccountLogin(opts) {
11491
11567
  if (opts.signal?.aborted) throw new RemoteAccountLoginCancelled();
11492
11568
  let res;
11493
11569
  try {
11494
- res = await fetchImpl(resultUrl);
11495
- } catch {
11496
- if (opts.signal?.aborted) throw new RemoteAccountLoginCancelled();
11570
+ res = await relayFetch(opts.fetchImpl, resultUrl);
11571
+ } catch (err) {
11572
+ if (opts.signal?.aborted || isRemoteAccountLoginCancelled(err)) {
11573
+ throw new RemoteAccountLoginCancelled();
11574
+ }
11497
11575
  await sleep2(pollIntervalMs, opts.signal);
11498
11576
  continue;
11499
11577
  }
@@ -11518,8 +11596,7 @@ async function startRemoteAccountLogin(opts) {
11518
11596
  }
11519
11597
  async function disconnectRemoteAccount(opts) {
11520
11598
  const origin = (opts.origin ?? remoteAccountHttpOrigin()).replace(/\/+$/, "");
11521
- const fetchImpl = opts.fetchImpl ?? fetch;
11522
- await fetchImpl(`${origin}${REMOTE_LOGOUT_PATH}`, {
11599
+ await relayFetch(opts.fetchImpl, `${origin}${REMOTE_LOGOUT_PATH}`, {
11523
11600
  method: "POST",
11524
11601
  headers: { "Content-Type": "application/json" },
11525
11602
  body: JSON.stringify({ accountToken: opts.accountToken })
@@ -12411,7 +12488,7 @@ async function continueSourceThread(threadId, prompt) {
12411
12488
  await continueOnReply(threadId, prompt);
12412
12489
  return;
12413
12490
  }
12414
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-6YVY6T5I.js");
12491
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-65QGA6BB.js");
12415
12492
  await getOrchestrator2().send(threadId, prompt);
12416
12493
  } catch {
12417
12494
  }
@@ -12870,6 +12947,8 @@ export {
12870
12947
  applyThreadIntoMain,
12871
12948
  applyTurnUsage,
12872
12949
  applyWorkspaceTags,
12950
+ archiveRemovedWorkspaceChats,
12951
+ archivesWithRemovedWorkspace,
12873
12952
  armSchedules,
12874
12953
  assertAbleTimeCredential,
12875
12954
  assertAbleTimeMcpCredential,