@great-arrow/cli 0.1.45 → 0.1.47
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/README.md +7 -0
- package/dist/index.js +264 -138
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,6 +38,13 @@ gad whoami
|
|
|
38
38
|
|
|
39
39
|
# Revoke the session server-side and remove stored credentials
|
|
40
40
|
gad logout
|
|
41
|
+
|
|
42
|
+
# For tools, not humans: print a fresh access token through the CLI's locked
|
|
43
|
+
# refresh path (~/.great-arrow/refresh.lock), so other programs never refresh
|
|
44
|
+
# this credential themselves. --json prints {accessToken, accessExpiresAt,
|
|
45
|
+
# apiUrl}. Exit 2: session expired or not signed in. Exit 3: the stored
|
|
46
|
+
# credential is a personal token (nothing to refresh).
|
|
47
|
+
gad auth token [--json]
|
|
41
48
|
```
|
|
42
49
|
|
|
43
50
|
Credentials live in your OS keychain (Keychain Access / libsecret / Credential
|
package/dist/index.js
CHANGED
|
@@ -1964,7 +1964,7 @@ var require_minimist = __commonJS({
|
|
|
1964
1964
|
var require_rc = __commonJS({
|
|
1965
1965
|
"node_modules/.pnpm/rc@1.2.8/node_modules/rc/index.js"(exports, module) {
|
|
1966
1966
|
var cc = require_utils();
|
|
1967
|
-
var
|
|
1967
|
+
var join9 = __require("path").join;
|
|
1968
1968
|
var deepExtend = require_deep_extend();
|
|
1969
1969
|
var etc = "/etc";
|
|
1970
1970
|
var win = process.platform === "win32";
|
|
@@ -1989,15 +1989,15 @@ var require_rc = __commonJS({
|
|
|
1989
1989
|
}
|
|
1990
1990
|
if (!win)
|
|
1991
1991
|
[
|
|
1992
|
-
|
|
1993
|
-
|
|
1992
|
+
join9(etc, name, "config"),
|
|
1993
|
+
join9(etc, name + "rc")
|
|
1994
1994
|
].forEach(addConfigFile);
|
|
1995
1995
|
if (home)
|
|
1996
1996
|
[
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
1997
|
+
join9(home, ".config", name, "config"),
|
|
1998
|
+
join9(home, ".config", name),
|
|
1999
|
+
join9(home, "." + name, "config"),
|
|
2000
|
+
join9(home, "." + name + "rc")
|
|
2001
2001
|
].forEach(addConfigFile);
|
|
2002
2002
|
addConfigFile(cc.find("." + name + "rc"));
|
|
2003
2003
|
if (env4.config) addConfigFile(env4.config);
|
|
@@ -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.47";
|
|
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";
|
|
@@ -9538,10 +9538,55 @@ async function clearStoredCredential() {
|
|
|
9538
9538
|
await deleteToken();
|
|
9539
9539
|
}
|
|
9540
9540
|
|
|
9541
|
+
// src/lib/cli-locator.ts
|
|
9542
|
+
import {
|
|
9543
|
+
chmodSync,
|
|
9544
|
+
mkdirSync,
|
|
9545
|
+
realpathSync,
|
|
9546
|
+
renameSync,
|
|
9547
|
+
rmSync,
|
|
9548
|
+
writeFileSync
|
|
9549
|
+
} from "node:fs";
|
|
9550
|
+
import { homedir as homedir2 } from "node:os";
|
|
9551
|
+
import { join as join2 } from "node:path";
|
|
9552
|
+
function writeCliLocator(home = homedir2(), entry = process.argv[1]) {
|
|
9553
|
+
if (!entry) return;
|
|
9554
|
+
const dir = join2(home, ".great-arrow");
|
|
9555
|
+
const target = join2(dir, "cli-bin.json");
|
|
9556
|
+
const tmp = `${target}.${process.pid}.tmp`;
|
|
9557
|
+
try {
|
|
9558
|
+
let resolved = entry;
|
|
9559
|
+
try {
|
|
9560
|
+
resolved = realpathSync(entry);
|
|
9561
|
+
} catch (err) {
|
|
9562
|
+
debugSwallow("cli-locator.realpath", err);
|
|
9563
|
+
}
|
|
9564
|
+
mkdirSync(dir, { recursive: true });
|
|
9565
|
+
writeFileSync(
|
|
9566
|
+
tmp,
|
|
9567
|
+
JSON.stringify({
|
|
9568
|
+
node: process.execPath,
|
|
9569
|
+
entry: resolved,
|
|
9570
|
+
version: CLI_VERSION
|
|
9571
|
+
}),
|
|
9572
|
+
{ mode: 384 }
|
|
9573
|
+
);
|
|
9574
|
+
chmodSync(tmp, 384);
|
|
9575
|
+
renameSync(tmp, target);
|
|
9576
|
+
} catch (err) {
|
|
9577
|
+
debugSwallow("cli-locator.write", err);
|
|
9578
|
+
try {
|
|
9579
|
+
rmSync(tmp, { force: true });
|
|
9580
|
+
} catch (cleanupErr) {
|
|
9581
|
+
debugSwallow("cli-locator.cleanup", cleanupErr);
|
|
9582
|
+
}
|
|
9583
|
+
}
|
|
9584
|
+
}
|
|
9585
|
+
|
|
9541
9586
|
// src/lib/config.ts
|
|
9542
9587
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "node:fs/promises";
|
|
9543
|
-
import { homedir as
|
|
9544
|
-
import { join as
|
|
9588
|
+
import { homedir as homedir3 } from "node:os";
|
|
9589
|
+
import { join as join3, dirname as dirname2 } from "node:path";
|
|
9545
9590
|
var DEFAULTS = {
|
|
9546
9591
|
api_url: "https://www.greatarrow.ai",
|
|
9547
9592
|
default_workspace: "",
|
|
@@ -9552,7 +9597,7 @@ var DEFAULTS = {
|
|
|
9552
9597
|
telemetry_enabled: false
|
|
9553
9598
|
};
|
|
9554
9599
|
function getConfigPath() {
|
|
9555
|
-
return
|
|
9600
|
+
return join3(homedir3(), ".gadrc");
|
|
9556
9601
|
}
|
|
9557
9602
|
function parseConfig(content) {
|
|
9558
9603
|
const config = {};
|
|
@@ -9849,11 +9894,13 @@ function toCredential(env4, apiUrl, clientId, now) {
|
|
|
9849
9894
|
apiUrl: trimSlash2(apiUrl)
|
|
9850
9895
|
};
|
|
9851
9896
|
}
|
|
9852
|
-
|
|
9897
|
+
var TOKEN_POST_TIMEOUT_MS = 8e3;
|
|
9898
|
+
async function postToken(apiUrl, form, fetchImpl, timeoutMs = TOKEN_POST_TIMEOUT_MS) {
|
|
9853
9899
|
const res = await fetchImpl(`${trimSlash2(apiUrl)}/api/oauth/token`, {
|
|
9854
9900
|
method: "POST",
|
|
9855
9901
|
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
9856
|
-
body: new URLSearchParams(form).toString()
|
|
9902
|
+
body: new URLSearchParams(form).toString(),
|
|
9903
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
9857
9904
|
});
|
|
9858
9905
|
const json = await res.json().catch(() => ({}));
|
|
9859
9906
|
return { ok: res.ok, status: res.status, json };
|
|
@@ -9894,7 +9941,8 @@ async function revokeToken(opts) {
|
|
|
9894
9941
|
const res = await doFetch(`${trimSlash2(opts.apiUrl)}/api/oauth/revoke`, {
|
|
9895
9942
|
method: "POST",
|
|
9896
9943
|
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
9897
|
-
body: new URLSearchParams(form).toString()
|
|
9944
|
+
body: new URLSearchParams(form).toString(),
|
|
9945
|
+
signal: AbortSignal.timeout(TOKEN_POST_TIMEOUT_MS)
|
|
9898
9946
|
});
|
|
9899
9947
|
return res.ok;
|
|
9900
9948
|
} catch {
|
|
@@ -9910,7 +9958,8 @@ async function refreshTokens(opts) {
|
|
|
9910
9958
|
client_id: opts.clientId,
|
|
9911
9959
|
refresh_token: opts.refreshToken
|
|
9912
9960
|
},
|
|
9913
|
-
opts.fetchImpl ?? fetch
|
|
9961
|
+
opts.fetchImpl ?? fetch,
|
|
9962
|
+
opts.timeoutMs
|
|
9914
9963
|
);
|
|
9915
9964
|
if (!ok) {
|
|
9916
9965
|
const desc = String(json.error_description ?? json.error ?? "unknown");
|
|
@@ -10284,6 +10333,7 @@ var loginCommand = new Command("login").description("Authenticate the CLI with y
|
|
|
10284
10333
|
process.exitCode = 1;
|
|
10285
10334
|
return;
|
|
10286
10335
|
}
|
|
10336
|
+
writeCliLocator();
|
|
10287
10337
|
config.cli_client_id = result.clientId;
|
|
10288
10338
|
config.cli_redirect_uri = result.redirectUri;
|
|
10289
10339
|
config.api_url = DEFAULT_API_URL;
|
|
@@ -10303,52 +10353,22 @@ var loginCommand = new Command("login").description("Authenticate the CLI with y
|
|
|
10303
10353
|
);
|
|
10304
10354
|
var login_default = loginCommand;
|
|
10305
10355
|
|
|
10306
|
-
// src/commands/logout.ts
|
|
10307
|
-
var logoutCommand = new Command("logout").description("Remove stored authentication credentials").action(async (_options, cmd) => {
|
|
10308
|
-
const parent = cmd.parent;
|
|
10309
|
-
const json = parent?.opts().json ?? false;
|
|
10310
|
-
const quiet = parent?.opts().quiet ?? false;
|
|
10311
|
-
const noColor = parent?.opts().noColor ?? false;
|
|
10312
|
-
const fmt = createFormatter({
|
|
10313
|
-
json,
|
|
10314
|
-
quiet,
|
|
10315
|
-
isTTY: isTTY(),
|
|
10316
|
-
noColor
|
|
10317
|
-
});
|
|
10318
|
-
const stored = await loadStoredCredential();
|
|
10319
|
-
if (stored?.kind === "oauth") {
|
|
10320
|
-
await revokeToken({
|
|
10321
|
-
apiUrl: stored.credential.apiUrl,
|
|
10322
|
-
clientId: stored.credential.clientId,
|
|
10323
|
-
token: stored.credential.refreshToken,
|
|
10324
|
-
tokenTypeHint: "refresh_token"
|
|
10325
|
-
});
|
|
10326
|
-
}
|
|
10327
|
-
await clearStoredCredential();
|
|
10328
|
-
const config = await loadConfig();
|
|
10329
|
-
if (config.token) {
|
|
10330
|
-
config.token = "";
|
|
10331
|
-
await saveConfig(config);
|
|
10332
|
-
}
|
|
10333
|
-
fmt.success("Logged out successfully.");
|
|
10334
|
-
});
|
|
10335
|
-
|
|
10336
10356
|
// src/lib/auth.ts
|
|
10337
10357
|
import { mkdir as mkdir3, open, rm, stat } from "node:fs/promises";
|
|
10338
|
-
import { homedir as
|
|
10339
|
-
import { join as
|
|
10358
|
+
import { homedir as homedir4 } from "node:os";
|
|
10359
|
+
import { join as join4 } from "node:path";
|
|
10340
10360
|
var REFRESH_SKEW_MS = 12e4;
|
|
10341
10361
|
var inflightRefresh = null;
|
|
10342
10362
|
var REFRESH_LOCK_STALE_MS = 15e3;
|
|
10343
10363
|
var REFRESH_LOCK_WAIT_MS = 5e3;
|
|
10344
10364
|
var REFRESH_LOCK_POLL_MS = 100;
|
|
10345
10365
|
function refreshLockPath() {
|
|
10346
|
-
return
|
|
10366
|
+
return join4(homedir4(), ".great-arrow", "refresh.lock");
|
|
10347
10367
|
}
|
|
10348
10368
|
async function acquireRefreshLock() {
|
|
10349
10369
|
const path10 = refreshLockPath();
|
|
10350
10370
|
try {
|
|
10351
|
-
await mkdir3(
|
|
10371
|
+
await mkdir3(join4(homedir4(), ".great-arrow"), { recursive: true });
|
|
10352
10372
|
} catch (err) {
|
|
10353
10373
|
debugSwallow("refresh-lock.mkdir", err);
|
|
10354
10374
|
}
|
|
@@ -10382,7 +10402,7 @@ async function releaseRefreshLock() {
|
|
|
10382
10402
|
debugSwallow("refresh-lock.release", err);
|
|
10383
10403
|
}
|
|
10384
10404
|
}
|
|
10385
|
-
async function
|
|
10405
|
+
async function storedPairOtherThan(ours) {
|
|
10386
10406
|
let stored = null;
|
|
10387
10407
|
try {
|
|
10388
10408
|
stored = await loadStoredCredential();
|
|
@@ -10390,8 +10410,11 @@ async function rotatedByAnotherProcess(ours) {
|
|
|
10390
10410
|
debugSwallow("refresh.reread", err);
|
|
10391
10411
|
}
|
|
10392
10412
|
if (stored?.kind !== "oauth") return null;
|
|
10393
|
-
|
|
10394
|
-
|
|
10413
|
+
return stored.credential.refreshToken === ours.refreshToken ? null : stored.credential;
|
|
10414
|
+
}
|
|
10415
|
+
async function rotatedByAnotherProcess(ours) {
|
|
10416
|
+
const theirs = await storedPairOtherThan(ours);
|
|
10417
|
+
if (!theirs) return null;
|
|
10395
10418
|
if (Date.now() >= theirs.accessExpiresAt - REFRESH_SKEW_MS) return null;
|
|
10396
10419
|
return theirs;
|
|
10397
10420
|
}
|
|
@@ -10439,6 +10462,27 @@ async function resolveAuth() {
|
|
|
10439
10462
|
"Run 'gad login' to authenticate, or set the GAD_TOKEN environment variable."
|
|
10440
10463
|
);
|
|
10441
10464
|
}
|
|
10465
|
+
var NotOAuthCredential = class extends Error {
|
|
10466
|
+
code = "not_oauth";
|
|
10467
|
+
};
|
|
10468
|
+
async function getFreshOAuthAccessToken() {
|
|
10469
|
+
const stored = await loadStoredCredential();
|
|
10470
|
+
if (!stored) {
|
|
10471
|
+
throw authError(
|
|
10472
|
+
"Session expired. Not signed in.",
|
|
10473
|
+
"Run 'gad login' to authenticate."
|
|
10474
|
+
);
|
|
10475
|
+
}
|
|
10476
|
+
if (stored.kind !== "oauth") {
|
|
10477
|
+
throw new NotOAuthCredential("stored credential is not OAuth");
|
|
10478
|
+
}
|
|
10479
|
+
const fresh = await ensureFreshAccessToken(stored.credential);
|
|
10480
|
+
return {
|
|
10481
|
+
accessToken: fresh.accessToken,
|
|
10482
|
+
accessExpiresAt: fresh.accessExpiresAt,
|
|
10483
|
+
apiUrl: fresh.apiUrl
|
|
10484
|
+
};
|
|
10485
|
+
}
|
|
10442
10486
|
async function ensureFreshAccessToken(credential) {
|
|
10443
10487
|
if (Date.now() < credential.accessExpiresAt - REFRESH_SKEW_MS) {
|
|
10444
10488
|
return credential;
|
|
@@ -10468,6 +10512,8 @@ async function doRefresh(credential) {
|
|
|
10468
10512
|
return refreshed;
|
|
10469
10513
|
} catch (err) {
|
|
10470
10514
|
if (err instanceof RefreshRejected) {
|
|
10515
|
+
const theirs = await storedPairOtherThan(credential);
|
|
10516
|
+
if (theirs) return theirs;
|
|
10471
10517
|
await clearStoredCredential();
|
|
10472
10518
|
throw sessionExpired();
|
|
10473
10519
|
}
|
|
@@ -10480,6 +10526,70 @@ function sessionExpired() {
|
|
|
10480
10526
|
return authError("Session expired.", "Run 'gad login' to re-authenticate.");
|
|
10481
10527
|
}
|
|
10482
10528
|
|
|
10529
|
+
// src/commands/auth.ts
|
|
10530
|
+
var EXIT_SESSION_EXPIRED = 2;
|
|
10531
|
+
var EXIT_NOT_OAUTH = 3;
|
|
10532
|
+
function authCommand() {
|
|
10533
|
+
const cmd = new Command("auth").description("Authentication helpers");
|
|
10534
|
+
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) => {
|
|
10535
|
+
try {
|
|
10536
|
+
const t = await getFreshOAuthAccessToken();
|
|
10537
|
+
writeCliLocator();
|
|
10538
|
+
process.stdout.write(
|
|
10539
|
+
options.json ? `${JSON.stringify(t)}
|
|
10540
|
+
` : `${t.accessToken}
|
|
10541
|
+
`
|
|
10542
|
+
);
|
|
10543
|
+
} catch (error) {
|
|
10544
|
+
if (error instanceof NotOAuthCredential) {
|
|
10545
|
+
process.stderr.write(`${error.message}
|
|
10546
|
+
`);
|
|
10547
|
+
process.exitCode = EXIT_NOT_OAUTH;
|
|
10548
|
+
return;
|
|
10549
|
+
}
|
|
10550
|
+
if (error instanceof CliError && error.code === 1) {
|
|
10551
|
+
const hint = error.hint ? ` ${error.hint}` : "";
|
|
10552
|
+
process.stderr.write(`${error.message}${hint}
|
|
10553
|
+
`);
|
|
10554
|
+
process.exitCode = EXIT_SESSION_EXPIRED;
|
|
10555
|
+
return;
|
|
10556
|
+
}
|
|
10557
|
+
throw error;
|
|
10558
|
+
}
|
|
10559
|
+
});
|
|
10560
|
+
return cmd;
|
|
10561
|
+
}
|
|
10562
|
+
|
|
10563
|
+
// src/commands/logout.ts
|
|
10564
|
+
var logoutCommand = new Command("logout").description("Remove stored authentication credentials").action(async (_options, cmd) => {
|
|
10565
|
+
const parent = cmd.parent;
|
|
10566
|
+
const json = parent?.opts().json ?? false;
|
|
10567
|
+
const quiet = parent?.opts().quiet ?? false;
|
|
10568
|
+
const noColor = parent?.opts().noColor ?? false;
|
|
10569
|
+
const fmt = createFormatter({
|
|
10570
|
+
json,
|
|
10571
|
+
quiet,
|
|
10572
|
+
isTTY: isTTY(),
|
|
10573
|
+
noColor
|
|
10574
|
+
});
|
|
10575
|
+
const stored = await loadStoredCredential();
|
|
10576
|
+
if (stored?.kind === "oauth") {
|
|
10577
|
+
await revokeToken({
|
|
10578
|
+
apiUrl: stored.credential.apiUrl,
|
|
10579
|
+
clientId: stored.credential.clientId,
|
|
10580
|
+
token: stored.credential.refreshToken,
|
|
10581
|
+
tokenTypeHint: "refresh_token"
|
|
10582
|
+
});
|
|
10583
|
+
}
|
|
10584
|
+
await clearStoredCredential();
|
|
10585
|
+
const config = await loadConfig();
|
|
10586
|
+
if (config.token) {
|
|
10587
|
+
config.token = "";
|
|
10588
|
+
await saveConfig(config);
|
|
10589
|
+
}
|
|
10590
|
+
fmt.success("Logged out successfully.");
|
|
10591
|
+
});
|
|
10592
|
+
|
|
10483
10593
|
// src/lib/client.ts
|
|
10484
10594
|
import { execSync } from "node:child_process";
|
|
10485
10595
|
|
|
@@ -12302,8 +12412,8 @@ var work_default = workCommand;
|
|
|
12302
12412
|
|
|
12303
12413
|
// src/commands/worktree.ts
|
|
12304
12414
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
12305
|
-
import { existsSync, readFileSync as readFileSync2, statSync, writeFileSync } from "node:fs";
|
|
12306
|
-
import { basename, dirname as dirname3, isAbsolute, join as
|
|
12415
|
+
import { existsSync, readFileSync as readFileSync2, statSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
12416
|
+
import { basename, dirname as dirname3, isAbsolute, join as join5, resolve } from "node:path";
|
|
12307
12417
|
var realExec = (cmd, args, opts) => {
|
|
12308
12418
|
const out = execFileSync3(cmd, args, {
|
|
12309
12419
|
cwd: opts?.cwd,
|
|
@@ -12325,9 +12435,9 @@ function parseDefaultBranch(symbolicRef) {
|
|
|
12325
12435
|
return match ? match[1] : null;
|
|
12326
12436
|
}
|
|
12327
12437
|
function detectPackageManager(repoRoot) {
|
|
12328
|
-
if (existsSync(
|
|
12329
|
-
if (existsSync(
|
|
12330
|
-
if (existsSync(
|
|
12438
|
+
if (existsSync(join5(repoRoot, "pnpm-lock.yaml"))) return "pnpm";
|
|
12439
|
+
if (existsSync(join5(repoRoot, "bun.lockb"))) return "bun";
|
|
12440
|
+
if (existsSync(join5(repoRoot, "yarn.lock"))) return "yarn";
|
|
12331
12441
|
return "npm";
|
|
12332
12442
|
}
|
|
12333
12443
|
function defaultWorktreeDir(repoRoot, branch) {
|
|
@@ -12335,7 +12445,7 @@ function defaultWorktreeDir(repoRoot, branch) {
|
|
|
12335
12445
|
/[^A-Za-z0-9._-]+/g,
|
|
12336
12446
|
"-"
|
|
12337
12447
|
);
|
|
12338
|
-
return
|
|
12448
|
+
return join5(dirname3(repoRoot), `${basename(repoRoot)}-${slug}`);
|
|
12339
12449
|
}
|
|
12340
12450
|
var AGENT_PROCESS_RE = /(^|\/)(claude|kiro|cursor|codex)/i;
|
|
12341
12451
|
function psField(pid, field) {
|
|
@@ -12358,7 +12468,7 @@ function findAgentPid(startPid) {
|
|
|
12358
12468
|
return null;
|
|
12359
12469
|
}
|
|
12360
12470
|
function ownGitDir(worktreeDir) {
|
|
12361
|
-
const dotGit =
|
|
12471
|
+
const dotGit = join5(worktreeDir, ".git");
|
|
12362
12472
|
if (!existsSync(dotGit)) return null;
|
|
12363
12473
|
if (statSync(dotGit).isDirectory()) return dotGit;
|
|
12364
12474
|
const match = readFileSync2(dotGit, "utf8").trim().match(/^gitdir:\s*(.+)$/m);
|
|
@@ -12372,8 +12482,8 @@ function stampWorktreeOwner(worktreeDir) {
|
|
|
12372
12482
|
if (!gitDir) return null;
|
|
12373
12483
|
const ownerPid = findAgentPid(process.ppid);
|
|
12374
12484
|
if (!ownerPid) return null;
|
|
12375
|
-
|
|
12376
|
-
|
|
12485
|
+
writeFileSync2(
|
|
12486
|
+
join5(gitDir, "agent-owner.json"),
|
|
12377
12487
|
JSON.stringify(
|
|
12378
12488
|
{
|
|
12379
12489
|
ownerPid,
|
|
@@ -12467,7 +12577,7 @@ function createTaskWorktree(opts) {
|
|
|
12467
12577
|
const stampedPid = opts.stamp === false ? null : stampWorktreeOwner(dir);
|
|
12468
12578
|
const packageManager = detectPackageManager(repoRoot);
|
|
12469
12579
|
let installed = false;
|
|
12470
|
-
if (opts.install !== false && existsSync(
|
|
12580
|
+
if (opts.install !== false && existsSync(join5(repoRoot, "package.json"))) {
|
|
12471
12581
|
exec2(packageManager, ["install"], { cwd: dir, inherit: true });
|
|
12472
12582
|
installed = true;
|
|
12473
12583
|
}
|
|
@@ -12530,13 +12640,13 @@ var worktree_default = worktreeCommand;
|
|
|
12530
12640
|
// src/commands/install-hooks.ts
|
|
12531
12641
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
12532
12642
|
import {
|
|
12533
|
-
chmodSync,
|
|
12643
|
+
chmodSync as chmodSync2,
|
|
12534
12644
|
existsSync as existsSync2,
|
|
12535
|
-
mkdirSync,
|
|
12645
|
+
mkdirSync as mkdirSync2,
|
|
12536
12646
|
readFileSync as readFileSync3,
|
|
12537
|
-
writeFileSync as
|
|
12647
|
+
writeFileSync as writeFileSync3
|
|
12538
12648
|
} from "node:fs";
|
|
12539
|
-
import { isAbsolute as isAbsolute2, join as
|
|
12649
|
+
import { isAbsolute as isAbsolute2, join as join6, resolve as resolve2 } from "node:path";
|
|
12540
12650
|
var GUARD_MARKER = "# gad-agent-guard v1";
|
|
12541
12651
|
var SCHEMA_AUDIT_MARKER = "# gad-schema-audit v1";
|
|
12542
12652
|
var GUARD_FILE = "gad-commit-guard.mjs";
|
|
@@ -12719,28 +12829,28 @@ function installCommitGuard(opts) {
|
|
|
12719
12829
|
);
|
|
12720
12830
|
}
|
|
12721
12831
|
if (!isAbsolute2(commonDir)) commonDir = resolve2(repoRoot, commonDir);
|
|
12722
|
-
const hooksDir =
|
|
12723
|
-
|
|
12724
|
-
const guardPath =
|
|
12725
|
-
|
|
12726
|
-
|
|
12727
|
-
const huskyHook =
|
|
12728
|
-
const hookPath = existsSync2(huskyHook) ? huskyHook :
|
|
12832
|
+
const hooksDir = join6(commonDir, "hooks");
|
|
12833
|
+
mkdirSync2(hooksDir, { recursive: true });
|
|
12834
|
+
const guardPath = join6(hooksDir, GUARD_FILE);
|
|
12835
|
+
writeFileSync3(guardPath, buildGuardScript());
|
|
12836
|
+
chmodSync2(guardPath, 493);
|
|
12837
|
+
const huskyHook = join6(repoRoot, ".husky", "pre-commit");
|
|
12838
|
+
const hookPath = existsSync2(huskyHook) ? huskyHook : join6(hooksDir, "pre-commit");
|
|
12729
12839
|
const existing = existsSync2(hookPath) ? readFileSync3(hookPath, "utf8") : null;
|
|
12730
12840
|
const plan = planHookInstall(existing);
|
|
12731
12841
|
if (plan.action !== "noop") {
|
|
12732
|
-
|
|
12842
|
+
writeFileSync3(hookPath, plan.content);
|
|
12733
12843
|
}
|
|
12734
|
-
|
|
12735
|
-
const huskyDir =
|
|
12736
|
-
const huskyPrePush =
|
|
12737
|
-
const schemaAuditHookPath = existsSync2(huskyPrePush) || existsSync2(huskyDir) ? huskyPrePush :
|
|
12844
|
+
chmodSync2(hookPath, 493);
|
|
12845
|
+
const huskyDir = join6(repoRoot, ".husky");
|
|
12846
|
+
const huskyPrePush = join6(huskyDir, "pre-push");
|
|
12847
|
+
const schemaAuditHookPath = existsSync2(huskyPrePush) || existsSync2(huskyDir) ? huskyPrePush : join6(hooksDir, "pre-push");
|
|
12738
12848
|
const existingSchemaAuditHook = existsSync2(schemaAuditHookPath) ? readFileSync3(schemaAuditHookPath, "utf8") : null;
|
|
12739
12849
|
const schemaAuditPlan = planSchemaAuditHookInstall(existingSchemaAuditHook);
|
|
12740
12850
|
if (schemaAuditPlan.action !== "noop") {
|
|
12741
|
-
|
|
12851
|
+
writeFileSync3(schemaAuditHookPath, schemaAuditPlan.content);
|
|
12742
12852
|
}
|
|
12743
|
-
|
|
12853
|
+
chmodSync2(schemaAuditHookPath, 493);
|
|
12744
12854
|
return {
|
|
12745
12855
|
guardPath,
|
|
12746
12856
|
hookPath,
|
|
@@ -12858,8 +12968,8 @@ function guardrailsCommand() {
|
|
|
12858
12968
|
// src/commands/doctor.ts
|
|
12859
12969
|
import { existsSync as existsSync3 } from "node:fs";
|
|
12860
12970
|
import { copyFile, mkdir as mkdir4, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
12861
|
-
import { homedir as
|
|
12862
|
-
import { dirname as dirname4, join as
|
|
12971
|
+
import { homedir as homedir5 } from "node:os";
|
|
12972
|
+
import { dirname as dirname4, join as join7 } from "node:path";
|
|
12863
12973
|
|
|
12864
12974
|
// src/lib/codex-config.ts
|
|
12865
12975
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
@@ -14390,7 +14500,7 @@ async function checkMcp(auth) {
|
|
|
14390
14500
|
}
|
|
14391
14501
|
}
|
|
14392
14502
|
function defaultCodexConfigPath() {
|
|
14393
|
-
return
|
|
14503
|
+
return join7(homedir5(), ".codex", "config.toml");
|
|
14394
14504
|
}
|
|
14395
14505
|
function codexIssuesToChecks(issues) {
|
|
14396
14506
|
return issues.map((issue) => {
|
|
@@ -14528,12 +14638,12 @@ function claudeCommand() {
|
|
|
14528
14638
|
isTTY: isTTY(),
|
|
14529
14639
|
noColor: g.noColor
|
|
14530
14640
|
});
|
|
14531
|
-
const home =
|
|
14532
|
-
const gaDir =
|
|
14533
|
-
const userConfigPath =
|
|
14534
|
-
const settingsPath =
|
|
14535
|
-
const hookConfigPath =
|
|
14536
|
-
const glanceHookPath =
|
|
14641
|
+
const home = homedir5();
|
|
14642
|
+
const gaDir = join7(home, ".great-arrow");
|
|
14643
|
+
const userConfigPath = join7(home, ".claude.json");
|
|
14644
|
+
const settingsPath = join7(home, ".claude", "settings.json");
|
|
14645
|
+
const hookConfigPath = join7(gaDir, "hook-config.json");
|
|
14646
|
+
const glanceHookPath = join7(gaDir, "claude-glance-hook.mjs");
|
|
14537
14647
|
const checks = [];
|
|
14538
14648
|
const repairs = [];
|
|
14539
14649
|
const backups = [];
|
|
@@ -14741,8 +14851,8 @@ function claudeCommand() {
|
|
|
14741
14851
|
file: "/Library/Application Support/ClaudeCode/managed-settings.json"
|
|
14742
14852
|
},
|
|
14743
14853
|
{ scope: "user", file: settingsPath },
|
|
14744
|
-
{ scope: "project", file:
|
|
14745
|
-
{ scope: "local", file:
|
|
14854
|
+
{ scope: "project", file: join7(cwd, ".claude", "settings.json") },
|
|
14855
|
+
{ scope: "local", file: join7(cwd, ".claude", "settings.local.json") }
|
|
14746
14856
|
];
|
|
14747
14857
|
const configured = [];
|
|
14748
14858
|
for (const { scope, file } of scopes) {
|
|
@@ -14811,12 +14921,12 @@ function claudeCommand() {
|
|
|
14811
14921
|
});
|
|
14812
14922
|
}
|
|
14813
14923
|
function defaultJsonClientConfigs() {
|
|
14814
|
-
const home =
|
|
14924
|
+
const home = homedir5();
|
|
14815
14925
|
return [
|
|
14816
|
-
{ name: "Claude Code", path:
|
|
14817
|
-
{ name: "Cursor", path:
|
|
14818
|
-
{ name: "Kiro", path:
|
|
14819
|
-
{ name: "Gemini CLI", path:
|
|
14926
|
+
{ name: "Claude Code", path: join7(home, ".claude.json") },
|
|
14927
|
+
{ name: "Cursor", path: join7(home, ".cursor", "mcp.json") },
|
|
14928
|
+
{ name: "Kiro", path: join7(home, ".kiro", "settings", "mcp.json") },
|
|
14929
|
+
{ name: "Gemini CLI", path: join7(home, ".gemini", "settings.json") }
|
|
14820
14930
|
];
|
|
14821
14931
|
}
|
|
14822
14932
|
function clientsCommand() {
|
|
@@ -15462,12 +15572,12 @@ async function pathExists(path10) {
|
|
|
15462
15572
|
}
|
|
15463
15573
|
}
|
|
15464
15574
|
async function installCodexConfig(apiUrl, token, repoUrl) {
|
|
15465
|
-
const { homedir:
|
|
15466
|
-
const { join:
|
|
15575
|
+
const { homedir: homedir7 } = await import("node:os");
|
|
15576
|
+
const { join: join9 } = await import("node:path");
|
|
15467
15577
|
const { chmod, copyFile: copyFile2, mkdir: mkdir6, readFile: readFile5, writeFile: writeFile5 } = await import("node:fs/promises");
|
|
15468
|
-
const codexDir =
|
|
15469
|
-
const configPath =
|
|
15470
|
-
const envPath =
|
|
15578
|
+
const codexDir = join9(homedir7(), ".codex");
|
|
15579
|
+
const configPath = join9(codexDir, "config.toml");
|
|
15580
|
+
const envPath = join9(codexDir, ".env");
|
|
15471
15581
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
15472
15582
|
await mkdir6(codexDir, { recursive: true });
|
|
15473
15583
|
const existingConfig = await pathExists(configPath) ? await readFile5(configPath, "utf8") : "";
|
|
@@ -15766,11 +15876,11 @@ var installCommand = new Command("install").description("Generate MCP configurat
|
|
|
15766
15876
|
process.stdout.write(configJson2 + "\n");
|
|
15767
15877
|
return;
|
|
15768
15878
|
}
|
|
15769
|
-
const { homedir:
|
|
15770
|
-
const { join:
|
|
15879
|
+
const { homedir: homedir7 } = await import("node:os");
|
|
15880
|
+
const { join: join10 } = await import("node:path");
|
|
15771
15881
|
const { mkdir: mkdir6, readFile: readFile5, writeFile: writeFile6 } = await import("node:fs/promises");
|
|
15772
|
-
const geminiDir =
|
|
15773
|
-
const mcpPath =
|
|
15882
|
+
const geminiDir = join10(homedir7(), ".gemini");
|
|
15883
|
+
const mcpPath = join10(geminiDir, "settings.json");
|
|
15774
15884
|
await mkdir6(geminiDir, { recursive: true });
|
|
15775
15885
|
let existingConfig = {};
|
|
15776
15886
|
try {
|
|
@@ -15792,14 +15902,14 @@ var installCommand = new Command("install").description("Generate MCP configurat
|
|
|
15792
15902
|
"utf-8"
|
|
15793
15903
|
);
|
|
15794
15904
|
fmt.success(`Wrote gemini MCP config to ${mcpPath}`);
|
|
15795
|
-
const agyMcpDir =
|
|
15905
|
+
const agyMcpDir = join10(
|
|
15796
15906
|
geminiDir,
|
|
15797
15907
|
"antigravity-cli",
|
|
15798
15908
|
"mcp",
|
|
15799
15909
|
MCP_SERVER_NAME
|
|
15800
15910
|
);
|
|
15801
15911
|
await mkdir6(agyMcpDir, { recursive: true });
|
|
15802
|
-
const instructionsPath =
|
|
15912
|
+
const instructionsPath = join10(agyMcpDir, "instructions.md");
|
|
15803
15913
|
const instructionsContent = `You are connected to greatarrow.ai - the user's private workspace memory + integrations brain.
|
|
15804
15914
|
|
|
15805
15915
|
CRITICAL DIRECTIVE (MANDATORY STANDARD):
|
|
@@ -15831,8 +15941,8 @@ Always assume full autonomy to leverage these tools to their maximum extent.`;
|
|
|
15831
15941
|
return;
|
|
15832
15942
|
}
|
|
15833
15943
|
const { writeFile: writeFile5 } = await import("node:fs/promises");
|
|
15834
|
-
const { join:
|
|
15835
|
-
const outputPath =
|
|
15944
|
+
const { join: join9 } = await import("node:path");
|
|
15945
|
+
const outputPath = join9(process.cwd(), ".mcp.json");
|
|
15836
15946
|
await writeFile5(outputPath, configJson + "\n", { mode: 384 });
|
|
15837
15947
|
fmt.success(`Wrote ${clientName} MCP config to .mcp.json`);
|
|
15838
15948
|
if (await mcpJsonAtRiskOfCommit(process.cwd())) {
|
|
@@ -15863,13 +15973,13 @@ async function readKeychainOnly() {
|
|
|
15863
15973
|
}
|
|
15864
15974
|
}
|
|
15865
15975
|
async function resolveProxyScript(override) {
|
|
15866
|
-
const { homedir:
|
|
15867
|
-
const { join:
|
|
15976
|
+
const { homedir: homedir7 } = await import("node:os");
|
|
15977
|
+
const { join: join9 } = await import("node:path");
|
|
15868
15978
|
const candidates = [
|
|
15869
15979
|
override,
|
|
15870
15980
|
process.env.GAD_PROXY_SCRIPT,
|
|
15871
|
-
|
|
15872
|
-
|
|
15981
|
+
join9(homedir7(), ".great-arrow", "mcp-server.mjs"),
|
|
15982
|
+
join9(process.cwd(), "scripts", "mcp-server.mjs")
|
|
15873
15983
|
].filter((c) => Boolean(c));
|
|
15874
15984
|
for (const candidate of candidates) {
|
|
15875
15985
|
if (await pathExists(candidate)) return candidate;
|
|
@@ -15893,13 +16003,13 @@ async function runProxyDiagnostics(scriptPath) {
|
|
|
15893
16003
|
}
|
|
15894
16004
|
}
|
|
15895
16005
|
async function findLegacyStores(cwd) {
|
|
15896
|
-
const { join:
|
|
16006
|
+
const { join: join9 } = await import("node:path");
|
|
15897
16007
|
const { readdir } = await import("node:fs/promises");
|
|
15898
16008
|
const dirs = /* @__PURE__ */ new Set([cwd]);
|
|
15899
16009
|
try {
|
|
15900
|
-
const worktreeRoot =
|
|
16010
|
+
const worktreeRoot = join9(cwd, ".claude", "worktrees");
|
|
15901
16011
|
for (const entry of await readdir(worktreeRoot, { withFileTypes: true })) {
|
|
15902
|
-
if (entry.isDirectory()) dirs.add(
|
|
16012
|
+
if (entry.isDirectory()) dirs.add(join9(worktreeRoot, entry.name));
|
|
15903
16013
|
}
|
|
15904
16014
|
} catch (err) {
|
|
15905
16015
|
debugSwallow("mcp.findLegacyStores(worktrees)", err);
|
|
@@ -15921,18 +16031,18 @@ async function findLegacyStores(cwd) {
|
|
|
15921
16031
|
}
|
|
15922
16032
|
const stores = [];
|
|
15923
16033
|
for (const dir of dirs) {
|
|
15924
|
-
const path10 =
|
|
16034
|
+
const path10 = join9(dir, ".mcp", OAUTH_CRED_FILENAME);
|
|
15925
16035
|
const raw = await readIfExists(path10);
|
|
15926
16036
|
if (raw !== null) stores.push({ path: path10, raw });
|
|
15927
16037
|
}
|
|
15928
16038
|
return stores;
|
|
15929
16039
|
}
|
|
15930
16040
|
async function scanConnections() {
|
|
15931
|
-
const { homedir:
|
|
15932
|
-
const { join:
|
|
15933
|
-
const home =
|
|
16041
|
+
const { homedir: homedir7 } = await import("node:os");
|
|
16042
|
+
const { join: join9 } = await import("node:path");
|
|
16043
|
+
const home = homedir7();
|
|
15934
16044
|
const hookSettings = await readIfExists(
|
|
15935
|
-
|
|
16045
|
+
join9(home, ".claude", "settings.json")
|
|
15936
16046
|
);
|
|
15937
16047
|
const hooksInstalled = hookSettings ? hasGreatArrowHooks(hookSettings) : false;
|
|
15938
16048
|
const entries = [];
|
|
@@ -15965,16 +16075,16 @@ async function probeEndpoint() {
|
|
|
15965
16075
|
}
|
|
15966
16076
|
}
|
|
15967
16077
|
async function applyMigration(plan) {
|
|
15968
|
-
const { homedir:
|
|
15969
|
-
const { join:
|
|
16078
|
+
const { homedir: homedir7 } = await import("node:os");
|
|
16079
|
+
const { join: join9 } = await import("node:path");
|
|
15970
16080
|
const { mkdir: mkdir6, rename, writeFile: writeFile5 } = await import("node:fs/promises");
|
|
15971
16081
|
const applied = [];
|
|
15972
|
-
const dir =
|
|
16082
|
+
const dir = join9(homedir7(), ".great-arrow");
|
|
15973
16083
|
await mkdir6(dir, { recursive: true, mode: 448 });
|
|
15974
16084
|
if (plan.seedFrom) {
|
|
15975
16085
|
const raw = await readIfExists(plan.seedFrom);
|
|
15976
16086
|
if (raw !== null) {
|
|
15977
|
-
const target =
|
|
16087
|
+
const target = join9(dir, OAUTH_CRED_FILENAME);
|
|
15978
16088
|
const tmp = `${target}.tmp`;
|
|
15979
16089
|
await writeFile5(tmp, raw, { mode: 384 });
|
|
15980
16090
|
await rename(tmp, target);
|
|
@@ -15984,7 +16094,7 @@ async function applyMigration(plan) {
|
|
|
15984
16094
|
if (plan.syncKeychainToFile) {
|
|
15985
16095
|
const raw = await readKeychainOnly();
|
|
15986
16096
|
if (raw) {
|
|
15987
|
-
const target =
|
|
16097
|
+
const target = join9(dir, "credential");
|
|
15988
16098
|
const tmp = `${target}.tmp`;
|
|
15989
16099
|
await writeFile5(tmp, raw, { mode: 384 });
|
|
15990
16100
|
await rename(tmp, target);
|
|
@@ -16010,19 +16120,19 @@ var doctorSubcommand = new Command("doctor").description(
|
|
|
16010
16120
|
noColor: false
|
|
16011
16121
|
});
|
|
16012
16122
|
const c = createColor(jsonFlag);
|
|
16013
|
-
const { homedir:
|
|
16014
|
-
const { join:
|
|
16015
|
-
const home =
|
|
16123
|
+
const { homedir: homedir7 } = await import("node:os");
|
|
16124
|
+
const { join: join9 } = await import("node:path");
|
|
16125
|
+
const home = homedir7();
|
|
16016
16126
|
const proxyPath = await resolveProxyScript(options.proxy);
|
|
16017
16127
|
const diagnostics = proxyPath ? await runProxyDiagnostics(proxyPath) : null;
|
|
16018
16128
|
const entries = await scanConnections();
|
|
16019
16129
|
const duplicates = detectDuplicates(entries);
|
|
16020
16130
|
const keychain = await readKeychainOnly();
|
|
16021
16131
|
const credentialFile = await readIfExists(
|
|
16022
|
-
|
|
16132
|
+
join9(home, ".great-arrow", "credential")
|
|
16023
16133
|
);
|
|
16024
16134
|
const userStore = await readIfExists(
|
|
16025
|
-
|
|
16135
|
+
join9(home, ".great-arrow", OAUTH_CRED_FILENAME)
|
|
16026
16136
|
);
|
|
16027
16137
|
const legacyStores = await findLegacyStores(process.cwd());
|
|
16028
16138
|
const findings = [
|
|
@@ -16447,8 +16557,8 @@ function askCommand() {
|
|
|
16447
16557
|
|
|
16448
16558
|
// src/lib/glance-footer.ts
|
|
16449
16559
|
import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir5 } from "node:fs/promises";
|
|
16450
|
-
import { homedir as
|
|
16451
|
-
import { join as
|
|
16560
|
+
import { homedir as homedir6 } from "node:os";
|
|
16561
|
+
import { join as join8, dirname as dirname5 } from "node:path";
|
|
16452
16562
|
|
|
16453
16563
|
// src/lib/seen.ts
|
|
16454
16564
|
var SEEN_TIMEOUT_MS = 1e3;
|
|
@@ -16570,6 +16680,18 @@ function firstCommand(argv) {
|
|
|
16570
16680
|
}
|
|
16571
16681
|
return null;
|
|
16572
16682
|
}
|
|
16683
|
+
var PRE_DISPATCH_REFUSALS = /* @__PURE__ */ new Set([
|
|
16684
|
+
"workspace_choice_required"
|
|
16685
|
+
]);
|
|
16686
|
+
function refusedBeforeTool(result) {
|
|
16687
|
+
if (typeof result !== "object" || result === null) return false;
|
|
16688
|
+
const r = result;
|
|
16689
|
+
if (r.isError !== true) return false;
|
|
16690
|
+
const body = parseMcpPayload(r.content);
|
|
16691
|
+
if (typeof body !== "object" || body === null) return false;
|
|
16692
|
+
const code = body.error;
|
|
16693
|
+
return typeof code === "string" && PRE_DISPATCH_REFUSALS.has(code);
|
|
16694
|
+
}
|
|
16573
16695
|
async function fetchGlance(apiUrl, token, includeTip) {
|
|
16574
16696
|
const controller = new AbortController();
|
|
16575
16697
|
const timer = setTimeout(() => controller.abort(), fetchBudgetMs(includeTip));
|
|
@@ -16600,6 +16722,9 @@ async function fetchGlance(apiUrl, token, includeTip) {
|
|
|
16600
16722
|
}
|
|
16601
16723
|
const data = await response.json();
|
|
16602
16724
|
if (data.error) return { payload: null, tipMaybeSpent };
|
|
16725
|
+
if (refusedBeforeTool(data.result)) {
|
|
16726
|
+
return { payload: null, tipMaybeSpent: false };
|
|
16727
|
+
}
|
|
16603
16728
|
return {
|
|
16604
16729
|
payload: normalizeGlance(
|
|
16605
16730
|
parseMcpPayload(data.result?.content ?? data.result)
|
|
@@ -16820,7 +16945,7 @@ function shouldRequestTip(input) {
|
|
|
16820
16945
|
return now - state.lastTipAt >= TIP_THROTTLE_INTERVAL_MS;
|
|
16821
16946
|
}
|
|
16822
16947
|
function getGlanceStatePath() {
|
|
16823
|
-
return
|
|
16948
|
+
return join8(homedir6(), ".gad", "glance-state.json");
|
|
16824
16949
|
}
|
|
16825
16950
|
async function loadGlanceState() {
|
|
16826
16951
|
try {
|
|
@@ -19067,9 +19192,9 @@ node_default(Temp.purgeSyncAll);
|
|
|
19067
19192
|
var temp_default = Temp;
|
|
19068
19193
|
|
|
19069
19194
|
// node_modules/.pnpm/atomically@2.1.1/node_modules/atomically/dist/index.js
|
|
19070
|
-
function
|
|
19195
|
+
function writeFileSync4(filePath, data, options = DEFAULT_WRITE_OPTIONS) {
|
|
19071
19196
|
if (isString(options))
|
|
19072
|
-
return
|
|
19197
|
+
return writeFileSync4(filePath, data, { encoding: options });
|
|
19073
19198
|
const timeout2 = options.timeout ?? DEFAULT_TIMEOUT_SYNC;
|
|
19074
19199
|
const retryOptions = { timeout: timeout2 };
|
|
19075
19200
|
let tempDisposer = null;
|
|
@@ -19396,7 +19521,7 @@ var Configstore = class {
|
|
|
19396
19521
|
}
|
|
19397
19522
|
if (error.name === "SyntaxError") {
|
|
19398
19523
|
if (this._clearInvalidConfig) {
|
|
19399
|
-
|
|
19524
|
+
writeFileSync4(this._path, "", writeFileOptions);
|
|
19400
19525
|
return {};
|
|
19401
19526
|
}
|
|
19402
19527
|
throw error;
|
|
@@ -19408,7 +19533,7 @@ var Configstore = class {
|
|
|
19408
19533
|
set all(value) {
|
|
19409
19534
|
try {
|
|
19410
19535
|
import_graceful_fs.default.mkdirSync(path5.dirname(this._path), mkdirOptions);
|
|
19411
|
-
|
|
19536
|
+
writeFileSync4(this._path, JSON.stringify(value, void 0, " "), writeFileOptions);
|
|
19412
19537
|
} catch (error) {
|
|
19413
19538
|
handlePermissionError(error);
|
|
19414
19539
|
}
|
|
@@ -22115,6 +22240,7 @@ void captureCliEvent({
|
|
|
22115
22240
|
});
|
|
22116
22241
|
program2.addCommand(login_default);
|
|
22117
22242
|
program2.addCommand(logoutCommand);
|
|
22243
|
+
program2.addCommand(authCommand());
|
|
22118
22244
|
program2.addCommand(whoamiCommand());
|
|
22119
22245
|
program2.addCommand(memoryCommand);
|
|
22120
22246
|
program2.addCommand(workspace_default);
|