@sideboard-ai/core 0.1.68 → 0.1.71

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 (36) hide show
  1. package/dist/{agents-PE3RHQS5.js → agents-GB7XL2LI.js} +6 -5
  2. package/dist/{agents-JBD7IAGK.js → agents-TCAK3MXN.js} +6 -5
  3. package/dist/{app-settings-ONKMFSEJ.js → app-settings-3TLA2EJ7.js} +16 -1
  4. package/dist/{app-settings-GJVZGU3M.js → app-settings-P42Z3VOB.js} +16 -1
  5. package/dist/caffeinate-hold-BEJIYPJ7.js +107 -0
  6. package/dist/caffeinate-hold-KLC6SABD.js +14 -0
  7. package/dist/{chunk-DPDGMMGI.js → chunk-3CY6WJ7O.js} +2 -2
  8. package/dist/{chunk-ROXEENBT.js → chunk-57ROTAFD.js} +62 -3
  9. package/dist/{chunk-N5LMEP65.js → chunk-7NCIHRAU.js} +22 -4
  10. package/dist/{chunk-OICHV4DH.js → chunk-DGPUAZA4.js} +62 -3
  11. package/dist/{chunk-VX6ACNXS.js → chunk-H2IXNFQ2.js} +22 -4
  12. package/dist/chunk-JAWEDVVA.js +106 -0
  13. package/dist/chunk-JT7R45JB.js +20 -0
  14. package/dist/{chunk-EEBDVLDK.js → chunk-MF2YMEGD.js} +61 -9
  15. package/dist/{chunk-47RBLBRK.js → chunk-NG7S3OPX.js} +10 -4
  16. package/dist/chunk-NSTQ6QKD.js +23 -0
  17. package/dist/{chunk-REKGFVUX.js → chunk-OE7YBB5X.js} +61 -9
  18. package/dist/{chunk-BPOTVI5J.js → chunk-PTJJIQK7.js} +472 -18
  19. package/dist/{chunk-6Q7H6SMX.js → chunk-S25IHL5H.js} +10 -4
  20. package/dist/{chunk-QQC2D4MY.js → chunk-UH57WVFP.js} +2 -2
  21. package/dist/{chunk-MHR4OGZ4.js → chunk-W7YOTDVO.js} +493 -18
  22. package/dist/{coordinator-prompt-YZYZ5P6P.js → coordinator-prompt-2J4PIMUF.js} +6 -3
  23. package/dist/{coordinator-prompt-HD6IMCKS.js → coordinator-prompt-QYYG2IBB.js} +6 -3
  24. package/dist/{global-workspace-Z6GF7D2K.js → global-workspace-KHIFQUUM.js} +11 -4
  25. package/dist/{global-workspace-7P5NG3JZ.js → global-workspace-SVRYNJZA.js} +11 -4
  26. package/dist/index.cjs +4184 -850
  27. package/dist/index.d.cts +543 -21
  28. package/dist/index.d.ts +543 -21
  29. package/dist/index.js +3285 -748
  30. package/dist/mcp/run-stdio.cjs +1995 -482
  31. package/dist/mcp/run-stdio.js +943 -151
  32. package/dist/{workspaces-BWJNGEE6.js → workspaces-AHFTHVBT.js} +6 -5
  33. package/dist/{workspaces-O6EZGKQK.js → workspaces-SVQIEVIZ.js} +6 -5
  34. package/dist/{worktree-VDXLUOWR.js → worktree-KWXHMKRN.js} +1 -1
  35. package/dist/{worktree-ZPSKEZFE.js → worktree-VOCH3WS3.js} +1 -1
  36. package/package.json +3 -1
@@ -0,0 +1,106 @@
1
+ import {
2
+ writePrivateFile
3
+ } from "./chunk-JT7R45JB.js";
4
+ import {
5
+ appDataDir
6
+ } from "./chunk-M37RITA6.js";
7
+
8
+ // src/store/caffeinate-hold.ts
9
+ import { spawn } from "child_process";
10
+ import { existsSync, readFileSync, unlinkSync } from "fs";
11
+ import { join } from "path";
12
+ var hooks = {};
13
+ function setCaffeinateHoldHooks(next) {
14
+ hooks = next;
15
+ }
16
+ function caffeinateHoldPath() {
17
+ return join(appDataDir(), "caffeinate-hold.json");
18
+ }
19
+ function processAlive(pid) {
20
+ if (hooks.processAlive) return hooks.processAlive(pid);
21
+ try {
22
+ process.kill(pid, 0);
23
+ return true;
24
+ } catch {
25
+ return false;
26
+ }
27
+ }
28
+ function killPid(pid) {
29
+ if (hooks.kill) {
30
+ hooks.kill(pid);
31
+ return;
32
+ }
33
+ try {
34
+ process.kill(pid, "SIGTERM");
35
+ } catch {
36
+ }
37
+ }
38
+ function readHold() {
39
+ const path = caffeinateHoldPath();
40
+ if (!existsSync(path)) return null;
41
+ try {
42
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
43
+ if (typeof parsed?.pid === "number" && parsed.pid > 0) return parsed;
44
+ } catch {
45
+ }
46
+ return null;
47
+ }
48
+ function writeHold(pid) {
49
+ writePrivateFile(caffeinateHoldPath(), `${JSON.stringify({ pid })}
50
+ `);
51
+ }
52
+ function clearHold() {
53
+ try {
54
+ unlinkSync(caffeinateHoldPath());
55
+ } catch {
56
+ }
57
+ }
58
+ function getCaffeinateHold() {
59
+ const platform = hooks.platform ?? process.platform;
60
+ const hold = readHold();
61
+ if (!hold) {
62
+ return { held: false, pid: null, running: false, platform };
63
+ }
64
+ const running = processAlive(hold.pid);
65
+ if (!running) {
66
+ clearHold();
67
+ return { held: false, pid: null, running: false, platform };
68
+ }
69
+ return { held: true, pid: hold.pid, running: true, platform };
70
+ }
71
+ function setCaffeinateHold(enabled) {
72
+ const platform = hooks.platform ?? process.platform;
73
+ const current = getCaffeinateHold();
74
+ if (!enabled) {
75
+ if (current.pid) killPid(current.pid);
76
+ clearHold();
77
+ return { held: false, pid: null, running: false, platform };
78
+ }
79
+ if (current.running && current.pid) return current;
80
+ if (platform !== "darwin") {
81
+ return { held: false, pid: null, running: false, platform };
82
+ }
83
+ const spawnImpl = hooks.spawn ?? spawn;
84
+ const child = spawnImpl("caffeinate", ["-dimsu"], {
85
+ detached: true,
86
+ stdio: "ignore"
87
+ });
88
+ const pid = child.pid;
89
+ if (!pid) {
90
+ try {
91
+ child.kill();
92
+ } catch {
93
+ }
94
+ return { held: false, pid: null, running: false, platform };
95
+ }
96
+ child.unref();
97
+ writeHold(pid);
98
+ return { held: true, pid, running: true, platform };
99
+ }
100
+
101
+ export {
102
+ setCaffeinateHoldHooks,
103
+ caffeinateHoldPath,
104
+ getCaffeinateHold,
105
+ setCaffeinateHold
106
+ };
@@ -0,0 +1,20 @@
1
+ // src/store/private-file.ts
2
+ import { chmodSync, mkdirSync, writeFileSync } from "fs";
3
+ import { dirname } from "path";
4
+ var PRIVATE_FILE_MODE = 384;
5
+ function writePrivateFile(path, contents) {
6
+ mkdirSync(dirname(path), { recursive: true });
7
+ writeFileSync(path, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
8
+ chmodOwnerOnly(path);
9
+ }
10
+ function chmodOwnerOnly(path) {
11
+ try {
12
+ chmodSync(path, PRIVATE_FILE_MODE);
13
+ } catch {
14
+ }
15
+ }
16
+
17
+ export {
18
+ writePrivateFile,
19
+ chmodOwnerOnly
20
+ };
@@ -887,6 +887,10 @@ function formatIpcInvokeError(err) {
887
887
  }
888
888
 
889
889
  // src/git/pr-gates.ts
890
+ function prIsInMergeQueue(gate) {
891
+ if (gate.isInMergeQueue) return true;
892
+ return (gate.mergeStateStatus ?? "").toUpperCase() === "QUEUED";
893
+ }
890
894
  function buildMergeGateChecks(gate, opts = {}) {
891
895
  const rows = [];
892
896
  const base = gate.baseRefName?.trim() || "the base branch";
@@ -896,7 +900,8 @@ function buildMergeGateChecks(gate, opts = {}) {
896
900
  const review = (gate.reviewDecision ?? "").toUpperCase();
897
901
  const suppressBlocked = opts.suppressGenericBlocked !== false;
898
902
  const conflicting = mergeable === "CONFLICTING" || mergeState === "DIRTY";
899
- if (conflicting) {
903
+ const inQueue = prIsInMergeQueue(gate);
904
+ if (conflicting && !inQueue) {
900
905
  rows.push({
901
906
  name: "Merge conflicts",
902
907
  state: mergeable === "CONFLICTING" ? "CONFLICTING" : mergeState || "DIRTY",
@@ -908,6 +913,18 @@ function buildMergeGateChecks(gate, opts = {}) {
908
913
  workflow: "mergeability",
909
914
  kind: "mergeability"
910
915
  });
916
+ } else if (inQueue) {
917
+ rows.push({
918
+ name: "Merge queue",
919
+ state: "QUEUED",
920
+ bucket: "pending",
921
+ startedAt: null,
922
+ completedAt: null,
923
+ link,
924
+ description: `This pull request is in the GitHub merge queue for ${base}.`,
925
+ workflow: "mergeability",
926
+ kind: "mergeability"
927
+ });
911
928
  } else if (mergeState === "BEHIND") {
912
929
  rows.push({
913
930
  name: "Branch behind",
@@ -1441,10 +1458,21 @@ async function fetchPrMergeGate(cwd, selector, slug) {
1441
1458
  "view",
1442
1459
  selector,
1443
1460
  "--json",
1444
- "mergeable,mergeStateStatus,reviewDecision,baseRefName,url"
1461
+ "mergeable,mergeStateStatus,reviewDecision,baseRefName,url,isInMergeQueue"
1445
1462
  ];
1446
1463
  if (slug) args.push("--repo", slug);
1447
- const { stdout, exitCode, stderr } = await gh(args, cwd, { reject: false });
1464
+ let { stdout, exitCode, stderr } = await gh(args, cwd, { reject: false });
1465
+ if (exitCode !== 0 && isUnknownJsonField(stderr, "isInMergeQueue")) {
1466
+ const retry = [
1467
+ "pr",
1468
+ "view",
1469
+ selector,
1470
+ "--json",
1471
+ "mergeable,mergeStateStatus,reviewDecision,baseRefName,url"
1472
+ ];
1473
+ if (slug) retry.push("--repo", slug);
1474
+ ({ stdout, exitCode, stderr } = await gh(retry, cwd, { reject: false }));
1475
+ }
1448
1476
  if (exitCode !== 0 || !stdout.trim()) {
1449
1477
  if (/no pull requests found/i.test(stderr)) return null;
1450
1478
  return null;
@@ -1456,12 +1484,22 @@ async function fetchPrMergeGate(cwd, selector, slug) {
1456
1484
  mergeStateStatus: typeof view.mergeStateStatus === "string" && view.mergeStateStatus ? view.mergeStateStatus : null,
1457
1485
  reviewDecision: typeof view.reviewDecision === "string" && view.reviewDecision ? view.reviewDecision : null,
1458
1486
  baseRefName: typeof view.baseRefName === "string" && view.baseRefName ? view.baseRefName : null,
1459
- url: typeof view.url === "string" && view.url ? view.url : null
1487
+ url: typeof view.url === "string" && view.url ? view.url : null,
1488
+ isInMergeQueue: parseInMergeQueue(view)
1460
1489
  };
1461
1490
  } catch {
1462
1491
  return null;
1463
1492
  }
1464
1493
  }
1494
+ function isUnknownJsonField(stderr, field) {
1495
+ return new RegExp(`unknown json field[^\\n]*${field}`, "i").test(stderr);
1496
+ }
1497
+ function parseInMergeQueue(view) {
1498
+ return prIsInMergeQueue({
1499
+ isInMergeQueue: view.isInMergeQueue === true,
1500
+ mergeStateStatus: typeof view.mergeStateStatus === "string" ? view.mergeStateStatus : null
1501
+ });
1502
+ }
1465
1503
  async function detectLocalMergeConflicts(cwd, baseRefName) {
1466
1504
  const baseName = (baseRefName?.trim() || await resolveDefaultBranch(cwd)).replace(
1467
1505
  /^origin\//,
@@ -1522,7 +1560,8 @@ async function getPrChecks(cwd, selector) {
1522
1560
  const mergeable = (gate?.mergeable ?? "").toUpperCase();
1523
1561
  const mergeState = (gate?.mergeStateStatus ?? "").toUpperCase();
1524
1562
  const alreadyConflicting = mergeable === "CONFLICTING" || mergeState === "DIRTY";
1525
- const needsLocalProbe = !alreadyConflicting;
1563
+ const inQueue = gate ? prIsInMergeQueue(gate) : false;
1564
+ const needsLocalProbe = !alreadyConflicting && !inQueue;
1526
1565
  if (needsLocalProbe) {
1527
1566
  try {
1528
1567
  const local = await detectLocalMergeConflicts(cwd, gate?.baseRefName ?? null);
@@ -1533,7 +1572,8 @@ async function getPrChecks(cwd, selector) {
1533
1572
  mergeStateStatus: "DIRTY",
1534
1573
  reviewDecision: gate?.reviewDecision ?? null,
1535
1574
  baseRefName: local.base,
1536
- url: gate?.url ?? null
1575
+ url: gate?.url ?? null,
1576
+ isInMergeQueue: false
1537
1577
  };
1538
1578
  const ciFailed2 = ciChecks.some((c) => c.bucket === "fail");
1539
1579
  const review2 = (gate.reviewDecision ?? "").toUpperCase();
@@ -1577,10 +1617,21 @@ async function getPrMeta(cwd, selector) {
1577
1617
  "view",
1578
1618
  selector,
1579
1619
  "--json",
1580
- "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName"
1620
+ "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,isInMergeQueue,mergeStateStatus"
1581
1621
  ];
1582
1622
  if (slug) viewArgs.push("--repo", slug);
1583
- const { stdout, exitCode, stderr } = await gh(viewArgs, cwd, { reject: false });
1623
+ let { stdout, exitCode, stderr } = await gh(viewArgs, cwd, { reject: false });
1624
+ if (exitCode !== 0 && isUnknownJsonField(stderr, "isInMergeQueue")) {
1625
+ const retry = [
1626
+ "pr",
1627
+ "view",
1628
+ selector,
1629
+ "--json",
1630
+ "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,mergeStateStatus"
1631
+ ];
1632
+ if (slug) retry.push("--repo", slug);
1633
+ ({ stdout, exitCode, stderr } = await gh(retry, cwd, { reject: false }));
1634
+ }
1584
1635
  if (exitCode !== 0 || !stdout.trim()) {
1585
1636
  if (/no pull requests found/i.test(stderr)) return null;
1586
1637
  return null;
@@ -1595,7 +1646,8 @@ async function getPrMeta(cwd, selector) {
1595
1646
  isDraft: Boolean(view.isDraft),
1596
1647
  reviewDecision: typeof view.reviewDecision === "string" && view.reviewDecision ? view.reviewDecision : null,
1597
1648
  baseRefName: String(view.baseRefName ?? ""),
1598
- headRefName: String(view.headRefName ?? "")
1649
+ headRefName: String(view.headRefName ?? ""),
1650
+ isInMergeQueue: parseInMergeQueue(view)
1599
1651
  };
1600
1652
  } catch {
1601
1653
  return null;
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-VROPG6QF.js";
10
10
  import {
11
11
  isOrchestratorThread
12
- } from "./chunk-OICHV4DH.js";
12
+ } from "./chunk-DGPUAZA4.js";
13
13
  import {
14
14
  enrichPathWithNpmGlobalBin,
15
15
  isConductorBundledCli,
@@ -22,7 +22,7 @@ import {
22
22
  loadAppSettings,
23
23
  resolveAgentExecutable,
24
24
  resolveClaudeExecutable
25
- } from "./chunk-BPOTVI5J.js";
25
+ } from "./chunk-PTJJIQK7.js";
26
26
  import {
27
27
  appDataDir
28
28
  } from "./chunk-7MV3RXSC.js";
@@ -580,7 +580,13 @@ var SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS = [
580
580
  "mcp__sideboard__present_schema",
581
581
  "mcp__sideboard__present_files",
582
582
  "mcp__sideboard__ask_user",
583
- "mcp__sideboard__present_plan"
583
+ "mcp__sideboard__present_plan",
584
+ "mcp__sideboard__list_teams",
585
+ "mcp__sideboard__slack_list_channels",
586
+ "mcp__sideboard__slack_list_users",
587
+ "mcp__sideboard__slack_search",
588
+ "mcp__sideboard__slack_read",
589
+ "mcp__sideboard__slack_post"
584
590
  ];
585
591
  var brightsyMcpCommandCache = null;
586
592
  async function resolveBrightsyMcpCommand() {
@@ -1000,7 +1006,7 @@ var claudeAdapter = {
1000
1006
  );
1001
1007
  }
1002
1008
  const mode = permissionMode(thread);
1003
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-Z6GF7D2K.js");
1009
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-KHIFQUUM.js");
1004
1010
  const isOrchestrator = isOrchestratorThread2(thread);
1005
1011
  const injectedServers = await buildInjectedMcpServers({
1006
1012
  includeSideboard: true,
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+
3
+
4
+ // src/store/private-file.ts
5
+ import { chmodSync, mkdirSync, writeFileSync } from "fs";
6
+ import { dirname } from "path";
7
+ var PRIVATE_FILE_MODE = 384;
8
+ function writePrivateFile(path, contents) {
9
+ mkdirSync(dirname(path), { recursive: true });
10
+ writeFileSync(path, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
11
+ chmodOwnerOnly(path);
12
+ }
13
+ function chmodOwnerOnly(path) {
14
+ try {
15
+ chmodSync(path, PRIVATE_FILE_MODE);
16
+ } catch {
17
+ }
18
+ }
19
+
20
+ export {
21
+ writePrivateFile,
22
+ chmodOwnerOnly
23
+ };
@@ -882,6 +882,10 @@ function formatGhLandError(raw, opts) {
882
882
  }
883
883
 
884
884
  // src/git/pr-gates.ts
885
+ function prIsInMergeQueue(gate) {
886
+ if (gate.isInMergeQueue) return true;
887
+ return (gate.mergeStateStatus ?? "").toUpperCase() === "QUEUED";
888
+ }
885
889
  function buildMergeGateChecks(gate, opts = {}) {
886
890
  const rows = [];
887
891
  const base = gate.baseRefName?.trim() || "the base branch";
@@ -891,7 +895,8 @@ function buildMergeGateChecks(gate, opts = {}) {
891
895
  const review = (gate.reviewDecision ?? "").toUpperCase();
892
896
  const suppressBlocked = opts.suppressGenericBlocked !== false;
893
897
  const conflicting = mergeable === "CONFLICTING" || mergeState === "DIRTY";
894
- if (conflicting) {
898
+ const inQueue = prIsInMergeQueue(gate);
899
+ if (conflicting && !inQueue) {
895
900
  rows.push({
896
901
  name: "Merge conflicts",
897
902
  state: mergeable === "CONFLICTING" ? "CONFLICTING" : mergeState || "DIRTY",
@@ -903,6 +908,18 @@ function buildMergeGateChecks(gate, opts = {}) {
903
908
  workflow: "mergeability",
904
909
  kind: "mergeability"
905
910
  });
911
+ } else if (inQueue) {
912
+ rows.push({
913
+ name: "Merge queue",
914
+ state: "QUEUED",
915
+ bucket: "pending",
916
+ startedAt: null,
917
+ completedAt: null,
918
+ link,
919
+ description: `This pull request is in the GitHub merge queue for ${base}.`,
920
+ workflow: "mergeability",
921
+ kind: "mergeability"
922
+ });
906
923
  } else if (mergeState === "BEHIND") {
907
924
  rows.push({
908
925
  name: "Branch behind",
@@ -1408,10 +1425,21 @@ async function fetchPrMergeGate(cwd, selector, slug) {
1408
1425
  "view",
1409
1426
  selector,
1410
1427
  "--json",
1411
- "mergeable,mergeStateStatus,reviewDecision,baseRefName,url"
1428
+ "mergeable,mergeStateStatus,reviewDecision,baseRefName,url,isInMergeQueue"
1412
1429
  ];
1413
1430
  if (slug) args.push("--repo", slug);
1414
- const { stdout, exitCode, stderr } = await gh(args, cwd, { reject: false });
1431
+ let { stdout, exitCode, stderr } = await gh(args, cwd, { reject: false });
1432
+ if (exitCode !== 0 && isUnknownJsonField(stderr, "isInMergeQueue")) {
1433
+ const retry = [
1434
+ "pr",
1435
+ "view",
1436
+ selector,
1437
+ "--json",
1438
+ "mergeable,mergeStateStatus,reviewDecision,baseRefName,url"
1439
+ ];
1440
+ if (slug) retry.push("--repo", slug);
1441
+ ({ stdout, exitCode, stderr } = await gh(retry, cwd, { reject: false }));
1442
+ }
1415
1443
  if (exitCode !== 0 || !stdout.trim()) {
1416
1444
  if (/no pull requests found/i.test(stderr)) return null;
1417
1445
  return null;
@@ -1423,12 +1451,22 @@ async function fetchPrMergeGate(cwd, selector, slug) {
1423
1451
  mergeStateStatus: typeof view.mergeStateStatus === "string" && view.mergeStateStatus ? view.mergeStateStatus : null,
1424
1452
  reviewDecision: typeof view.reviewDecision === "string" && view.reviewDecision ? view.reviewDecision : null,
1425
1453
  baseRefName: typeof view.baseRefName === "string" && view.baseRefName ? view.baseRefName : null,
1426
- url: typeof view.url === "string" && view.url ? view.url : null
1454
+ url: typeof view.url === "string" && view.url ? view.url : null,
1455
+ isInMergeQueue: parseInMergeQueue(view)
1427
1456
  };
1428
1457
  } catch {
1429
1458
  return null;
1430
1459
  }
1431
1460
  }
1461
+ function isUnknownJsonField(stderr, field) {
1462
+ return new RegExp(`unknown json field[^\\n]*${field}`, "i").test(stderr);
1463
+ }
1464
+ function parseInMergeQueue(view) {
1465
+ return prIsInMergeQueue({
1466
+ isInMergeQueue: view.isInMergeQueue === true,
1467
+ mergeStateStatus: typeof view.mergeStateStatus === "string" ? view.mergeStateStatus : null
1468
+ });
1469
+ }
1432
1470
  async function detectLocalMergeConflicts(cwd, baseRefName) {
1433
1471
  const baseName = (baseRefName?.trim() || await resolveDefaultBranch(cwd)).replace(
1434
1472
  /^origin\//,
@@ -1489,7 +1527,8 @@ async function getPrChecks(cwd, selector) {
1489
1527
  const mergeable = (gate?.mergeable ?? "").toUpperCase();
1490
1528
  const mergeState = (gate?.mergeStateStatus ?? "").toUpperCase();
1491
1529
  const alreadyConflicting = mergeable === "CONFLICTING" || mergeState === "DIRTY";
1492
- const needsLocalProbe = !alreadyConflicting;
1530
+ const inQueue = gate ? prIsInMergeQueue(gate) : false;
1531
+ const needsLocalProbe = !alreadyConflicting && !inQueue;
1493
1532
  if (needsLocalProbe) {
1494
1533
  try {
1495
1534
  const local = await detectLocalMergeConflicts(cwd, gate?.baseRefName ?? null);
@@ -1500,7 +1539,8 @@ async function getPrChecks(cwd, selector) {
1500
1539
  mergeStateStatus: "DIRTY",
1501
1540
  reviewDecision: gate?.reviewDecision ?? null,
1502
1541
  baseRefName: local.base,
1503
- url: gate?.url ?? null
1542
+ url: gate?.url ?? null,
1543
+ isInMergeQueue: false
1504
1544
  };
1505
1545
  const ciFailed2 = ciChecks.some((c) => c.bucket === "fail");
1506
1546
  const review2 = (gate.reviewDecision ?? "").toUpperCase();
@@ -1544,10 +1584,21 @@ async function getPrMeta(cwd, selector) {
1544
1584
  "view",
1545
1585
  selector,
1546
1586
  "--json",
1547
- "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName"
1587
+ "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,isInMergeQueue,mergeStateStatus"
1548
1588
  ];
1549
1589
  if (slug) viewArgs.push("--repo", slug);
1550
- const { stdout, exitCode, stderr } = await gh(viewArgs, cwd, { reject: false });
1590
+ let { stdout, exitCode, stderr } = await gh(viewArgs, cwd, { reject: false });
1591
+ if (exitCode !== 0 && isUnknownJsonField(stderr, "isInMergeQueue")) {
1592
+ const retry = [
1593
+ "pr",
1594
+ "view",
1595
+ selector,
1596
+ "--json",
1597
+ "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,mergeStateStatus"
1598
+ ];
1599
+ if (slug) retry.push("--repo", slug);
1600
+ ({ stdout, exitCode, stderr } = await gh(retry, cwd, { reject: false }));
1601
+ }
1551
1602
  if (exitCode !== 0 || !stdout.trim()) {
1552
1603
  if (/no pull requests found/i.test(stderr)) return null;
1553
1604
  return null;
@@ -1562,7 +1613,8 @@ async function getPrMeta(cwd, selector) {
1562
1613
  isDraft: Boolean(view.isDraft),
1563
1614
  reviewDecision: typeof view.reviewDecision === "string" && view.reviewDecision ? view.reviewDecision : null,
1564
1615
  baseRefName: String(view.baseRefName ?? ""),
1565
- headRefName: String(view.headRefName ?? "")
1616
+ headRefName: String(view.headRefName ?? ""),
1617
+ isInMergeQueue: parseInMergeQueue(view)
1566
1618
  };
1567
1619
  } catch {
1568
1620
  return null;