@coreplane/switchboard 1.216.0 → 1.216.1

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.
@@ -439,7 +439,10 @@ export default {
439
439
  : pathname === COPY_PATH
440
440
  ? // The artifact copy (artifactsCopy.ts): the R2 binding and the Slack
441
441
  // token are this Worker's; the bot only asks, with its copy bearer.
442
- await handleArtifactsCopy(inbound, {
442
+ // `forwarded`, never `inbound`: `withTraceContext` rebuilt the request
443
+ // with `new Request(inbound, …)`, which takes the body stream with it —
444
+ // `inbound.text()` is empty afterwards and the route read "not JSON" live.
445
+ await handleArtifactsCopy(forwarded, {
443
446
  bucket: env.ARTIFACTS,
444
447
  bucketName: env.ARTIFACTS_BUCKET_NAME,
445
448
  copyToken: env.ARTIFACTS_COPY_TOKEN,
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "switchboard",
3
- "version": "1.216.0",
3
+ "version": "1.216.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "switchboard",
9
- "version": "1.216.0",
9
+ "version": "1.216.1",
10
10
  "license": "Apache-2.0",
11
11
  "workspaces": [
12
12
  "web",
@@ -19000,7 +19000,7 @@
19000
19000
  },
19001
19001
  "packages/switchboard": {
19002
19002
  "name": "@coreplane/switchboard",
19003
- "version": "1.216.0",
19003
+ "version": "1.216.1",
19004
19004
  "license": "Apache-2.0",
19005
19005
  "dependencies": {
19006
19006
  "@anthropic-ai/sdk": "^0.124.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "switchboard",
3
- "version": "1.216.0",
3
+ "version": "1.216.1",
4
4
  "private": true,
5
5
  "description": "Mention it in Slack and an agent reviews the PR, ships the fix, or answers the question — on the model you choose, with its tools running where you decide.",
6
6
  "license": "Apache-2.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.216.0",
3
- "commit": "1c13717b8a2b0c59b740fd75b7d3e7304657ddb2",
4
- "builtAt": "2026-09-14T22:25:28.373Z"
2
+ "version": "1.216.1",
3
+ "commit": "2982fdfa088bb070355f48b8be547bcab2d23447",
4
+ "builtAt": "2026-09-14T22:51:50.515Z"
5
5
  }
package/dist/cli.js CHANGED
@@ -24312,6 +24312,73 @@ var init_resolve = __esm({
24312
24312
  }
24313
24313
  });
24314
24314
 
24315
+ // ../../src/core/statusCardFrame.ts
24316
+ function createCardShell(opts) {
24317
+ let label = opts.label;
24318
+ let link = opts.link;
24319
+ let frame = 0;
24320
+ let finishedAt;
24321
+ let setupLabel;
24322
+ const lead = opts.lead ?? [];
24323
+ const elapsed2 = () => formatDuration((finishedAt ?? opts.now()) - opts.startedAt, "clock");
24324
+ const headline = (icon) => `${icon} ${label} \xB7 ${elapsed2()}`;
24325
+ const closeDetail = (close, own) => [close.shape, close.queued, own, opts.footer].filter(Boolean).join("\n") || void 0;
24326
+ return {
24327
+ get label() {
24328
+ return label;
24329
+ },
24330
+ setLabel(next) {
24331
+ label = next;
24332
+ },
24333
+ setLink(next) {
24334
+ link = next;
24335
+ },
24336
+ freeze(at) {
24337
+ finishedAt = at;
24338
+ },
24339
+ setSetupLabel(next) {
24340
+ setupLabel = next;
24341
+ },
24342
+ ack() {
24343
+ const detail = lead.join("\n");
24344
+ return { title: `\u{1F440} ${label} \xB7 preparing workspace\u2026`, ...detail ? { detail } : {} };
24345
+ },
24346
+ live(parts = {}) {
24347
+ const glyph = SPINNER_GLYPHS[frame++ % SPINNER_GLYPHS.length];
24348
+ const detail = [...lead, ...parts.detail ?? []].filter(Boolean).join("\n");
24349
+ return {
24350
+ title: headline(glyph) + (setupLabel ? ` \u2014 ${setupLabel}` : "") + (parts.suffix ?? "") + (parts.notice ? ` \xB7 ${parts.notice}` : ""),
24351
+ detail: detail || void 0,
24352
+ link
24353
+ };
24354
+ },
24355
+ close(close) {
24356
+ const detail = closeDetail(close, close.kind === "done" ? close.detail : void 0);
24357
+ switch (close.kind) {
24358
+ case "done":
24359
+ return { title: headline(close.icon), detail, link };
24360
+ case "not_started":
24361
+ return { title: `${close.icon} ${label} \xB7 not started (${close.reason}) \xB7 ${elapsed2()}`, detail };
24362
+ case "refused":
24363
+ return { title: `${close.icon} ${label} \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
24364
+ case "setup_failed":
24365
+ return { title: `\u274C setup failed \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
24366
+ }
24367
+ }
24368
+ };
24369
+ }
24370
+ var SPINNER_GLYPHS, LIVE_CARD_PREFIXES, ROUTED_LABEL_PREFIX, ROUTED_CARD_FOOTER;
24371
+ var init_statusCardFrame = __esm({
24372
+ "../../src/core/statusCardFrame.ts"() {
24373
+ "use strict";
24374
+ init_formatDuration();
24375
+ SPINNER_GLYPHS = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
24376
+ LIVE_CARD_PREFIXES = [...SPINNER_GLYPHS, "\u{1F440}"];
24377
+ ROUTED_LABEL_PREFIX = "routed:";
24378
+ ROUTED_CARD_FOOTER = "reply agent:<preset> to run it another way";
24379
+ }
24380
+ });
24381
+
24315
24382
  // ../../src/core/dispatch/awaitChildren.ts
24316
24383
  function decideWait(inputs) {
24317
24384
  const { children, now, budgetEndsAt, timeoutAt, stop, followUpPending } = inputs;
@@ -24918,7 +24985,7 @@ async function routeRequest(deps, ctx) {
24918
24985
  };
24919
24986
  }
24920
24987
  function routedLabel(reason, collapsed) {
24921
- return `routed: ${reason}${collapsed ? ` (compound collapsed: ${collapsed.presets.join("+")})` : ""}`;
24988
+ return `${ROUTED_LABEL_PREFIX} ${reason}${collapsed ? ` (compound collapsed: ${collapsed.presets.join("+")})` : ""}`;
24922
24989
  }
24923
24990
  function routedPartLines(parts) {
24924
24991
  return parts.map((p) => {
@@ -24934,7 +25001,7 @@ function compoundBrief(text, parts) {
24934
25001
  ...parts.map((p, i) => `${i + 1}. \`${p.preset}\`: ${p.text}`)
24935
25002
  ].join("\n");
24936
25003
  }
24937
- var ROUTE_TEXT_CAP, ROUTE_REASON_CAP, ROUTE_MIN_OUTPUT_TOKENS, ROUTE_TOOL_NAME, ROUTE_TIMEOUT_MS, ROUTE_PART_TEXT_CAP, ROUTE_PART_LINE_CAP, COMPOUND_BRIEF_HEADING, identityOf, ROUTED_CARD_FOOTER;
25004
+ var ROUTE_TEXT_CAP, ROUTE_REASON_CAP, ROUTE_MIN_OUTPUT_TOKENS, ROUTE_TOOL_NAME, ROUTE_TIMEOUT_MS, ROUTE_PART_TEXT_CAP, ROUTE_PART_LINE_CAP, COMPOUND_BRIEF_HEADING, identityOf;
24938
25005
  var init_route = __esm({
24939
25006
  "../../src/core/dispatch/route.ts"() {
24940
25007
  "use strict";
@@ -24942,7 +25009,9 @@ var init_route = __esm({
24942
25009
  init_config2();
24943
25010
  init_types3();
24944
25011
  init_redact();
25012
+ init_statusCardFrame();
24945
25013
  init_spawn();
25014
+ init_statusCardFrame();
24946
25015
  ROUTE_TEXT_CAP = 2e3;
24947
25016
  ROUTE_REASON_CAP = 120;
24948
25017
  ROUTE_MIN_OUTPUT_TOKENS = 200;
@@ -24952,7 +25021,6 @@ var init_route = __esm({
24952
25021
  ROUTE_PART_LINE_CAP = 100;
24953
25022
  COMPOUND_BRIEF_HEADING = "Routed as a compound request";
24954
25023
  identityOf = (preset) => AGENTS[preset]?.identity;
24955
- ROUTED_CARD_FOOTER = "reply agent:<preset> to run it another way";
24956
25024
  }
24957
25025
  });
24958
25026
 
@@ -28923,71 +28991,6 @@ var init_customInstructions = __esm({
28923
28991
  }
28924
28992
  });
28925
28993
 
28926
- // ../../src/core/statusCardFrame.ts
28927
- function createCardShell(opts) {
28928
- let label = opts.label;
28929
- let link = opts.link;
28930
- let frame = 0;
28931
- let finishedAt;
28932
- let setupLabel;
28933
- const lead = opts.lead ?? [];
28934
- const elapsed2 = () => formatDuration((finishedAt ?? opts.now()) - opts.startedAt, "clock");
28935
- const headline = (icon) => `${icon} ${label} \xB7 ${elapsed2()}`;
28936
- const closeDetail = (close, own) => [close.shape, close.queued, own, opts.footer].filter(Boolean).join("\n") || void 0;
28937
- return {
28938
- get label() {
28939
- return label;
28940
- },
28941
- setLabel(next) {
28942
- label = next;
28943
- },
28944
- setLink(next) {
28945
- link = next;
28946
- },
28947
- freeze(at) {
28948
- finishedAt = at;
28949
- },
28950
- setSetupLabel(next) {
28951
- setupLabel = next;
28952
- },
28953
- ack() {
28954
- const detail = lead.join("\n");
28955
- return { title: `\u{1F440} ${label} \xB7 preparing workspace\u2026`, ...detail ? { detail } : {} };
28956
- },
28957
- live(parts = {}) {
28958
- const glyph = SPINNER_GLYPHS[frame++ % SPINNER_GLYPHS.length];
28959
- const detail = [...lead, ...parts.detail ?? []].filter(Boolean).join("\n");
28960
- return {
28961
- title: headline(glyph) + (setupLabel ? ` \u2014 ${setupLabel}` : "") + (parts.suffix ?? "") + (parts.notice ? ` \xB7 ${parts.notice}` : ""),
28962
- detail: detail || void 0,
28963
- link
28964
- };
28965
- },
28966
- close(close) {
28967
- const detail = closeDetail(close, close.kind === "done" ? close.detail : void 0);
28968
- switch (close.kind) {
28969
- case "done":
28970
- return { title: headline(close.icon), detail, link };
28971
- case "not_started":
28972
- return { title: `${close.icon} ${label} \xB7 not started (${close.reason}) \xB7 ${elapsed2()}`, detail };
28973
- case "refused":
28974
- return { title: `${close.icon} ${label} \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
28975
- case "setup_failed":
28976
- return { title: `\u274C setup failed \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
28977
- }
28978
- }
28979
- };
28980
- }
28981
- var SPINNER_GLYPHS, LIVE_CARD_PREFIXES;
28982
- var init_statusCardFrame = __esm({
28983
- "../../src/core/statusCardFrame.ts"() {
28984
- "use strict";
28985
- init_formatDuration();
28986
- SPINNER_GLYPHS = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
28987
- LIVE_CARD_PREFIXES = [...SPINNER_GLYPHS, "\u{1F440}"];
28988
- }
28989
- });
28990
-
28991
28994
  // ../../src/core/statusCoalescer.ts
28992
28995
  function coalesceStatus(inner, minIntervalMs, now = Date.now, schedule = setTimeout) {
28993
28996
  let lastSentAt = -Infinity;
@@ -35969,9 +35972,12 @@ function findOrphanedCards(input) {
35969
35972
  }
35970
35973
  function interruptedCardFrame(cardText) {
35971
35974
  const label = cardText.replace(LIVE_GLYPH_PREFIX, "").replace(SHUTDOWN_NOTICE_SUFFIX, "").replace(ACTIVITY_SUFFIX, "").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&").trim();
35975
+ const detail = "The bot restarted (a deploy) while this run was in flight, so the run was lost and this card stopped updating. Re-send your request to run it again.";
35976
+ const routed = label.includes(` \xB7 ${ROUTED_LABEL_PREFIX}`);
35972
35977
  return {
35973
35978
  title: `\u274C interrupted \xB7 ${label}`,
35974
- detail: "The bot restarted (a deploy) while this run was in flight, so the run was lost and this card stopped updating. Re-send your request to run it again."
35979
+ detail: routed ? `${detail}
35980
+ ${ROUTED_CARD_FOOTER}` : detail
35975
35981
  };
35976
35982
  }
35977
35983
  async function catchUpMissedMentions(opts) {
@@ -36282,9 +36288,14 @@ async function closeReclaimedCards(client, closures, warn = console.warn) {
36282
36288
  let closed = 0;
36283
36289
  for (const c of closures) {
36284
36290
  if (!c.card || !(c.status in glyph)) continue;
36291
+ const detail = c.status === "interrupted" ? c.note ?? "The bot restarted while this run was in flight and it could not be resumed." : "The bot restarted after this run replied; its record is complete.";
36285
36292
  const frame = {
36286
36293
  title: `${glyph[c.status]} ${c.agent ?? "run"} \xB7 ${c.status.replace("_", " ")}`,
36287
- detail: c.status === "interrupted" ? c.note ?? "The bot restarted while this run was in flight and it could not be resumed." : "The bot restarted after this run replied; its record is complete."
36294
+ // A routed run's close ends with the override footer wherever it is
36295
+ // written: this is the close a person most needs it on — the run was
36296
+ // cut by a deploy, and `agent:<preset>` in a reply is how to run it again.
36297
+ detail: c.routed ? `${detail}
36298
+ ${ROUTED_CARD_FOOTER}` : detail
36288
36299
  };
36289
36300
  try {
36290
36301
  await client.chat.update({ channel: c.card.channel, ts: c.card.ts, ...render2(frame) });
@@ -36322,6 +36333,7 @@ var RENDER_DETAIL_RAW_MAX, liveCards, liveCardKey, foreignLiveCards, foreignLive
36322
36333
  var init_statusCard = __esm({
36323
36334
  "../../src/channels/slack/statusCard.ts"() {
36324
36335
  "use strict";
36336
+ init_statusCardFrame();
36325
36337
  init_slackEscape();
36326
36338
  RENDER_DETAIL_RAW_MAX = 900;
36327
36339
  liveCards = /* @__PURE__ */ new Set();
@@ -39712,6 +39724,9 @@ function prUrlOf(events) {
39712
39724
  for (const e of events) if (e.type === "pr_opened" && typeof e.url === "string") url = e.url;
39713
39725
  return url;
39714
39726
  }
39727
+ function routedOf(events) {
39728
+ return events.some((e) => e.type === "run_meta" && e.agentSource === "route");
39729
+ }
39715
39730
  async function reclaimRuns(opts) {
39716
39731
  const { ledger, gen } = opts;
39717
39732
  const now = opts.now ?? Date.now;
@@ -39786,6 +39801,7 @@ async function reclaimRuns(opts) {
39786
39801
  events: events.length,
39787
39802
  ...row.meta.agent !== void 0 ? { agent: row.meta.agent } : {},
39788
39803
  ...prUrl2 !== void 0 ? { prUrl: prUrl2 } : {},
39804
+ ...routedOf(events) ? { routed: true } : {},
39789
39805
  ...status3 === "interrupted" ? { note: closureNote(row.meta.agent, prUrl2) } : {}
39790
39806
  });
39791
39807
  log(
@@ -42787,7 +42803,8 @@ async function runBot() {
42787
42803
  status: c.status,
42788
42804
  agent: c.agent,
42789
42805
  card: c.card,
42790
- ...c.note ? { note: c.note } : {}
42806
+ ...c.note ? { note: c.note } : {},
42807
+ ...c.routed ? { routed: true } : {}
42791
42808
  })),
42792
42809
  (w) => console.warn(w)
42793
42810
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreplane/switchboard",
3
- "version": "1.216.0",
3
+ "version": "1.216.1",
4
4
  "description": "Mention it in Slack and an agent reviews the PR, ships the fix, or answers the question — on the model you choose, with its tools running where you decide.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://openswitchboard.dev",