@great-arrow/cli 0.10.2 → 0.10.5

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 (2) hide show
  1. package/dist/index.js +99 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4031,11 +4031,11 @@ var require_clean = __commonJS({
4031
4031
  "node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/clean.js"(exports, module) {
4032
4032
  "use strict";
4033
4033
  var parse3 = require_parse();
4034
- var clean2 = (version2, options) => {
4034
+ var clean3 = (version2, options) => {
4035
4035
  const s2 = parse3(version2.trim().replace(/^[=v]+/, ""), options);
4036
4036
  return s2 ? s2.version : null;
4037
4037
  };
4038
- module.exports = clean2;
4038
+ module.exports = clean3;
4039
4039
  }
4040
4040
  });
4041
4041
 
@@ -5363,7 +5363,7 @@ var require_semver2 = __commonJS({
5363
5363
  var identifiers = require_identifiers();
5364
5364
  var parse3 = require_parse();
5365
5365
  var valid = require_valid();
5366
- var clean2 = require_clean();
5366
+ var clean3 = require_clean();
5367
5367
  var inc = require_inc();
5368
5368
  var diff = require_diff();
5369
5369
  var major = require_major();
@@ -5402,7 +5402,7 @@ var require_semver2 = __commonJS({
5402
5402
  module.exports = {
5403
5403
  parse: parse3,
5404
5404
  valid,
5405
- clean: clean2,
5405
+ clean: clean3,
5406
5406
  inc,
5407
5407
  diff,
5408
5408
  major,
@@ -10011,7 +10011,7 @@ async function clearStoredCredential() {
10011
10011
 
10012
10012
  // src/lib/version.ts
10013
10013
  var CLI_PACKAGE_NAME = "@great-arrow/cli";
10014
- var CLI_VERSION = "0.10.2";
10014
+ var CLI_VERSION = "0.10.5";
10015
10015
  var GAD_INSTALL_VERSION = "2026.08.08";
10016
10016
  var GAD_INSTALL_MIN_VERSION = "2026.06.22";
10017
10017
  var GAD_INSTALL_HEADER = "X-GAD-Install-Version";
@@ -32522,8 +32522,8 @@ function readStdin(stream) {
32522
32522
  // src/lib/sources.ts
32523
32523
  function nonEmpty2(value) {
32524
32524
  if (typeof value !== "string") return null;
32525
- const clean2 = stripControlChars(value).trim();
32526
- return clean2 === "" ? null : clean2;
32525
+ const clean3 = stripControlChars(value).trim();
32526
+ return clean3 === "" ? null : clean3;
32527
32527
  }
32528
32528
  function httpUrl2(value) {
32529
32529
  const raw = nonEmpty2(value);
@@ -38604,6 +38604,82 @@ var agentsCommand = new Command("agents").description(
38604
38604
  process.stdout.write(renderAgentsNow(result) + "\n");
38605
38605
  });
38606
38606
 
38607
+ // src/commands/ci-status.ts
38608
+ function ciStatusParams(pr, opts) {
38609
+ return {
38610
+ ...opts.repo ? { repo: opts.repo } : {},
38611
+ ...pr ? { pr } : {},
38612
+ ...opts.branch ? { branch: opts.branch } : {},
38613
+ ...opts.sha ? { sha: opts.sha } : {},
38614
+ ...opts.queue ? { queue: "1" } : {}
38615
+ };
38616
+ }
38617
+ var clean = (v) => stripControlChars(String(v ?? ""));
38618
+ function ageOf(iso, now) {
38619
+ const min = Math.max(0, Math.round((now - Date.parse(iso)) / 6e4));
38620
+ return min < 1 ? "<1m ago" : `${min}m ago`;
38621
+ }
38622
+ function checkMark(c) {
38623
+ if (c.status !== "completed") return c.status;
38624
+ return c.conclusion ?? "completed";
38625
+ }
38626
+ function renderCiStatus(s2, now = Date.now()) {
38627
+ const lines = [];
38628
+ const head = s2.asOf ? `Board as of ${ageOf(s2.asOf, now)}: ${s2.verdict}` : `Board is empty: ${s2.verdict}`;
38629
+ lines.push(s2.reason ? `${head} (${clean(s2.reason)})` : head);
38630
+ if (s2.verdict === "unverified")
38631
+ lines.push("Verify on GitHub before acting on this.");
38632
+ const checks = s2.checks ?? [];
38633
+ for (const pr of s2.prs ?? []) {
38634
+ const flags = [
38635
+ pr.state,
38636
+ pr.isDraft ? "draft" : null,
38637
+ pr.queueState !== "none" ? pr.queueState : null,
38638
+ pr.mergeable ? clean(pr.mergeable).toLowerCase() : null
38639
+ ].filter(Boolean);
38640
+ lines.push("");
38641
+ const where = s2.repo ? "" : `${clean(pr.repo)}`;
38642
+ lines.push(
38643
+ `${where}#${pr.prNumber} ${clean(pr.headRef)} [${flags.join(", ")}]`
38644
+ );
38645
+ for (const c of checks.filter((x) => x.headSha === pr.headSha)) {
38646
+ lines.push(
38647
+ ` ${checkMark(c).padEnd(12)} ${clean(c.checkName)}${c.isRequired ? " (required)" : ""}`
38648
+ );
38649
+ }
38650
+ }
38651
+ if (s2.queue && s2.queue.length > 0) {
38652
+ lines.push("", "Merge queue");
38653
+ for (const q of s2.queue) {
38654
+ lines.push(
38655
+ ` ${q.position ?? "?"}. #${q.prNumber} ${q.queueState} (position seen ${ageOf(q.observedAt, now)})`
38656
+ );
38657
+ }
38658
+ }
38659
+ if (s2.budget) {
38660
+ lines.push(
38661
+ "",
38662
+ `GitHub budget: REST ${s2.budget.restRemaining}, GraphQL ${s2.budget.graphqlRemaining}`
38663
+ );
38664
+ }
38665
+ return lines.join("\n");
38666
+ }
38667
+ var ciCommand = new Command("ci").description(
38668
+ "CI status from the Great Arrow board, with no GitHub call"
38669
+ );
38670
+ ciCommand.command("status [pr]").description("PR checks and merge-queue state; unverified exits 0").option("--repo <owner/name>", "Repository (default: the workspace's repo)").option("--queue", "Show the merge queue").option("--branch <branch>", "Pull request by head branch").option("--sha <sha>", "Checks for a commit").option("--json", "Output as JSON").action(async (pr, opts, command) => {
38671
+ const g = globalOutputOpts(command);
38672
+ const auth = await resolveAuth();
38673
+ const client2 = new GadClient({ token: auth.token, apiUrl: auth.apiUrl });
38674
+ const result = await client2.get(
38675
+ "/api/ci/status",
38676
+ ciStatusParams(pr, opts)
38677
+ );
38678
+ process.stdout.write(
38679
+ (g.json ? JSON.stringify(result, null, 2) : renderCiStatus(result)) + "\n"
38680
+ );
38681
+ });
38682
+
38607
38683
  // src/commands/inbox.ts
38608
38684
  var BACKOFF_BASE_MS = 15e3;
38609
38685
  var BACKOFF_MAX_MS = 12e4;
@@ -39105,6 +39181,8 @@ function normalizeGlance(raw) {
39105
39181
  }
39106
39182
  ];
39107
39183
  });
39184
+ const more = obj.needsYouMore;
39185
+ const needsYouMore = more && typeof more.count === "number" && more.count > 0 && typeof more.text === "string" && typeof more.href === "string" ? { count: more.count, text: more.text, href: more.href } : null;
39108
39186
  const atRisk = asArray2(obj.atRisk).flatMap((item) => {
39109
39187
  if (typeof item !== "object" || item === null) return [];
39110
39188
  const it = item;
@@ -39194,6 +39272,7 @@ function normalizeGlance(raw) {
39194
39272
  return typeof row.id === "string" && typeof row.name === "string" ? [{ id: row.id, name: row.name }] : [];
39195
39273
  }) : [],
39196
39274
  needsYou,
39275
+ ...needsYouMore ? { needsYouMore } : {},
39197
39276
  atRisk,
39198
39277
  topGoal,
39199
39278
  integrations,
@@ -39403,6 +39482,13 @@ function renderFooter(payload, apiUrl) {
39403
39482
  if (url2) lines.push(` ${c.dim("\u2192")} ${c.cyan(url2)}`);
39404
39483
  }
39405
39484
  }
39485
+ if (payload.needsYouMore) {
39486
+ const hidden = Math.max(0, payload.needsYou.length - 2) + payload.needsYouMore.count;
39487
+ const url2 = glanceItemUrl(payload.needsYouMore.href, apiUrl);
39488
+ lines.push(
39489
+ `${c.dim(`+${hidden} more needs you`)}${url2 ? ` ${c.dim("\u2192")} ${c.cyan(url2)}` : ""}`
39490
+ );
39491
+ }
39406
39492
  if (lines.length === 0) {
39407
39493
  const integration = payload.integrations[0];
39408
39494
  if (integration) {
@@ -52357,7 +52443,7 @@ function parseRaw(out2) {
52357
52443
  }
52358
52444
  return changes;
52359
52445
  }
52360
- function clean(name23) {
52446
+ function clean2(name23) {
52361
52447
  return [...name23].filter((c) => !new RegExp("\\p{Cc}", "u").test(c)).slice(0, 200).join("");
52362
52448
  }
52363
52449
  async function scanChanges(layout, changes, maxFile, opts = {}) {
@@ -52375,7 +52461,7 @@ async function scanChanges(layout, changes, maxFile, opts = {}) {
52375
52461
  if (size2.code !== 0 || !Number.isSafeInteger(bytes))
52376
52462
  throw new Refusal("commit_failed");
52377
52463
  if (bytes > maxFile)
52378
- throw new Refusal("file_too_large", clean(change.path));
52464
+ throw new Refusal("file_too_large", clean2(change.path));
52379
52465
  const blob = await worktreeGitBytes(
52380
52466
  layout,
52381
52467
  ["cat-file", "blob", change.newSha],
@@ -52384,7 +52470,7 @@ async function scanChanges(layout, changes, maxFile, opts = {}) {
52384
52470
  if (blob.code !== 0) throw new Refusal("commit_failed");
52385
52471
  const line = secretLine(blob.stdout);
52386
52472
  if (line !== null)
52387
- throw new Refusal("secret_in_diff", `${clean(change.path)} line ${line}`);
52473
+ throw new Refusal("secret_in_diff", `${clean2(change.path)} line ${line}`);
52388
52474
  }
52389
52475
  }
52390
52476
  function linkTextStaysInside(rel, target) {
@@ -52502,9 +52588,9 @@ function readVerified(root, rel, max, probe = {}) {
52502
52588
  const fst = fstatSync(fd);
52503
52589
  if (!fst.isFile()) throw new Refusal("unsupported_file");
52504
52590
  if (fst.nlink !== 1) throw new Refusal("hardlink_in_worktree");
52505
- if (fst.size > max) throw new Refusal("file_too_large", clean(rel));
52591
+ if (fst.size > max) throw new Refusal("file_too_large", clean2(rel));
52506
52592
  const bytes = readUpTo(fd, max + 1);
52507
- if (bytes.length > max) throw new Refusal("file_too_large", clean(rel));
52593
+ if (bytes.length > max) throw new Refusal("file_too_large", clean2(rel));
52508
52594
  probe.afterRead?.(rel);
52509
52595
  recheck();
52510
52596
  return { kind: "file", bytes, executable: (fst.mode & 64) !== 0 };
@@ -58024,6 +58110,7 @@ program2.addCommand(integrations_default);
58024
58110
  program2.addCommand(mcp_default);
58025
58111
  program2.addCommand(agentCommand);
58026
58112
  program2.addCommand(agentsCommand);
58113
+ program2.addCommand(ciCommand);
58027
58114
  program2.addCommand(inboxCommand);
58028
58115
  program2.addCommand(presenceCommand);
58029
58116
  program2.addCommand(askCommand());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@great-arrow/cli",
3
- "version": "0.10.2",
3
+ "version": "0.10.5",
4
4
  "description": "GreatArrow.ai CLI tool",
5
5
  "type": "module",
6
6
  "bin": {