@botbuddy/cli 1.59.8 → 1.59.9

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.
@@ -1,7 +1,7 @@
1
1
  {
2
- "release_version": "1.59.8",
3
- "source_commit": "d72599a3ac43155a4d66e30b2d73e5f2a46cf956",
4
- "source_sha256": "5ccca5bc66c82f02e856a25c0cedf9056f69b3e72b95a668dc62a3dff4a0f72f",
2
+ "release_version": "1.59.9",
3
+ "source_commit": "d9c73efb211e953ac2d57257a0d7d3cd21660d67",
4
+ "source_sha256": "57b561506694e9a2d326bba24731ab1b0354ef38c509b452686b8a450b59bd4b",
5
5
  "target": "darwin-arm64",
6
- "sha256": "24810c0fd70f40e77d860b0c247f1a7112a6a2a09b8754c83c7ca50b023e38c1"
6
+ "sha256": "ad8d7b6e3255d85f1c1237ae1b6bbd0a6b359b7909fba60b4819566bd7362c31"
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
- "release_version": "1.59.8",
3
- "source_commit": "d72599a3ac43155a4d66e30b2d73e5f2a46cf956",
4
- "source_sha256": "5ccca5bc66c82f02e856a25c0cedf9056f69b3e72b95a668dc62a3dff4a0f72f",
2
+ "release_version": "1.59.9",
3
+ "source_commit": "d9c73efb211e953ac2d57257a0d7d3cd21660d67",
4
+ "source_sha256": "57b561506694e9a2d326bba24731ab1b0354ef38c509b452686b8a450b59bd4b",
5
5
  "target": "linux-x64",
6
- "sha256": "61b9f79104394a9fe11e43b25cf3aa3c84dc1538f44c4439b7ed0555b8e8b858"
6
+ "sha256": "bf2f3a46ef151ace3e5b21633c03dc1824bee2e42fc6edd8f6898ca35d48f10c"
7
7
  }
@@ -1,21 +1,21 @@
1
1
  {
2
2
  "schema_version": 1,
3
- "release_version": "1.59.8",
4
- "source_commit": "d72599a3ac43155a4d66e30b2d73e5f2a46cf956",
5
- "source_sha256": "5ccca5bc66c82f02e856a25c0cedf9056f69b3e72b95a668dc62a3dff4a0f72f",
3
+ "release_version": "1.59.9",
4
+ "source_commit": "d9c73efb211e953ac2d57257a0d7d3cd21660d67",
5
+ "source_sha256": "57b561506694e9a2d326bba24731ab1b0354ef38c509b452686b8a450b59bd4b",
6
6
  "targets": {
7
7
  "darwin-arm64": {
8
8
  "goos": "darwin",
9
9
  "goarch": "arm64",
10
10
  "binary": "daemon/bin/darwin-arm64/botbuddy-daemon",
11
- "sha256": "24810c0fd70f40e77d860b0c247f1a7112a6a2a09b8754c83c7ca50b023e38c1",
11
+ "sha256": "ad8d7b6e3255d85f1c1237ae1b6bbd0a6b359b7909fba60b4819566bd7362c31",
12
12
  "mode": "0755"
13
13
  },
14
14
  "linux-x64": {
15
15
  "goos": "linux",
16
16
  "goarch": "amd64",
17
17
  "binary": "daemon/bin/linux-x64/botbuddy-daemon",
18
- "sha256": "61b9f79104394a9fe11e43b25cf3aa3c84dc1538f44c4439b7ed0555b8e8b858",
18
+ "sha256": "bf2f3a46ef151ace3e5b21633c03dc1824bee2e42fc6edd8f6898ca35d48f10c",
19
19
  "mode": "0755"
20
20
  }
21
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbuddy/cli",
3
- "version": "1.59.8",
3
+ "version": "1.59.9",
4
4
  "description": "BotBuddy \u2014 Swarm coordination CLI for multi-agent workflows",
5
5
  "type": "module",
6
6
  "bin": {
package/src/wait-core.mjs CHANGED
@@ -287,9 +287,10 @@ const VALIDATORS = {
287
287
  // BOT-1507 — scope=next adds a fourth, LIVE-ONLY selector: it names no run or PR
288
288
  // (they must already exist at arm time) and wakes on the first terminal CI run for
289
289
  // the repo delivered AFTER the wait was armed — the post-merge / cron train case.
290
- // Optional branch=/workflow= filter that first run; branch is valid only with
291
- // scope=next. A workflow also pins a level-triggered sha= recovery to one
292
- // canonical workflow identity.
290
+ // Optional branch=/workflow=/workflow_id=/workflow_path= filters narrow that
291
+ // first run; branch and stable workflow identities are valid only with
292
+ // scope=next. The legacy display-name filter also pins a level-triggered
293
+ // sha= recovery to one historical workflow.
293
294
  // BOT-1685 — scope=next also accepts an optional sha= FILTER (distinct from the
294
295
  // level-triggered sha= selector): a wait armed BEFORE re-dispatching a run for a
295
296
  // known commit then wakes on the NEXT terminal run for THAT commit, instead of
@@ -309,9 +310,13 @@ const VALIDATORS = {
309
310
  }
310
311
  const hasBranchFilter = p.branch !== undefined;
311
312
  const hasWorkflowFilter = p.workflow !== undefined;
313
+ const hasWorkflowIdFilter = p.workflow_id !== undefined;
314
+ const hasWorkflowPathFilter = p.workflow_path !== undefined;
312
315
  if (p.scope !== undefined) {
313
316
  if (p.scope === "latest") {
314
- if (hasBranchFilter || hasWorkflowFilter) throw new Error("ci branch=/workflow= are only valid with scope=next");
317
+ if (hasBranchFilter || hasWorkflowFilter || hasWorkflowIdFilter || hasWorkflowPathFilter) {
318
+ throw new Error("ci branch=/workflow=/workflow_id=/workflow_path= are only valid with scope=next");
319
+ }
315
320
  if (p.pr === undefined || !/^\d+$/.test(String(p.pr).trim())) {
316
321
  throw new Error("ci scope=latest needs pr=<number>");
317
322
  }
@@ -329,12 +334,23 @@ const VALIDATORS = {
329
334
  if (v === "") throw new Error(`ci ${key}= must be non-empty`);
330
335
  return v;
331
336
  };
332
- return { repo, scope: "next", branch: filter("branch"), workflow: filter("workflow"), sha: filter("sha"), pr: null };
337
+ const workflowId = filter("workflow_id");
338
+ const workflowPath = filter("workflow_path");
339
+ return {
340
+ repo,
341
+ scope: "next",
342
+ branch: filter("branch"),
343
+ workflow: filter("workflow"),
344
+ ...(workflowId == null ? {} : { workflowId }),
345
+ ...(workflowPath == null ? {} : { workflowPath }),
346
+ sha: filter("sha"),
347
+ pr: null,
348
+ };
333
349
  }
334
350
  throw new Error("ci scope must be 'latest' or 'next' (or use run_id=/sha=)");
335
351
  }
336
- if (hasBranchFilter || (hasWorkflowFilter && p.sha === undefined)) {
337
- throw new Error("ci branch= is only valid with scope=next; workflow= also accepts an exact sha selector");
352
+ if (hasBranchFilter || hasWorkflowIdFilter || hasWorkflowPathFilter || (hasWorkflowFilter && p.sha === undefined)) {
353
+ throw new Error("ci branch=/workflow_id=/workflow_path= are only valid with scope=next; legacy workflow= also accepts an exact sha selector");
338
354
  }
339
355
  if (p.run_id !== undefined) {
340
356
  if (!String(p.run_id).trim()) throw new Error("ci run_id must be non-empty");
@@ -343,7 +359,13 @@ const VALIDATORS = {
343
359
  if (!String(p.sha).trim()) throw new Error("ci sha must be non-empty");
344
360
  const workflow = p.workflow === undefined ? null : String(p.workflow).trim();
345
361
  if (p.workflow !== undefined && workflow === "") throw new Error("ci workflow= must be non-empty");
346
- return { repo, scope: "sha", sha: String(p.sha).trim(), workflow, pr: p.pr != null ? String(p.pr).trim() : null };
362
+ return {
363
+ repo,
364
+ scope: "sha",
365
+ sha: String(p.sha).trim(),
366
+ workflow,
367
+ pr: p.pr != null ? String(p.pr).trim() : null,
368
+ };
347
369
  },
348
370
  "staging-green"(p) {
349
371
  const repo = p.repo != null ? String(p.repo).trim() : null;
@@ -1013,7 +1035,7 @@ export function formatUnknownWorkflowGuidance(detail, candidates) {
1013
1035
  const named = Array.isArray(candidates) ? candidates.filter((c) => typeof c === "string" && c.trim() !== "") : [];
1014
1036
  if (named.length === 0) return lines;
1015
1037
  lines.push("closest workflow names this repo has actually reported:");
1016
- for (const name of named) lines.push(` workflow=${name}`);
1038
+ for (const name of named) lines.push(` ${name.includes("=") ? name : `workflow=${name}`}`);
1017
1039
  return lines;
1018
1040
  }
1019
1041
 
@@ -1152,16 +1174,20 @@ function conditionMatchesSignal(condition, signal, waitSessionId) {
1152
1174
  if (params.scope === "run_id") return String(signal.payload?.run_id) === params.runId;
1153
1175
  if (params.scope === "sha") {
1154
1176
  if (signal.payload?.head_sha !== params.sha) return false;
1155
- if (params.workflow == null) return true;
1156
- const workflow = signal.payload?.workflow_name;
1157
- return typeof workflow === "string" && workflow.trim().toLowerCase() === params.workflow.trim().toLowerCase();
1177
+ if (params.workflow != null) {
1178
+ const workflow = signal.payload?.workflow_name;
1179
+ if (typeof workflow !== "string" || workflow.trim().toLowerCase() !== params.workflow.trim().toLowerCase()) return false;
1180
+ }
1181
+ if (params.workflowId != null && String(signal.payload?.workflow_id ?? "").trim() !== params.workflowId) return false;
1182
+ if (params.workflowPath != null && String(signal.payload?.workflow_path ?? "").trim() !== params.workflowPath) return false;
1183
+ return true;
1158
1184
  }
1159
1185
  if (params.scope === "next") {
1160
1186
  // BOT-1507 — live-only: the first TERMINAL run for the repo. Never keys on
1161
1187
  // subject_key (it is run:<id> for post-merge runs and owner/repo#n for PR
1162
1188
  // runs — both are legitimate wakes); a null/empty conclusion is an
1163
1189
  // in-progress signal and never terminal. Optional branch/workflow filters:
1164
- // branch is exact, workflow is the GitHub display name (case/space-insensitive).
1190
+ // branch/path/id are exact; the display name is case/space-insensitive.
1165
1191
  const conclusion = signal.payload?.conclusion;
1166
1192
  if (typeof conclusion !== "string" || conclusion.trim() === "") return false;
1167
1193
  // BOT-1685: an optional sha filter pins scope=next to a commit, so a
@@ -1174,6 +1200,8 @@ function conditionMatchesSignal(condition, signal, waitSessionId) {
1174
1200
  return false;
1175
1201
  }
1176
1202
  }
1203
+ if (params.workflowId != null && String(signal.payload?.workflow_id ?? "").trim() !== params.workflowId) return false;
1204
+ if (params.workflowPath != null && String(signal.payload?.workflow_path ?? "").trim() !== params.workflowPath) return false;
1177
1205
  return true;
1178
1206
  }
1179
1207
  // scope=latest: the PR's run (by subject owner/repo#pr or payload pr_number).