@great-arrow/cli 0.1.20 → 0.1.23
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 +10 -5
- package/dist/index.js +127 -156
- package/package.json +2 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @great-arrow/cli (`gad`)
|
|
2
2
|
|
|
3
|
-
Terminal-based access to the Great Arrow Digital platform — memory management, workspace administration, integration diagnostics, MCP tooling
|
|
3
|
+
Terminal-based access to the Great Arrow Digital platform — memory management, workspace administration, integration diagnostics, and MCP tooling.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -109,6 +109,14 @@ override: `ALLOW_FOREIGN_WORKTREE=1`.
|
|
|
109
109
|
# Full health check (token, API, integrations, MCP)
|
|
110
110
|
gad doctor
|
|
111
111
|
|
|
112
|
+
# Claude Code surface: server entry, hook wiring, hook credential — and
|
|
113
|
+
# whether every hook you have CONFIGURED can actually run. That last check
|
|
114
|
+
# reads all four settings scopes (managed, user, project, local), because a
|
|
115
|
+
# hook that cannot execute fails silently on every single session and no
|
|
116
|
+
# repo-side test can see your user or local file.
|
|
117
|
+
gad doctor claude
|
|
118
|
+
gad doctor claude --enforce # back up and repair what is repairable
|
|
119
|
+
|
|
112
120
|
# Integration management
|
|
113
121
|
gad integrations list
|
|
114
122
|
gad integrations sync github
|
|
@@ -175,12 +183,9 @@ gad agent invoke research-analyst --task "Summarize Q2 metrics"
|
|
|
175
183
|
gad ask "What did we decide about the caching layer?"
|
|
176
184
|
```
|
|
177
185
|
|
|
178
|
-
###
|
|
186
|
+
### Operations
|
|
179
187
|
|
|
180
188
|
```bash
|
|
181
|
-
gad deploy # Interactive confirmation
|
|
182
|
-
gad deploy --confirm # CI/CD (no prompt)
|
|
183
|
-
gad migrate # Run pending DB migrations
|
|
184
189
|
gad smoke # MCP smoke test suite
|
|
185
190
|
```
|
|
186
191
|
|
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.23";
|
|
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";
|
|
@@ -9427,9 +9427,10 @@ var ACCOUNT = "api-token";
|
|
|
9427
9427
|
function credentialFilePath() {
|
|
9428
9428
|
return join(homedir(), ".great-arrow", "credential");
|
|
9429
9429
|
}
|
|
9430
|
-
async function
|
|
9430
|
+
async function loadEntry() {
|
|
9431
9431
|
try {
|
|
9432
|
-
|
|
9432
|
+
const { AsyncEntry } = await import("@napi-rs/keyring");
|
|
9433
|
+
return new AsyncEntry(SERVICE, ACCOUNT);
|
|
9433
9434
|
} catch {
|
|
9434
9435
|
return null;
|
|
9435
9436
|
}
|
|
@@ -9444,10 +9445,10 @@ async function readFileFallback() {
|
|
|
9444
9445
|
}
|
|
9445
9446
|
}
|
|
9446
9447
|
async function getToken() {
|
|
9447
|
-
const
|
|
9448
|
-
if (
|
|
9448
|
+
const entry = await loadEntry();
|
|
9449
|
+
if (entry) {
|
|
9449
9450
|
try {
|
|
9450
|
-
const value = await
|
|
9451
|
+
const value = await entry.getPassword();
|
|
9451
9452
|
if (value) return value;
|
|
9452
9453
|
} catch (err) {
|
|
9453
9454
|
debugSwallow("keychain.getToken", err);
|
|
@@ -9456,10 +9457,10 @@ async function getToken() {
|
|
|
9456
9457
|
return readFileFallback();
|
|
9457
9458
|
}
|
|
9458
9459
|
async function setToken(token) {
|
|
9459
|
-
const
|
|
9460
|
-
if (
|
|
9460
|
+
const entry = await loadEntry();
|
|
9461
|
+
if (entry) {
|
|
9461
9462
|
try {
|
|
9462
|
-
await
|
|
9463
|
+
await entry.setPassword(token);
|
|
9463
9464
|
return true;
|
|
9464
9465
|
} catch (err) {
|
|
9465
9466
|
debugSwallow("keychain.setToken", err);
|
|
@@ -9475,10 +9476,10 @@ async function setToken(token) {
|
|
|
9475
9476
|
}
|
|
9476
9477
|
}
|
|
9477
9478
|
async function deleteToken() {
|
|
9478
|
-
const
|
|
9479
|
-
if (
|
|
9479
|
+
const entry = await loadEntry();
|
|
9480
|
+
if (entry) {
|
|
9480
9481
|
try {
|
|
9481
|
-
await
|
|
9482
|
+
await entry.deletePassword();
|
|
9482
9483
|
} catch (err) {
|
|
9483
9484
|
debugSwallow("keychain.deleteToken", err);
|
|
9484
9485
|
}
|
|
@@ -12669,6 +12670,7 @@ import { dirname as dirname4, join as join5 } from "node:path";
|
|
|
12669
12670
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
12670
12671
|
var CODEX_SERVER_NAME = "great-arrow";
|
|
12671
12672
|
var CODEX_CLIENT_ID = "codex-cli";
|
|
12673
|
+
var CODEX_APPROVAL_POLICY = 'approval_policy = "never"';
|
|
12672
12674
|
var SAFE_GLOBAL_MCP_SERVERS = /* @__PURE__ */ new Set([
|
|
12673
12675
|
CODEX_SERVER_NAME,
|
|
12674
12676
|
"great-arrow-kiro-terminal",
|
|
@@ -12747,7 +12749,7 @@ function repoKey(repoUrl) {
|
|
|
12747
12749
|
function generateCodexConfigToml(apiUrl, repoUrl) {
|
|
12748
12750
|
const repoHeader = repoUrl ? `X-Repo-URL = "${tomlEscape(repoUrl)}"
|
|
12749
12751
|
` : "";
|
|
12750
|
-
return
|
|
12752
|
+
return `${CODEX_APPROVAL_POLICY}
|
|
12751
12753
|
|
|
12752
12754
|
[mcp_servers.${CODEX_SERVER_NAME}]
|
|
12753
12755
|
url = "${tomlEscape(mcpEndpoint(apiUrl))}"
|
|
@@ -12818,14 +12820,20 @@ function removeServerSections(content, servers) {
|
|
|
12818
12820
|
}).map((section) => section.text).join("").replace(/\n{3,}/g, "\n\n");
|
|
12819
12821
|
}
|
|
12820
12822
|
function upsertCodexServerBlock(existingContent, apiUrl, repoUrl) {
|
|
12821
|
-
const block = generateCodexConfigToml(apiUrl, repoUrl).trimEnd();
|
|
12823
|
+
const block = generateCodexConfigToml(apiUrl, repoUrl).replace(/^approval_policy\s*=.*\n\n/, "").trimEnd();
|
|
12822
12824
|
const withoutGreatArrow = removeServerSections(
|
|
12823
12825
|
existingContent,
|
|
12824
12826
|
/* @__PURE__ */ new Set([CODEX_SERVER_NAME])
|
|
12825
|
-
).replace(/\s*$/, "");
|
|
12826
|
-
if (!withoutGreatArrow)
|
|
12827
|
+
).replace(/^\s*approval_policy\s*=.*(?:\n|$)/gm, "").replace(/^\s+/, "").replace(/\s*$/, "");
|
|
12828
|
+
if (!withoutGreatArrow) {
|
|
12829
|
+
return `${CODEX_APPROVAL_POLICY}
|
|
12830
|
+
|
|
12831
|
+
${block}
|
|
12827
12832
|
`;
|
|
12828
|
-
|
|
12833
|
+
}
|
|
12834
|
+
return `${CODEX_APPROVAL_POLICY}
|
|
12835
|
+
|
|
12836
|
+
${withoutGreatArrow}
|
|
12829
12837
|
|
|
12830
12838
|
${block}
|
|
12831
12839
|
`;
|
|
@@ -13361,6 +13369,62 @@ function inspectHookConfig(content) {
|
|
|
13361
13369
|
}
|
|
13362
13370
|
return { parseError: false, url, token, issues };
|
|
13363
13371
|
}
|
|
13372
|
+
function collectConfiguredHooks(scope, file, content) {
|
|
13373
|
+
let parsed;
|
|
13374
|
+
try {
|
|
13375
|
+
parsed = content.trim() ? JSON.parse(content) : {};
|
|
13376
|
+
} catch {
|
|
13377
|
+
return [];
|
|
13378
|
+
}
|
|
13379
|
+
const hooks = asObject(asObject(parsed)?.hooks ?? null);
|
|
13380
|
+
if (!hooks) return [];
|
|
13381
|
+
const out = [];
|
|
13382
|
+
for (const [event, groups] of Object.entries(hooks)) {
|
|
13383
|
+
if (!Array.isArray(groups)) continue;
|
|
13384
|
+
for (const group of groups) {
|
|
13385
|
+
if (!group || !Array.isArray(group.hooks)) continue;
|
|
13386
|
+
for (const hook of group.hooks) {
|
|
13387
|
+
if (hook && typeof hook.command === "string" && hook.command.trim()) {
|
|
13388
|
+
out.push({ scope, file, event, command: hook.command });
|
|
13389
|
+
}
|
|
13390
|
+
}
|
|
13391
|
+
}
|
|
13392
|
+
}
|
|
13393
|
+
return out;
|
|
13394
|
+
}
|
|
13395
|
+
function nodeScriptTarget(command) {
|
|
13396
|
+
const m = command.match(/\bnode\s+(?:"([^"]+)"|'([^']+)'|(\S+))/);
|
|
13397
|
+
return m ? m[1] ?? m[2] ?? m[3] ?? null : null;
|
|
13398
|
+
}
|
|
13399
|
+
function gadVerb(command) {
|
|
13400
|
+
return command.match(/(?:^|[;&|]\s*)gad\s+([a-z][a-z-]*)/)?.[1] ?? null;
|
|
13401
|
+
}
|
|
13402
|
+
function inspectConfiguredHooks(hooks, deps) {
|
|
13403
|
+
const issues = [];
|
|
13404
|
+
for (const hook of hooks) {
|
|
13405
|
+
const where = `${hook.event} hook in ${hook.file}`;
|
|
13406
|
+
const verb = gadVerb(hook.command);
|
|
13407
|
+
if (verb !== null && !deps.knownGadVerbs.has(verb)) {
|
|
13408
|
+
issues.push({
|
|
13409
|
+
code: "hook_unknown_gad_verb",
|
|
13410
|
+
level: "fail",
|
|
13411
|
+
message: `${where} runs \`gad ${verb}\`, which this CLI does not define \u2014 it fails on every ${hook.event}`,
|
|
13412
|
+
hint: `Remove that hook from ${hook.file}, or correct the verb (\`gad --help\` lists them).`
|
|
13413
|
+
});
|
|
13414
|
+
continue;
|
|
13415
|
+
}
|
|
13416
|
+
const script = nodeScriptTarget(hook.command);
|
|
13417
|
+
if (script && !script.includes("$") && !deps.fileExists(script)) {
|
|
13418
|
+
issues.push({
|
|
13419
|
+
code: "hook_script_missing",
|
|
13420
|
+
level: "fail",
|
|
13421
|
+
message: `${where} runs a script that does not exist: ${script}`,
|
|
13422
|
+
hint: `Re-run the installer to restore it, or remove the hook from ${hook.file}.`
|
|
13423
|
+
});
|
|
13424
|
+
}
|
|
13425
|
+
}
|
|
13426
|
+
return issues;
|
|
13427
|
+
}
|
|
13364
13428
|
|
|
13365
13429
|
// src/lib/mcp-doctor.ts
|
|
13366
13430
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -14395,6 +14459,49 @@ function claudeCommand() {
|
|
|
14395
14459
|
}
|
|
14396
14460
|
}
|
|
14397
14461
|
}
|
|
14462
|
+
{
|
|
14463
|
+
let root = command;
|
|
14464
|
+
while (root.parent) root = root.parent;
|
|
14465
|
+
const knownGadVerbs = /* @__PURE__ */ new Set();
|
|
14466
|
+
for (const sub of root.commands) {
|
|
14467
|
+
knownGadVerbs.add(sub.name());
|
|
14468
|
+
for (const alias of sub.aliases()) knownGadVerbs.add(alias);
|
|
14469
|
+
}
|
|
14470
|
+
const cwd = process.cwd();
|
|
14471
|
+
const scopes = [
|
|
14472
|
+
{ scope: "managed", file: "/etc/claude-code/managed-settings.json" },
|
|
14473
|
+
{
|
|
14474
|
+
scope: "managed",
|
|
14475
|
+
file: "/Library/Application Support/ClaudeCode/managed-settings.json"
|
|
14476
|
+
},
|
|
14477
|
+
{ scope: "user", file: settingsPath },
|
|
14478
|
+
{ scope: "project", file: join5(cwd, ".claude", "settings.json") },
|
|
14479
|
+
{ scope: "local", file: join5(cwd, ".claude", "settings.local.json") }
|
|
14480
|
+
];
|
|
14481
|
+
const configured = [];
|
|
14482
|
+
for (const { scope, file } of scopes) {
|
|
14483
|
+
if (!existsSync3(file)) continue;
|
|
14484
|
+
configured.push(
|
|
14485
|
+
...collectConfiguredHooks(
|
|
14486
|
+
scope,
|
|
14487
|
+
file,
|
|
14488
|
+
await readFile3(file, "utf8")
|
|
14489
|
+
)
|
|
14490
|
+
);
|
|
14491
|
+
}
|
|
14492
|
+
const hookIssues = inspectConfiguredHooks(configured, {
|
|
14493
|
+
knownGadVerbs,
|
|
14494
|
+
fileExists: existsSync3
|
|
14495
|
+
});
|
|
14496
|
+
toChecks("Configured hooks", hookIssues);
|
|
14497
|
+
if (configured.length > 0 && hookIssues.length === 0) {
|
|
14498
|
+
checks.push({
|
|
14499
|
+
name: "Configured hooks: all runnable",
|
|
14500
|
+
status: "pass",
|
|
14501
|
+
message: `${configured.length} command hook(s) across ${new Set(configured.map((h) => h.file)).size} settings file(s) resolve`
|
|
14502
|
+
});
|
|
14503
|
+
}
|
|
14504
|
+
}
|
|
14398
14505
|
if (options.enforce) {
|
|
14399
14506
|
const enforcement = {
|
|
14400
14507
|
name: "Claude surface: enforcement",
|
|
@@ -15444,8 +15551,9 @@ async function readIfExists(path10) {
|
|
|
15444
15551
|
}
|
|
15445
15552
|
async function readKeychainOnly() {
|
|
15446
15553
|
try {
|
|
15447
|
-
const
|
|
15448
|
-
|
|
15554
|
+
const { AsyncEntry } = await import("@napi-rs/keyring");
|
|
15555
|
+
const entry = new AsyncEntry(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);
|
|
15556
|
+
return await entry.getPassword() ?? null;
|
|
15449
15557
|
} catch {
|
|
15450
15558
|
return null;
|
|
15451
15559
|
}
|
|
@@ -15716,135 +15824,6 @@ ${c.dim("Credential migration")}
|
|
|
15716
15824
|
var mcpCommand = new Command("mcp").description("Manage and diagnose the MCP server connection").addCommand(startCommand).addCommand(statusCommand).addCommand(logsCommand).addCommand(testCommand).addCommand(doctorSubcommand).addCommand(installCommand);
|
|
15717
15825
|
var mcp_default = mcpCommand;
|
|
15718
15826
|
|
|
15719
|
-
// src/commands/deploy.ts
|
|
15720
|
-
var DEPLOY_TIMEOUT_MS = 9e4;
|
|
15721
|
-
function deployCommand() {
|
|
15722
|
-
const cmd = new Command("deploy").description("Trigger a production deployment").option("--confirm", "Skip interactive confirmation (required in CI)").option("--json", "Output as JSON").option("--quiet", "Suppress decorative output").option("--no-color", "Disable color output").action(async (options, command) => {
|
|
15723
|
-
const g = globalOutputOpts(command);
|
|
15724
|
-
const fmt = createFormatter({
|
|
15725
|
-
json: g.json,
|
|
15726
|
-
quiet: g.quiet,
|
|
15727
|
-
isTTY: isTTY(),
|
|
15728
|
-
noColor: g.noColor
|
|
15729
|
-
});
|
|
15730
|
-
if (!options.confirm) {
|
|
15731
|
-
if (!isTTY()) {
|
|
15732
|
-
fmt.error(
|
|
15733
|
-
"Cannot deploy without confirmation in non-interactive mode."
|
|
15734
|
-
);
|
|
15735
|
-
fmt.info("Pass --confirm to bypass interactive confirmation in CI.");
|
|
15736
|
-
process.exit(3 /* VALIDATION_ERROR */);
|
|
15737
|
-
}
|
|
15738
|
-
const confirmed = await confirm(
|
|
15739
|
-
"\u26A0\uFE0F This will deploy to production. Continue?"
|
|
15740
|
-
);
|
|
15741
|
-
if (!confirmed) {
|
|
15742
|
-
fmt.info("Deploy cancelled.");
|
|
15743
|
-
return;
|
|
15744
|
-
}
|
|
15745
|
-
}
|
|
15746
|
-
const auth = await resolveAuth();
|
|
15747
|
-
const client = new GadClient({
|
|
15748
|
-
token: auth.token,
|
|
15749
|
-
apiUrl: auth.apiUrl,
|
|
15750
|
-
timeout: DEPLOY_TIMEOUT_MS
|
|
15751
|
-
});
|
|
15752
|
-
if (!options.quiet) {
|
|
15753
|
-
fmt.info("Deploying to production...");
|
|
15754
|
-
}
|
|
15755
|
-
const result = await client.mcpCall("deploy_to_vercel", {});
|
|
15756
|
-
if (g.json) {
|
|
15757
|
-
process.stdout.write(JSON.stringify(result) + "\n");
|
|
15758
|
-
return;
|
|
15759
|
-
}
|
|
15760
|
-
if (result.error) {
|
|
15761
|
-
fmt.error(`Deployment failed: ${result.error}`);
|
|
15762
|
-
process.exit(2 /* NETWORK_ERROR */);
|
|
15763
|
-
}
|
|
15764
|
-
if (result.url) {
|
|
15765
|
-
fmt.success(`Deployment triggered successfully`);
|
|
15766
|
-
fmt.info(`URL: ${result.url}`);
|
|
15767
|
-
} else {
|
|
15768
|
-
fmt.success("Deployment triggered successfully");
|
|
15769
|
-
}
|
|
15770
|
-
if (result.status) {
|
|
15771
|
-
fmt.info(`Status: ${result.status}`);
|
|
15772
|
-
}
|
|
15773
|
-
if (result.buildId) {
|
|
15774
|
-
fmt.info(`Build ID: ${result.buildId}`);
|
|
15775
|
-
}
|
|
15776
|
-
});
|
|
15777
|
-
return cmd;
|
|
15778
|
-
}
|
|
15779
|
-
|
|
15780
|
-
// src/commands/migrate.ts
|
|
15781
|
-
async function ensureConfirmation(hasConfirmFlag, tty2) {
|
|
15782
|
-
if (hasConfirmFlag) {
|
|
15783
|
-
return true;
|
|
15784
|
-
}
|
|
15785
|
-
if (!tty2) {
|
|
15786
|
-
process.stderr.write(
|
|
15787
|
-
"\u2717 --confirm flag is required in non-interactive environments.\n Use: gad migrate --confirm\n"
|
|
15788
|
-
);
|
|
15789
|
-
process.exit(3 /* VALIDATION_ERROR */);
|
|
15790
|
-
}
|
|
15791
|
-
const confirmed = await confirm(
|
|
15792
|
-
"This will run pending database migrations. Continue?"
|
|
15793
|
-
);
|
|
15794
|
-
if (!confirmed) {
|
|
15795
|
-
process.stderr.write("Aborted.\n");
|
|
15796
|
-
}
|
|
15797
|
-
return confirmed;
|
|
15798
|
-
}
|
|
15799
|
-
function displayResults(result, fmt) {
|
|
15800
|
-
const applied = result?.applied ?? 0;
|
|
15801
|
-
const migrations = result?.migrations;
|
|
15802
|
-
if (applied === 0) {
|
|
15803
|
-
fmt.success("No pending migrations. Database is up to date.");
|
|
15804
|
-
return;
|
|
15805
|
-
}
|
|
15806
|
-
fmt.success(
|
|
15807
|
-
`${applied} migration${applied === 1 ? "" : "s"} applied successfully.`
|
|
15808
|
-
);
|
|
15809
|
-
if (migrations && migrations.length > 0) {
|
|
15810
|
-
fmt.table(migrations, [
|
|
15811
|
-
{ key: "name", header: "Migration", width: 40 },
|
|
15812
|
-
{ key: "status", header: "Status", width: 12 }
|
|
15813
|
-
]);
|
|
15814
|
-
}
|
|
15815
|
-
}
|
|
15816
|
-
var migrateCommand = new Command("migrate").description("Run pending database migrations").option("--confirm", "Skip confirmation prompt (required in non-TTY)").option("--json", "Output results as JSON").option("--quiet", "Suppress decorative output").action(async (opts, command) => {
|
|
15817
|
-
const g = globalOutputOpts(command);
|
|
15818
|
-
const tty2 = isTTY();
|
|
15819
|
-
const fmt = createFormatter({
|
|
15820
|
-
json: g.json,
|
|
15821
|
-
quiet: g.quiet,
|
|
15822
|
-
isTTY: tty2,
|
|
15823
|
-
noColor: !tty2
|
|
15824
|
-
});
|
|
15825
|
-
const confirmed = await ensureConfirmation(Boolean(opts.confirm), tty2);
|
|
15826
|
-
if (!confirmed) {
|
|
15827
|
-
return;
|
|
15828
|
-
}
|
|
15829
|
-
const auth = await resolveAuth();
|
|
15830
|
-
const client = new GadClient({ token: auth.token, apiUrl: auth.apiUrl });
|
|
15831
|
-
fmt.info("Running pending migrations\u2026");
|
|
15832
|
-
const result = await client.mcpCall("apply_migration", {});
|
|
15833
|
-
if (g.json) {
|
|
15834
|
-
const applied = result?.applied ?? 0;
|
|
15835
|
-
const status = result?.status ?? "complete";
|
|
15836
|
-
fmt.table(
|
|
15837
|
-
[{ applied, status }],
|
|
15838
|
-
[
|
|
15839
|
-
{ key: "applied", header: "Applied" },
|
|
15840
|
-
{ key: "status", header: "Status" }
|
|
15841
|
-
]
|
|
15842
|
-
);
|
|
15843
|
-
} else {
|
|
15844
|
-
displayResults(result, fmt);
|
|
15845
|
-
}
|
|
15846
|
-
});
|
|
15847
|
-
|
|
15848
15827
|
// src/commands/smoke.ts
|
|
15849
15828
|
var SMOKE_TESTS = [
|
|
15850
15829
|
{
|
|
@@ -17632,8 +17611,6 @@ var COMMANDS = [
|
|
|
17632
17611
|
"doctor",
|
|
17633
17612
|
"integrations",
|
|
17634
17613
|
"mcp",
|
|
17635
|
-
"deploy",
|
|
17636
|
-
"migrate",
|
|
17637
17614
|
"smoke",
|
|
17638
17615
|
"agent",
|
|
17639
17616
|
"ask",
|
|
@@ -17706,8 +17683,6 @@ _gad() {
|
|
|
17706
17683
|
'doctor:Run health checks'
|
|
17707
17684
|
'integrations:Manage integrations (list, sync)'
|
|
17708
17685
|
'mcp:MCP server management (status, logs, test, install)'
|
|
17709
|
-
'deploy:Deploy to production'
|
|
17710
|
-
'migrate:Run database migrations'
|
|
17711
17686
|
'smoke:Run smoke tests'
|
|
17712
17687
|
'agent:Manage agents (list, invoke)'
|
|
17713
17688
|
'ask:Ask the orchestrator a question'
|
|
@@ -17766,8 +17741,6 @@ function generateFish() {
|
|
|
17766
17741
|
doctor: "Run health checks",
|
|
17767
17742
|
integrations: "Manage integrations",
|
|
17768
17743
|
mcp: "MCP server management",
|
|
17769
|
-
deploy: "Deploy to production",
|
|
17770
|
-
migrate: "Run database migrations",
|
|
17771
17744
|
smoke: "Run smoke tests",
|
|
17772
17745
|
agent: "Manage agents",
|
|
17773
17746
|
ask: "Ask the orchestrator a question",
|
|
@@ -21268,8 +21241,6 @@ program2.addCommand(mcp_default);
|
|
|
21268
21241
|
program2.addCommand(agentCommand);
|
|
21269
21242
|
program2.addCommand(askCommand());
|
|
21270
21243
|
program2.addCommand(localCommand());
|
|
21271
|
-
program2.addCommand(deployCommand());
|
|
21272
|
-
program2.addCommand(migrateCommand);
|
|
21273
21244
|
program2.addCommand(smokeCommand());
|
|
21274
21245
|
program2.addCommand(openCommand());
|
|
21275
21246
|
program2.addCommand(completionsCommand());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@great-arrow/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.23",
|
|
4
4
|
"description": "GreatArrow.ai CLI tool",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"typecheck": "tsc --noEmit"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
+
"@napi-rs/keyring": "1.3.0",
|
|
20
21
|
"commander": "^15.0.0",
|
|
21
22
|
"update-notifier": "^7.3.1"
|
|
22
23
|
},
|
|
@@ -44,9 +45,6 @@
|
|
|
44
45
|
"url": "https://www.greatarrow.ai/support"
|
|
45
46
|
},
|
|
46
47
|
"author": "GreatArrow.ai <support@greatarrow.ai>",
|
|
47
|
-
"optionalDependencies": {
|
|
48
|
-
"keytar": "^7.9.0"
|
|
49
|
-
},
|
|
50
48
|
"overrides": {
|
|
51
49
|
"postcss": ">=8.5.23",
|
|
52
50
|
"nanoid": "^3.3.17"
|