@coreplane/switchboard 1.263.0 → 1.265.0

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.
@@ -435,8 +435,10 @@ workspaceDir: ./workspaces
435
435
  # integer >= 14 (the loop's reserve plus one round). `maxMinutes` is the ship
436
436
  # preset's declared budget: a channel or user `boundary.maxMinutes` and a
437
437
  # per-message `budget:` directive clip it like any preset's, and the card says
438
- # so. Defaults shown; `maxRounds` must be an integer >= 1; any other key under
439
- # `ship` fails the load by name.
438
+ # so. An unfinished pipeline keeps only its remaining rounds and minutes on
439
+ # continuation. A new task after merge-ready starts with fresh caps, even when
440
+ # it adopts that pull request. Defaults shown; `maxRounds` must be an integer
441
+ # >= 1; any other key under `ship` fails the load by name.
440
442
  # ship:
441
443
  # maxRounds: 3 # review rounds per unit
442
444
  # maxMinutes: 240 # the ship preset's wall-clock budget in minutes (the registry's default)
@@ -57,7 +57,12 @@ export async function publishPrImage(
57
57
  if (!object) return json(404, { error: "artifact not found" });
58
58
  let bytes: Uint8Array;
59
59
  try {
60
- bytes = await readPrImage({ ...object, contentType: object.httpMetadata?.contentType ?? "" });
60
+ // R2ObjectBody is a runtime object; its size and body need not be enumerable.
61
+ bytes = await readPrImage({
62
+ size: object.size,
63
+ body: object.body,
64
+ contentType: object.httpMetadata?.contentType ?? "",
65
+ });
61
66
  } catch {
62
67
  // A storage stream can fail with internal paths or stack details; the caller
63
68
  // needs only the stable validation result.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "switchboard",
3
- "version": "1.263.0",
3
+ "version": "1.265.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "switchboard",
9
- "version": "1.263.0",
9
+ "version": "1.265.0",
10
10
  "license": "Apache-2.0",
11
11
  "workspaces": [
12
12
  "web",
@@ -21060,7 +21060,7 @@
21060
21060
  },
21061
21061
  "packages/switchboard": {
21062
21062
  "name": "@coreplane/switchboard",
21063
- "version": "1.263.0",
21063
+ "version": "1.265.0",
21064
21064
  "license": "Apache-2.0",
21065
21065
  "dependencies": {
21066
21066
  "@earendil-works/pi-ai": "0.85.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "switchboard",
3
- "version": "1.263.0",
3
+ "version": "1.265.0",
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.263.0",
3
- "commit": "45ff7fda11fb77898cd9677f0c6e42efd4f9ffbf",
4
- "builtAt": "2026-09-26T01:33:01.056Z"
2
+ "version": "1.265.0",
3
+ "commit": "39607a27b4b5751330311c08f9068a6bc007ca80",
4
+ "builtAt": "2026-09-26T04:13:47.389Z"
5
5
  }
@@ -1050,6 +1050,7 @@ async function runUnit(
1050
1050
  generated: plan.generated,
1051
1051
  ...(plan.runPageBase !== undefined ? { runPageBase: plan.runPageBase } : {}),
1052
1052
  ...(resume !== undefined ? { resume } : {}),
1053
+ ...(row?.publication !== undefined && resume === undefined && lastPush === undefined ? { freshAdopt: true } : {}),
1053
1054
  ...(lastPush !== undefined ? { lastPush } : {}),
1054
1055
  ...(session !== undefined ? { session } : {}),
1055
1056
  ...(row?.recovery !== undefined
@@ -1167,6 +1167,9 @@ export interface UnitPipelineInput {
1167
1167
  idleDays?: number;
1168
1168
  /** Resume at review: an open pull request of ship's own the requester named. */
1169
1169
  resume?: { pr: number; headSha?: string; url?: string };
1170
+ /** A task adopted an existing PR without a prior coding push. Its old
1171
+ * approval and checks cannot answer this task, so pre-check starts coding. */
1172
+ freshAdopt?: boolean;
1170
1173
  /** The head the previous attempt's coding child last pushed (a
1171
1174
  * `review_pending` ending's `headSha`, carried on the unit's row): when the
1172
1175
  * pre-check finds the open pull request still at exactly this head, there is
@@ -1995,10 +1998,12 @@ function settleCoding(
1995
1998
  // final observed head. Only then may a fresh remote read decide readiness.
1996
1999
  if (round.kind === "findings" && facts.status === "completed") {
1997
2000
  const issued = next.findingsByRound[round.index] ?? [];
1998
- const matched = matchDispositions(issued, facts.dispositions ?? []).matched;
2001
+ const { matched, dropped } = matchDispositions(issued, facts.dispositions ?? []);
1999
2002
  const missingOutputs = issued
2000
2003
  .filter((finding) => !matched.some((disposition) => disposition.findingId === finding.id))
2001
2004
  .map((finding) => `missing disposition for ${finding.id}`);
2005
+ if (missingOutputs.length > 0 && dropped.length > 0)
2006
+ missingOutputs.push(`submitted IDs with no matching finding: ${dropped.join(", ")}`);
2002
2007
  if (facts.description !== true) missingOutputs.push("missing updated pull request description");
2003
2008
  const observedHead = fullHead(facts.headSha);
2004
2009
  if (observedHead === undefined) missingOutputs.push("missing final observed commit");
@@ -3083,6 +3088,8 @@ export function applyReturn(s: UnitPipelineState, ret: StepReturn): Transition {
3083
3088
  };
3084
3089
  return nextReview(adopted);
3085
3090
  }
3091
+ if (s.input.freshAdopt === true)
3092
+ return enterRound({ ...clocked, pr: { number: r.pr.prNumber, url: r.pr.url } }, { index: 0, kind: "coding" });
3086
3093
  const branchHead = normalizeHead(r.pr.branchHead);
3087
3094
  const lastPush = normalizeHead(s.input.lastPush);
3088
3095
  const atBranchHead = head !== undefined && branchHead !== undefined && sameCommit(head, branchHead);
@@ -3121,6 +3128,12 @@ export function applyReturn(s: UnitPipelineState, ret: StepReturn): Transition {
3121
3128
  return nextReview(adopted);
3122
3129
  }
3123
3130
  }
3131
+ if (s.input.freshAdopt === true)
3132
+ return end(clocked, {
3133
+ kind: "aborted",
3134
+ reason: `⚠️ The adopted pull request on ${s.input.repo} is no longer open, so coding did not start.`,
3135
+ reviewRounds: s.reviewRounds,
3136
+ });
3124
3137
  return { state: { ...clocked, phase: { at: "branch" } }, notes: [] };
3125
3138
  }
3126
3139
  case "branch": {
package/dist/cli.js CHANGED
@@ -36722,13 +36722,16 @@ async function resolveRepoContext(msg, history = [], probe, residentSlugs, recor
36722
36722
  rejected = void 0;
36723
36723
  unverified = void 0;
36724
36724
  }
36725
+ const bareNumberText = !s.pr && repo === records?.pr?.repo ? /\b(?:PR|pull request)\s*#(\d+)\b/i.exec(unwrapSlack(msg.text).replace(CODE_SPAN, " "))?.[1] : void 0;
36726
+ const bareNumber = bareNumberText === void 0 ? void 0 : Number(bareNumberText);
36727
+ const namedPr = s.pr ?? (repo && bareNumber !== void 0 && Number.isSafeInteger(bareNumber) && bareNumber > 0 ? { repo, number: bareNumber } : void 0);
36725
36728
  let headSha;
36726
36729
  let baseRef;
36727
36730
  let prSize;
36728
36731
  let facts2;
36729
36732
  let closedPr;
36730
- if (s.pr && repo === s.pr.repo) {
36731
- const head = await prHead(s.pr).catch(() => void 0);
36733
+ if (namedPr && repo === namedPr.repo) {
36734
+ const head = await prHead(namedPr).catch(() => void 0);
36732
36735
  if (head?.ref && head.state === "open") {
36733
36736
  ref = head.ref;
36734
36737
  refFromPr = true;
@@ -36739,7 +36742,7 @@ async function resolveRepoContext(msg, history = [], probe, residentSlugs, recor
36739
36742
  facts2 = head?.facts;
36740
36743
  if (head?.state === "closed")
36741
36744
  closedPr = {
36742
- number: s.pr.number,
36745
+ number: namedPr.number,
36743
36746
  merged: head.merged,
36744
36747
  ...head.mergedAt !== void 0 ? { mergedAt: head.mergedAt } : {}
36745
36748
  };
@@ -36750,16 +36753,16 @@ async function resolveRepoContext(msg, history = [], probe, residentSlugs, recor
36750
36753
  else if (rejected) out.rejectedRepo = rejected;
36751
36754
  if (ref) out.ref = ref;
36752
36755
  if (refFromPr) out.refFromPr = true;
36753
- if (repo && s.pr && repo === s.pr.repo) {
36754
- out.pr = s.pr.number;
36756
+ if (repo && namedPr && repo === namedPr.repo) {
36757
+ out.pr = namedPr.number;
36755
36758
  out.prFromMessage = true;
36756
- if (isThreadOwnPr(records, repo, s.pr.number)) out.prIsThreadOwn = true;
36759
+ if (isThreadOwnPr(records, repo, namedPr.number)) out.prIsThreadOwn = true;
36757
36760
  if (headSha) out.headSha = headSha;
36758
36761
  if (baseRef) out.baseRef = baseRef;
36759
36762
  if (prSize) out.prSize = prSize;
36760
36763
  if (facts2) out.prDescription = facts2;
36761
36764
  if (closedPr) out.closedPr = closedPr;
36762
- } else if (repo && !s.pr) {
36765
+ } else if (repo && !namedPr) {
36763
36766
  const inherited = inheritedPr(thread, records, repo);
36764
36767
  if (inherited) {
36765
36768
  const head = await openPrHeadSha(inherited);
@@ -40789,24 +40792,38 @@ function instanceOf(runs) {
40789
40792
  return void 0;
40790
40793
  }
40791
40794
  async function ownerOf2(runs, unitsOf, threadKey) {
40792
- const live = runs.find((r) => !r.finished);
40795
+ const live = runs.find((r) => !r.finished && r.hosted !== true);
40793
40796
  if (live !== void 0) return { kind: "live", run: live };
40797
+ const hosted = runs.find((r) => !r.finished && r.hosted === true);
40794
40798
  const instanceId = instanceOf(runs);
40799
+ let releasedPr;
40795
40800
  if (instanceId !== void 0) {
40796
40801
  const units = await unitsOf(instanceId).catch(() => []);
40797
40802
  const unit = units.find((u) => u.threadKey === threadKey && u.ending === void 0);
40798
40803
  if (unit !== void 0) return { kind: "unit", instanceId, unit };
40804
+ if (hosted !== void 0) return { kind: "live", run: hosted };
40799
40805
  const ended = units.filter(
40800
- (u) => u.threadKey === threadKey && u.ending !== void 0 && u.ending.kind !== "merged" && u.ending.kind !== "already_landed"
40806
+ (u) => u.threadKey === threadKey && u.ending !== void 0 && u.ending.kind !== "merged" && u.ending.kind !== "already_landed" && // A completed, publication-bound PR is new work on the next reply.
40807
+ // Keep older rows without that binding on the guarded recovery path.
40808
+ (u.ending.kind !== "merge_ready" || u.publication === void 0)
40801
40809
  );
40802
40810
  const ship = runs.find((r) => r.instanceId === instanceId && r.finished);
40803
40811
  if (ended.length === 1 && ship !== void 0) return { kind: "pipeline", instanceId, run: ship, unit: ended[0] };
40804
40812
  if (ended.length > 1 && ship !== void 0)
40805
40813
  return { kind: "pipeline_ambiguous", instanceId, run: ship, units: ended };
40814
+ const released = units.filter((u) => {
40815
+ const binding = u.publication;
40816
+ return u.threadKey === threadKey && u.instanceId === instanceId && u.ending?.kind === "merge_ready" && binding !== void 0 && u.pr?.number === binding.pr && u.branch === binding.headRef && u.branch === binding.publicationRef && binding.owner.instanceId === instanceId && binding.owner.unit === u.unit && (u.lastPush === void 0 || u.lastPush === binding.expectedHeadSha);
40817
+ });
40818
+ if (released.length === 1) {
40819
+ const unit2 = released[0];
40820
+ releasedPr = { repo: unit2.publication.repo, number: unit2.publication.pr, at: unit2.ending.at };
40821
+ }
40806
40822
  }
40823
+ if (hosted !== void 0) return { kind: "live", run: hosted };
40807
40824
  const agent = stickyAgentOf(runs);
40808
- if (agent !== void 0) return { kind: "session", agent };
40809
- return { kind: "none" };
40825
+ if (agent !== void 0) return { kind: "session", agent, ...releasedPr ? { releasedPr } : {} };
40826
+ return { kind: "none", ...releasedPr ? { releasedPr } : {} };
40810
40827
  }
40811
40828
  async function shipRequestOf(service, runId3) {
40812
40829
  const result = await service.getRun(runId3, { include: "messages" }).catch(() => void 0);
@@ -46057,7 +46074,7 @@ var init_submit = __esm({
46057
46074
  submitDispositionsTool = {
46058
46075
  name: "submit_dispositions",
46059
46076
  failsInText: true,
46060
- description: "Record one disposition per review finding after addressing them: `fixed` (the finding is addressed in your pushed code) or `declined` (deliberately not doing it \u2014 the note says why). `findingId` is the finding's stable id from the review (F1, F2, \u2026) \u2014 use exactly those ids; an id the review never issued answers nothing and is dropped when the plan runner reads your record. Every finding gets exactly one entry, every severity included (nits too). Call it once with the complete set after your last push; a later call replaces the earlier one. The set rides this run's record, where the plan runner reads it for the re-review.",
46077
+ description: "Record one disposition per review finding after addressing them: `fixed` (the finding is addressed in your pushed code) or `declined` (deliberately not doing it \u2014 the note says why). `findingId` is the finding's stable id printed in the findings. Copy it exactly, including check ids such as `check:CI / checks (test)`; do not replace a check id with `F1`. An id the review never issued answers nothing and is dropped when the plan runner reads your record. Every finding gets exactly one entry, every severity included (nits too). Call it once with the complete set after your last push; a later call replaces the earlier one. The set rides this run's record, where the plan runner reads it for the re-review.",
46061
46078
  inputSchema: {
46062
46079
  type: "object",
46063
46080
  properties: {
@@ -46067,7 +46084,10 @@ var init_submit = __esm({
46067
46084
  items: {
46068
46085
  type: "object",
46069
46086
  properties: {
46070
- findingId: { type: "string", description: `The finding's stable id from the review (e.g. "F1")` },
46087
+ findingId: {
46088
+ type: "string",
46089
+ description: 'Copy the exact id in the findings (e.g. "F1" or "check:CI / checks (test)")'
46090
+ },
46071
46091
  disposition: { type: "string", enum: ["fixed", "declined"], description: "fixed | declined" },
46072
46092
  note: { type: "string", description: "One line: what was done, or why it was declined" }
46073
46093
  },
@@ -46083,7 +46103,7 @@ var init_submit = __esm({
46083
46103
  if (!ctx.onDispositions) return "no run is recording dispositions here";
46084
46104
  ctx.onDispositions(parsed.dispositions);
46085
46105
  const drops = parsed.dropped.length ? ` (dropped: ${parsed.dropped.join("; ")})` : "";
46086
- return `dispositions recorded: ${parsed.dispositions.length}${drops}; a later call replaces this one`;
46106
+ return `dispositions recorded: ${parsed.dispositions.length}${drops}; IDs are checked against the findings by the plan runner; a later call replaces this one`;
46087
46107
  }
46088
46108
  };
46089
46109
  submitPrDescriptionTool = {
@@ -50273,19 +50293,36 @@ function judgeBashCommand(command2, ctx) {
50273
50293
  if (MERGE_OR_APPROVE.test(command2)) {
50274
50294
  return refused4("merge/approve \u2014 a coding run never merges or approves a pull request");
50275
50295
  }
50296
+ const pushCommand = withoutShellContinuations(command2);
50276
50297
  if (ctx.identity !== "write") {
50277
- if (ANY_PUSH.test(command2)) return refused4("read-only \u2014 a read-identity run never pushes");
50298
+ if (ANY_PUSH.test(pushCommand)) return refused4("read-only \u2014 a read-identity run never pushes");
50278
50299
  if (GH_WRITE_VERB.test(command2) || GH_API_WRITE.test(command2) || CURL_GITHUB_WRITE.test(command2)) {
50279
50300
  return refused4("read-only \u2014 a read-identity run never writes to GitHub");
50280
50301
  }
50281
50302
  return allowed;
50282
50303
  }
50283
- for (const match of command2.matchAll(GIT_PUSH)) {
50304
+ for (const match of pushCommand.matchAll(GIT_PUSH)) {
50284
50305
  const verdict = judgePush(match[1], ctx);
50285
50306
  if (verdict.verdict !== "allowed") return verdict;
50286
50307
  }
50287
50308
  return allowed;
50288
50309
  }
50310
+ function withoutShellContinuations(command2) {
50311
+ let result = "";
50312
+ let quote3;
50313
+ for (let i = 0; i < command2.length; i++) {
50314
+ const char = command2[i];
50315
+ if (char === "\\" && quote3 !== "'" && i + 1 < command2.length) {
50316
+ const next = command2[++i];
50317
+ if (next !== "\n") result += char + next;
50318
+ continue;
50319
+ }
50320
+ if (char === quote3) quote3 = void 0;
50321
+ else if (quote3 === void 0 && (char === "'" || char === '"')) quote3 = char;
50322
+ result += char;
50323
+ }
50324
+ return result;
50325
+ }
50289
50326
  function judgeBashTimeout(timeout, ctx) {
50290
50327
  if (!ctx.loopEndsIn || typeof timeout !== "number" || !Number.isFinite(timeout) || timeout <= 0) return allowed;
50291
50328
  const leftMs = ctx.loopEndsIn();
@@ -50396,8 +50433,11 @@ var init_toolRules = __esm({
50396
50433
  ENV_DUMP = /(^|[;&|(]\s*)((printenv|env)(\s+-[A-Za-z0-9-]+)*|export\s+-p|declare\s+-[a-zA-Z]*[px][a-zA-Z]*|set)\s*($|[|;&>)])|\/proc\/(self|\d+)\/environ|process\.env(?![.[\w])/;
50397
50434
  CREDENTIAL_VAR = /\$\{?[A-Z][A-Z0-9_]*(_API_KEY|_TOKEN|_SECRET|_BEARER|_PASSWORD)\b|printenv\s+[A-Z][A-Z0-9_]*(_API_KEY|_TOKEN|_SECRET|_BEARER|_PASSWORD)\b/;
50398
50435
  MERGE_OR_APPROVE = /\bgh\s+pr\s+(merge|review)\b|\/pulls\/\d+\/(merge|reviews)\b/;
50399
- GIT_THEN_PUSH = String.raw`\bgit(?:\s+(?:-C\s+\S+|--git-dir=\S+|--work-tree=\S+|-c\s+\S+|--no-pager))*\s+push\b`;
50400
- GIT_PUSH = new RegExp(`${GIT_THEN_PUSH}((?:[^;&|]|(?<=[<>])&|&(?=>))*)`, "g");
50436
+ GIT_THEN_PUSH = String.raw`\bgit(?:[ \t]+(?:-C[ \t]+\S+|--git-dir=\S+|--work-tree=\S+|-c[ \t]+\S+|--no-pager))*[ \t]+push\b`;
50437
+ GIT_PUSH = new RegExp(
50438
+ GIT_THEN_PUSH + String.raw`((?:"(?:\\[\s\S]|[^"\\])*"|'[^']*'|\\[^\n]|[^\n;&|'"\\]|(?<=[<>])&|&(?=>))*)`,
50439
+ "g"
50440
+ );
50401
50441
  ANY_PUSH = new RegExp(GIT_THEN_PUSH);
50402
50442
  GH_WRITE_VERB = /\bgh\s+(pr|issue)\s+(comment|create|edit|close|reopen|ready|lock|unlock|review|merge|delete|transfer|pin|unpin)\b/;
50403
50443
  WRITE_METHOD = "(POST|post|PATCH|patch|PUT|put|DELETE|delete)";
@@ -56711,7 +56751,7 @@ async function dispatch(deps, msg, io, opts = {}) {
56711
56751
  // offers no steer line, the executor folds a steer bind like any
56712
56752
  // other, and the fold runs on to the seed refusal below, which
56713
56753
  // names the unit threads to reply in.
56714
- pageOwner.run.instanceId !== void 0 ? { kind: "live" } : { kind: "live", runId: pageOwner.run.id }
56754
+ pageOwner.run.hosted === true ? { kind: "live" } : { kind: "live", runId: pageOwner.run.id }
56715
56755
  ) : pageOwner?.kind === "unit" ? { kind: "unit", unit: pageOwner.unit.unit } : pageOwner?.kind === "pipeline" ? { kind: "pipeline", unit: pageOwner.unit.unit } : pageOwner?.kind === "pipeline_ambiguous" ? { kind: "pipeline", unit: pageOwner.units.map((unit) => unit.unit).join(", ") } : void 0;
56716
56756
  operatorEvent = await root.span(
56717
56757
  "dispatch.operator",
@@ -56777,7 +56817,8 @@ async function dispatch(deps, msg, io, opts = {}) {
56777
56817
  );
56778
56818
  };
56779
56819
  const stickyAgent = thread ? stickyAgentOf(thread) : void 0;
56780
- const threadPr = thread ? threadPrOf(thread) : void 0;
56820
+ const laterPr = (runPr, releasedPr) => releasedPr !== void 0 && (runPr === void 0 || releasedPr.at > runPr.at) ? releasedPr : runPr;
56821
+ let threadPr = laterPr(thread ? threadPrOf(thread) : void 0, pageOwner?.releasedPr);
56781
56822
  const inheritedRepo = operatorRepo ?? (thread ? newestFinishedRunOf(thread)?.repo : void 0) ?? deps.config.scopes(msg.channelId, msg.userId).channel.repo;
56782
56823
  const historicalRoutePreset = restart?.row.meta.route?.preset;
56783
56824
  const resolveCurrent = () => resolveRun(deps, {
@@ -56798,8 +56839,9 @@ async function dispatch(deps, msg, io, opts = {}) {
56798
56839
  const threadLive = admission.get(msg.threadKey) !== void 0 || !resume && !restart && deps.threadsElsewhere.get(msg.threadKey) !== void 0;
56799
56840
  if (thread && !threadLive && deps.coordinatorInstances !== void 0) {
56800
56841
  const owner = pageOwner ?? await ownerOf2(thread, (id) => deps.coordinatorInstances.listUnits(id), msg.threadKey);
56801
- if (owner.kind === "live" && owner.run.instanceId !== void 0) {
56802
- const units = await deps.coordinatorInstances.listUnits(owner.run.instanceId).catch(() => []);
56842
+ threadPr = laterPr(threadPr, owner.releasedPr);
56843
+ if (owner.kind === "live" && owner.run.hosted === true) {
56844
+ const units = owner.run.instanceId === void 0 ? [] : await deps.coordinatorInstances.listUnits(owner.run.instanceId).catch(() => []);
56803
56845
  const open2 = units.filter((u) => u.ending === void 0);
56804
56846
  await refuse3(
56805
56847
  refusalOf(
@@ -72938,7 +72980,7 @@ function findingsRequest(input) {
72938
72980
 
72939
72981
  A person answered the human-gated finding. Treat the finding and this answer together as the fix brief:
72940
72982
  ${input.answers.join("\n\n")}` : "";
72941
- return `The review of ${input.where} requested changes. Load the \`address-review-findings\` skill and address every finding below, nits included: record one disposition per finding with submit_dispositions (fixed or declined, with a note), squash to coherent commits, resubmit the pull request description with submit_pr_description, and push the branch. Never merge and never approve.
72983
+ return `The review of ${input.where} requested changes. Load the \`address-review-findings\` skill and address every finding below, nits included: record one disposition per finding with submit_dispositions (fixed or declined, with a note). Copy each finding ID exactly, including any \`check:\u2026\` ID; never substitute an \`F1\` ID for a check. Squash to coherent commits, resubmit the pull request description with submit_pr_description, and push the branch. Never merge and never approve.
72942
72984
 
72943
72985
  Findings:
72944
72986
  ${findings}${answers}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreplane/switchboard",
3
- "version": "1.263.0",
3
+ "version": "1.265.0",
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",