@great-arrow/cli 0.10.1 → 0.10.2
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.
- package/dist/index.js +91 -38
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -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.
|
|
10014
|
+
var CLI_VERSION = "0.10.2";
|
|
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";
|
|
@@ -33393,6 +33393,39 @@ import { readFileSync as readFileSync2 } from "node:fs";
|
|
|
33393
33393
|
// src/lib/work-status.ts
|
|
33394
33394
|
import { execFile as execFile3, execFileSync as execFileSync3 } from "node:child_process";
|
|
33395
33395
|
|
|
33396
|
+
// ../../src/lib/work-risk/local-git-truth.ts
|
|
33397
|
+
function isTimeoutError(error62) {
|
|
33398
|
+
if (!error62 || typeof error62 !== "object") return false;
|
|
33399
|
+
const e = error62;
|
|
33400
|
+
return e.code === "ETIMEDOUT" || e.killed === true || e.signal === "SIGTERM";
|
|
33401
|
+
}
|
|
33402
|
+
function contentAlreadyOnMain(head, run5) {
|
|
33403
|
+
const cherry = run5(["cherry", "origin/main", head]);
|
|
33404
|
+
if (cherry.status !== 0) return null;
|
|
33405
|
+
if (cherry.stdout.split("\n").some((line) => line.startsWith("+")))
|
|
33406
|
+
return false;
|
|
33407
|
+
const merges = run5(["rev-list", "--merges", `origin/main..${head}`]);
|
|
33408
|
+
if (merges.status !== 0) return null;
|
|
33409
|
+
for (const sha of merges.stdout.split("\n").filter(Boolean)) {
|
|
33410
|
+
const cc = run5(["diff-tree", "--cc", "--no-commit-id", "-p", sha]);
|
|
33411
|
+
if (cc.status !== 0) return null;
|
|
33412
|
+
if (cc.stdout.trim().length > 0) return false;
|
|
33413
|
+
}
|
|
33414
|
+
return true;
|
|
33415
|
+
}
|
|
33416
|
+
function contentOnMainWithinBudget(branches, run5, budgetMs, now = Date.now) {
|
|
33417
|
+
const deadline = now() + budgetMs;
|
|
33418
|
+
const verdicts = /* @__PURE__ */ new Map();
|
|
33419
|
+
for (const branch of branches) {
|
|
33420
|
+
if (now() >= deadline) {
|
|
33421
|
+
verdicts.set(branch, null);
|
|
33422
|
+
continue;
|
|
33423
|
+
}
|
|
33424
|
+
verdicts.set(branch, contentAlreadyOnMain(branch.head, run5));
|
|
33425
|
+
}
|
|
33426
|
+
return verdicts;
|
|
33427
|
+
}
|
|
33428
|
+
|
|
33396
33429
|
// ../../src/lib/work-risk/push-state.ts
|
|
33397
33430
|
var REMOTE_BRANCH_REF_PREFIX = "refs/remotes/origin/";
|
|
33398
33431
|
var REMOTE_BRANCH_TIPS_FORMAT = "%(refname)%09%(objectname)";
|
|
@@ -33432,7 +33465,7 @@ function run(command, args, cwd) {
|
|
|
33432
33465
|
status: e.status ?? 1,
|
|
33433
33466
|
stdout: e.stdout ?? "",
|
|
33434
33467
|
stderr: e.stderr ?? "",
|
|
33435
|
-
timedOut:
|
|
33468
|
+
timedOut: isTimeoutError(err2)
|
|
33436
33469
|
};
|
|
33437
33470
|
}
|
|
33438
33471
|
}
|
|
@@ -33441,7 +33474,7 @@ function git(args, cwd) {
|
|
|
33441
33474
|
}
|
|
33442
33475
|
var WORKTREE_STATUS_CONCURRENCY = 8;
|
|
33443
33476
|
var WORKTREE_STATUS_TIMEOUT_MS = 2e3;
|
|
33444
|
-
function gitAsync(args, cwd) {
|
|
33477
|
+
function gitAsync(args, cwd, timeoutMs = WORKTREE_STATUS_TIMEOUT_MS) {
|
|
33445
33478
|
return new Promise((resolve7) => {
|
|
33446
33479
|
execFile3(
|
|
33447
33480
|
"git",
|
|
@@ -33450,14 +33483,14 @@ function gitAsync(args, cwd) {
|
|
|
33450
33483
|
cwd,
|
|
33451
33484
|
encoding: "utf8",
|
|
33452
33485
|
maxBuffer: 10 * 1024 * 1024,
|
|
33453
|
-
timeout:
|
|
33486
|
+
timeout: timeoutMs
|
|
33454
33487
|
},
|
|
33455
33488
|
(error62, stdout, stderr) => {
|
|
33456
33489
|
resolve7({
|
|
33457
33490
|
status: error62 ? 1 : 0,
|
|
33458
33491
|
stdout: stdout ?? "",
|
|
33459
33492
|
stderr: stderr ?? "",
|
|
33460
|
-
timedOut: error62
|
|
33493
|
+
timedOut: isTimeoutError(error62)
|
|
33461
33494
|
});
|
|
33462
33495
|
}
|
|
33463
33496
|
);
|
|
@@ -33621,35 +33654,52 @@ async function auditWorktrees(root, localBranches) {
|
|
|
33621
33654
|
const branchByHead = new Map(
|
|
33622
33655
|
localBranches.map((branch) => [branch.head, branch])
|
|
33623
33656
|
);
|
|
33624
|
-
|
|
33625
|
-
|
|
33657
|
+
const parsed = parseWorktrees(raw);
|
|
33658
|
+
const statusArgs = ["--no-optional-locks", "status", "--porcelain"];
|
|
33659
|
+
const statuses = await mapConcurrent(
|
|
33660
|
+
parsed,
|
|
33626
33661
|
WORKTREE_STATUS_CONCURRENCY,
|
|
33627
|
-
|
|
33628
|
-
|
|
33629
|
-
|
|
33630
|
-
|
|
33662
|
+
(worktree) => gitAsync(statusArgs, worktree.path)
|
|
33663
|
+
);
|
|
33664
|
+
for (const [index, worktree] of parsed.entries()) {
|
|
33665
|
+
if (statuses[index].timedOut)
|
|
33666
|
+
statuses[index] = await gitAsync(
|
|
33667
|
+
statusArgs,
|
|
33668
|
+
worktree.path,
|
|
33669
|
+
LOCAL_COMMAND_TIMEOUT_MS
|
|
33631
33670
|
);
|
|
33632
|
-
|
|
33633
|
-
|
|
33634
|
-
|
|
33635
|
-
|
|
33636
|
-
|
|
33637
|
-
|
|
33638
|
-
|
|
33639
|
-
|
|
33640
|
-
|
|
33641
|
-
|
|
33642
|
-
|
|
33643
|
-
|
|
33644
|
-
|
|
33645
|
-
|
|
33646
|
-
|
|
33647
|
-
|
|
33671
|
+
}
|
|
33672
|
+
return parsed.map((worktree, index) => {
|
|
33673
|
+
const status = statuses[index];
|
|
33674
|
+
const branch = branchByName.get(worktree.branch) ?? branchByHead.get(worktree.head);
|
|
33675
|
+
const baseAudit = {
|
|
33676
|
+
path: worktree.path,
|
|
33677
|
+
branch: worktree.branch,
|
|
33678
|
+
head: worktree.head,
|
|
33679
|
+
dirty: status.status !== 0 || status.stdout.trim().length > 0,
|
|
33680
|
+
mergedToMain: branch?.mergedToMain ?? false,
|
|
33681
|
+
upstream: branch?.upstream ?? null,
|
|
33682
|
+
upstreamGone: branch?.upstreamGone ?? false,
|
|
33683
|
+
remoteHasHead: branch?.remoteHasHead ?? false,
|
|
33684
|
+
behindMain: branch?.behindMain ?? 0,
|
|
33685
|
+
aheadMain: branch?.aheadMain ?? 0,
|
|
33686
|
+
countsExact: branch?.countsExact ?? false
|
|
33687
|
+
};
|
|
33688
|
+
return { ...baseAudit, classification: classifyWorktree(baseAudit) };
|
|
33689
|
+
});
|
|
33690
|
+
}
|
|
33691
|
+
var CONTENT_CHECK_BUDGET_MS = 6e4;
|
|
33692
|
+
function auditDetachedLocalBranches(localBranches, checkedOutBranches, root) {
|
|
33693
|
+
const detached = localBranches.filter(
|
|
33694
|
+
({ branch }) => !checkedOutBranches.has(branch)
|
|
33648
33695
|
);
|
|
33649
|
-
|
|
33650
|
-
|
|
33651
|
-
|
|
33652
|
-
|
|
33696
|
+
const contentOnMain = contentOnMainWithinBudget(
|
|
33697
|
+
detached.filter((b) => !b.mergedToMain && !b.remoteHasHead),
|
|
33698
|
+
(args) => git(args, root),
|
|
33699
|
+
CONTENT_CHECK_BUDGET_MS
|
|
33700
|
+
);
|
|
33701
|
+
return detached.map((detachedBranch) => {
|
|
33702
|
+
const {
|
|
33653
33703
|
branch,
|
|
33654
33704
|
head,
|
|
33655
33705
|
mergedToMain,
|
|
@@ -33660,7 +33710,8 @@ function auditDetachedLocalBranches(localBranches, checkedOutBranches) {
|
|
|
33660
33710
|
upstreamGone,
|
|
33661
33711
|
remoteHasHead: remoteHasHead2,
|
|
33662
33712
|
committedAt
|
|
33663
|
-
}
|
|
33713
|
+
} = detachedBranch;
|
|
33714
|
+
return {
|
|
33664
33715
|
branch,
|
|
33665
33716
|
head,
|
|
33666
33717
|
mergedToMain,
|
|
@@ -33676,9 +33727,10 @@ function auditDetachedLocalBranches(localBranches, checkedOutBranches) {
|
|
|
33676
33727
|
remoteHasHead: remoteHasHead2,
|
|
33677
33728
|
// Without this the grace window read `ageMs = Infinity` for every
|
|
33678
33729
|
// branch, so a branch was "stranded" from its first second.
|
|
33679
|
-
committedAt
|
|
33680
|
-
|
|
33681
|
-
|
|
33730
|
+
committedAt,
|
|
33731
|
+
contentOnMain: contentOnMain.get(detachedBranch) ?? null
|
|
33732
|
+
};
|
|
33733
|
+
});
|
|
33682
33734
|
}
|
|
33683
33735
|
function auditRemoteBranchesWithoutPullRequests(root, openPullRequests) {
|
|
33684
33736
|
const openHeads = new Set(openPullRequests.map((pr) => pr.headRefName));
|
|
@@ -33772,7 +33824,8 @@ async function collectWorkStatus(opts) {
|
|
|
33772
33824
|
);
|
|
33773
33825
|
const detachedBranches = auditDetachedLocalBranches(
|
|
33774
33826
|
localBranches,
|
|
33775
|
-
checkedOutBranches
|
|
33827
|
+
checkedOutBranches,
|
|
33828
|
+
root
|
|
33776
33829
|
);
|
|
33777
33830
|
const openPullRequestResult = readOpenPullRequests(root);
|
|
33778
33831
|
if (openPullRequestResult === null)
|
|
@@ -56262,7 +56315,7 @@ var hasSearchParameters = (search) => {
|
|
|
56262
56315
|
function isHTTPError(error62) {
|
|
56263
56316
|
return error62 instanceof HTTPError || error62?.name === HTTPError.name;
|
|
56264
56317
|
}
|
|
56265
|
-
function
|
|
56318
|
+
function isTimeoutError2(error62) {
|
|
56266
56319
|
return error62 instanceof TimeoutError || error62?.name === TimeoutError.name;
|
|
56267
56320
|
}
|
|
56268
56321
|
|
|
@@ -56468,7 +56521,7 @@ var Ky = class _Ky {
|
|
|
56468
56521
|
return this.#calculateDelay();
|
|
56469
56522
|
}
|
|
56470
56523
|
}
|
|
56471
|
-
if (
|
|
56524
|
+
if (isTimeoutError2(error62) && !this.#options.retry.retryOnTimeout) {
|
|
56472
56525
|
throw error62;
|
|
56473
56526
|
}
|
|
56474
56527
|
if (isHTTPError(error62)) {
|