@great-arrow/cli 0.1.49 → 0.1.50
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 +58 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9399,7 +9399,7 @@ function isNodeError(value) {
|
|
|
9399
9399
|
|
|
9400
9400
|
// src/lib/version.ts
|
|
9401
9401
|
var CLI_PACKAGE_NAME = "@great-arrow/cli";
|
|
9402
|
-
var CLI_VERSION = "0.1.
|
|
9402
|
+
var CLI_VERSION = "0.1.50";
|
|
9403
9403
|
var GAD_INSTALL_VERSION = "2026.08.08";
|
|
9404
9404
|
var GAD_INSTALL_MIN_VERSION = "2026.06.22";
|
|
9405
9405
|
var GAD_INSTALL_HEADER = "X-GAD-Install-Version";
|
|
@@ -10543,12 +10543,13 @@ var EXIT_SESSION_EXPIRED = 2;
|
|
|
10543
10543
|
var EXIT_NOT_OAUTH = 3;
|
|
10544
10544
|
function authCommand() {
|
|
10545
10545
|
const cmd = new Command("auth").description("Authentication helpers");
|
|
10546
|
-
cmd.command("token").description("Print a fresh OAuth access token, refreshing it if needed").option("--json", "Output {accessToken, accessExpiresAt, apiUrl} as JSON").action(async (options) => {
|
|
10546
|
+
cmd.command("token").description("Print a fresh OAuth access token, refreshing it if needed").option("--json", "Output {accessToken, accessExpiresAt, apiUrl} as JSON").action(async (options, actionCommand) => {
|
|
10547
10547
|
try {
|
|
10548
10548
|
const t = await getFreshOAuthAccessToken();
|
|
10549
10549
|
writeCliLocator();
|
|
10550
|
+
const jsonOutput = options.json || actionCommand.optsWithGlobals().json;
|
|
10550
10551
|
process.stdout.write(
|
|
10551
|
-
|
|
10552
|
+
jsonOutput ? `${JSON.stringify(t)}
|
|
10552
10553
|
` : `${t.accessToken}
|
|
10553
10554
|
`
|
|
10554
10555
|
);
|
|
@@ -11958,6 +11959,29 @@ import { readFileSync } from "node:fs";
|
|
|
11958
11959
|
|
|
11959
11960
|
// src/lib/work-status.ts
|
|
11960
11961
|
import { execFile as execFile2, execFileSync as execFileSync2 } from "node:child_process";
|
|
11962
|
+
|
|
11963
|
+
// ../../src/lib/work-risk/push-state.ts
|
|
11964
|
+
var REMOTE_BRANCH_REF_PREFIX = "refs/remotes/origin/";
|
|
11965
|
+
var REMOTE_BRANCH_TIPS_FORMAT = "%(refname)%09%(objectname)";
|
|
11966
|
+
function parseRemoteBranchTips(raw) {
|
|
11967
|
+
const tips = /* @__PURE__ */ new Map();
|
|
11968
|
+
for (const line of raw.split("\n")) {
|
|
11969
|
+
const [refname, sha] = line.split(" ");
|
|
11970
|
+
if (!refname?.startsWith(REMOTE_BRANCH_REF_PREFIX) || !sha) continue;
|
|
11971
|
+
const branch = refname.slice(REMOTE_BRANCH_REF_PREFIX.length);
|
|
11972
|
+
if (!branch || branch === "HEAD") continue;
|
|
11973
|
+
tips.set(branch, sha.trim());
|
|
11974
|
+
}
|
|
11975
|
+
return tips;
|
|
11976
|
+
}
|
|
11977
|
+
function remoteHasHead(branch, head, tips, isAncestor2) {
|
|
11978
|
+
const tip = tips.get(branch);
|
|
11979
|
+
if (!tip) return false;
|
|
11980
|
+
if (tip === head) return true;
|
|
11981
|
+
return isAncestor2(head, tip);
|
|
11982
|
+
}
|
|
11983
|
+
|
|
11984
|
+
// src/lib/work-status.ts
|
|
11961
11985
|
var LOCAL_COMMAND_TIMEOUT_MS = 2e4;
|
|
11962
11986
|
function run(command, args, cwd) {
|
|
11963
11987
|
try {
|
|
@@ -12070,9 +12094,31 @@ function auditLocalBranches(root) {
|
|
|
12070
12094
|
root
|
|
12071
12095
|
).split("\n").filter(Boolean)
|
|
12072
12096
|
);
|
|
12097
|
+
const tipsResult = git(
|
|
12098
|
+
[
|
|
12099
|
+
"for-each-ref",
|
|
12100
|
+
`--format=${REMOTE_BRANCH_TIPS_FORMAT}`,
|
|
12101
|
+
"refs/remotes/origin"
|
|
12102
|
+
],
|
|
12103
|
+
root
|
|
12104
|
+
);
|
|
12105
|
+
const tips = parseRemoteBranchTips(
|
|
12106
|
+
tipsResult.status === 0 ? tipsResult.stdout : ""
|
|
12107
|
+
);
|
|
12073
12108
|
return raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
12074
12109
|
const parsed = parseLocalBranchLine(line, exact, unmerged);
|
|
12075
|
-
|
|
12110
|
+
if (!parsed) return [];
|
|
12111
|
+
return [
|
|
12112
|
+
{
|
|
12113
|
+
...parsed,
|
|
12114
|
+
remoteHasHead: remoteHasHead(
|
|
12115
|
+
parsed.branch,
|
|
12116
|
+
parsed.head,
|
|
12117
|
+
tips,
|
|
12118
|
+
(ancestor, descendant) => isAncestor(ancestor, descendant, root)
|
|
12119
|
+
)
|
|
12120
|
+
}
|
|
12121
|
+
];
|
|
12076
12122
|
});
|
|
12077
12123
|
}
|
|
12078
12124
|
function parseLocalBranchLine(line, exact, unmerged) {
|
|
@@ -12131,7 +12177,7 @@ function classifyWorktree(audit) {
|
|
|
12131
12177
|
if (audit.path.includes("/.claude/worktrees/")) return "agent-harness";
|
|
12132
12178
|
if (audit.mergedToMain) return "cleanup-ready";
|
|
12133
12179
|
if (audit.upstreamGone) return "upstream-gone";
|
|
12134
|
-
if (!audit.
|
|
12180
|
+
if (!audit.remoteHasHead) return "local-rescue";
|
|
12135
12181
|
return "active-unmerged";
|
|
12136
12182
|
}
|
|
12137
12183
|
async function auditWorktrees(root, localBranches) {
|
|
@@ -12159,6 +12205,7 @@ async function auditWorktrees(root, localBranches) {
|
|
|
12159
12205
|
mergedToMain: branch?.mergedToMain ?? false,
|
|
12160
12206
|
upstream: branch?.upstream ?? null,
|
|
12161
12207
|
upstreamGone: branch?.upstreamGone ?? false,
|
|
12208
|
+
remoteHasHead: branch?.remoteHasHead ?? false,
|
|
12162
12209
|
behindMain: branch?.behindMain ?? 0,
|
|
12163
12210
|
aheadMain: branch?.aheadMain ?? 0,
|
|
12164
12211
|
countsExact: branch?.countsExact ?? false
|
|
@@ -12178,6 +12225,7 @@ function auditDetachedLocalBranches(localBranches, checkedOutBranches) {
|
|
|
12178
12225
|
countsExact,
|
|
12179
12226
|
upstream,
|
|
12180
12227
|
upstreamGone,
|
|
12228
|
+
remoteHasHead: remoteHasHead2,
|
|
12181
12229
|
committedAt
|
|
12182
12230
|
}) => ({
|
|
12183
12231
|
branch,
|
|
@@ -12186,12 +12234,13 @@ function auditDetachedLocalBranches(localBranches, checkedOutBranches) {
|
|
|
12186
12234
|
behindMain,
|
|
12187
12235
|
aheadMain,
|
|
12188
12236
|
countsExact,
|
|
12189
|
-
// `
|
|
12190
|
-
// just has no PR yet" — the single bit that decides whether
|
|
12191
|
-
// actually be lost.
|
|
12192
|
-
//
|
|
12237
|
+
// `remoteHasHead` is what separates "never left this disk" from
|
|
12238
|
+
// "pushed, just has no PR yet" — the single bit that decides whether
|
|
12239
|
+
// work can actually be lost. `upstream` alone cannot: a task branch
|
|
12240
|
+
// could carry origin/main as its upstream without ever being pushed.
|
|
12193
12241
|
upstream,
|
|
12194
12242
|
upstreamGone,
|
|
12243
|
+
remoteHasHead: remoteHasHead2,
|
|
12195
12244
|
// Without this the grace window read `ageMs = Infinity` for every
|
|
12196
12245
|
// branch, so a branch was "stranded" from its first second.
|
|
12197
12246
|
committedAt
|