@great-arrow/cli 0.6.5 → 0.7.1
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 +6 -0
- package/dist/index.js +320 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -80,6 +80,12 @@ gad memory delete <id>
|
|
|
80
80
|
cat notes.md | gad memory create --title "Meeting notes"
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
+
`gad memory search` shows a **Source** column for every hit: the original
|
|
84
|
+
document's link (GitHub, Notion, Drive…) when there is one, otherwise the
|
|
85
|
+
memory's page in the web app. `gad ask` prints a numbered **Sources** list of
|
|
86
|
+
the memories its answer was built from, under the answer (`--quiet` hides it;
|
|
87
|
+
`--json` keeps the raw `hits`).
|
|
88
|
+
|
|
83
89
|
### Workspace
|
|
84
90
|
|
|
85
91
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -9483,7 +9483,7 @@ function isNodeError(value) {
|
|
|
9483
9483
|
|
|
9484
9484
|
// src/lib/version.ts
|
|
9485
9485
|
var CLI_PACKAGE_NAME = "@great-arrow/cli";
|
|
9486
|
-
var CLI_VERSION = "0.
|
|
9486
|
+
var CLI_VERSION = "0.7.1";
|
|
9487
9487
|
var GAD_INSTALL_VERSION = "2026.08.08";
|
|
9488
9488
|
var GAD_INSTALL_MIN_VERSION = "2026.06.22";
|
|
9489
9489
|
var GAD_INSTALL_HEADER = "X-GAD-Install-Version";
|
|
@@ -10965,11 +10965,11 @@ var EXIT_SESSION_EXPIRED = 2;
|
|
|
10965
10965
|
var EXIT_NOT_OAUTH = 3;
|
|
10966
10966
|
function authCommand() {
|
|
10967
10967
|
const cmd = new Command("auth").description("Authentication helpers");
|
|
10968
|
-
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,
|
|
10968
|
+
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, actionCommand2) => {
|
|
10969
10969
|
try {
|
|
10970
10970
|
const t = await getFreshOAuthAccessToken();
|
|
10971
10971
|
writeCliLocator();
|
|
10972
|
-
const jsonOutput = options.json ||
|
|
10972
|
+
const jsonOutput = options.json || actionCommand2.optsWithGlobals().json;
|
|
10973
10973
|
process.stdout.write(
|
|
10974
10974
|
jsonOutput ? `${JSON.stringify(t)}
|
|
10975
10975
|
` : `${t.accessToken}
|
|
@@ -12198,11 +12198,56 @@ function readStdin(stream) {
|
|
|
12198
12198
|
return readStream(input2);
|
|
12199
12199
|
}
|
|
12200
12200
|
|
|
12201
|
+
// src/lib/sources.ts
|
|
12202
|
+
function nonEmpty2(value) {
|
|
12203
|
+
if (typeof value !== "string") return null;
|
|
12204
|
+
const clean = stripControlChars(value).trim();
|
|
12205
|
+
return clean === "" ? null : clean;
|
|
12206
|
+
}
|
|
12207
|
+
function httpUrl(value) {
|
|
12208
|
+
const raw = nonEmpty2(value);
|
|
12209
|
+
if (!raw) return null;
|
|
12210
|
+
try {
|
|
12211
|
+
const parsed = new URL(raw);
|
|
12212
|
+
return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed.toString() : null;
|
|
12213
|
+
} catch {
|
|
12214
|
+
return null;
|
|
12215
|
+
}
|
|
12216
|
+
}
|
|
12217
|
+
function sourceOf(hit, apiUrl) {
|
|
12218
|
+
const memoryId = nonEmpty2(hit.memoryId);
|
|
12219
|
+
const link = httpUrl(hit.url) ?? (memoryId ? `${apiUrl.replace(/\/$/, "")}/stuff/memories/${encodeURIComponent(memoryId)}` : null);
|
|
12220
|
+
const label = nonEmpty2(hit.fileName) ?? nonEmpty2(hit.memoryTitle) ?? nonEmpty2(hit.title) ?? memoryId ?? "Untitled";
|
|
12221
|
+
return { label, link };
|
|
12222
|
+
}
|
|
12223
|
+
function uniqueSources(hits, apiUrl, max = 5) {
|
|
12224
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12225
|
+
const out2 = [];
|
|
12226
|
+
for (const hit of hits) {
|
|
12227
|
+
const source = sourceOf(hit, apiUrl);
|
|
12228
|
+
const key = source.link ?? source.label;
|
|
12229
|
+
if (seen.has(key)) continue;
|
|
12230
|
+
seen.add(key);
|
|
12231
|
+
out2.push(source);
|
|
12232
|
+
if (out2.length >= max) break;
|
|
12233
|
+
}
|
|
12234
|
+
return out2;
|
|
12235
|
+
}
|
|
12236
|
+
function formatSources(sources) {
|
|
12237
|
+
if (sources.length === 0) return "";
|
|
12238
|
+
const lines = sources.map(
|
|
12239
|
+
(s2, i) => ` [${i + 1}] ${s2.label}${s2.link ? ` \u2014 ${s2.link}` : ""}`
|
|
12240
|
+
);
|
|
12241
|
+
return `Sources:
|
|
12242
|
+
${lines.join("\n")}`;
|
|
12243
|
+
}
|
|
12244
|
+
|
|
12201
12245
|
// src/commands/memory.ts
|
|
12202
12246
|
var searchColumns = [
|
|
12203
12247
|
{ key: "title", header: "Title", width: 30 },
|
|
12204
12248
|
{ key: "layer", header: "Layer", width: 12 },
|
|
12205
12249
|
{ key: "freshness", header: "Freshness", width: 10 },
|
|
12250
|
+
{ key: "source", header: "Source" },
|
|
12206
12251
|
{
|
|
12207
12252
|
key: "preview",
|
|
12208
12253
|
header: "Preview",
|
|
@@ -12298,7 +12343,12 @@ memoryCommand.command("create").description("Create a new memory in the active w
|
|
|
12298
12343
|
});
|
|
12299
12344
|
memoryCommand.command("search <query>").description("Semantic search across memories").option("--json", "Output as JSON").option("-k, --limit <number>", "Max results", "10").option("--layer <layer>", "Filter by layer").action(async (query, opts, command) => {
|
|
12300
12345
|
const g = globalOutputOpts(command);
|
|
12301
|
-
const
|
|
12346
|
+
const auth = await resolveAuth();
|
|
12347
|
+
const client2 = new GadClient({
|
|
12348
|
+
token: auth.token,
|
|
12349
|
+
getToken: auth.getToken,
|
|
12350
|
+
apiUrl: auth.apiUrl
|
|
12351
|
+
});
|
|
12302
12352
|
const args = {
|
|
12303
12353
|
query,
|
|
12304
12354
|
k: Number.parseInt(opts.limit, 10)
|
|
@@ -12312,6 +12362,7 @@ memoryCommand.command("search <query>").description("Semantic search across memo
|
|
|
12312
12362
|
const rows = rawResults.map((item) => ({
|
|
12313
12363
|
...item,
|
|
12314
12364
|
title: item.title ?? item.memoryTitle,
|
|
12365
|
+
source: sourceOf(item, auth.apiUrl).link ?? "",
|
|
12315
12366
|
preview: extractPreview(item)
|
|
12316
12367
|
}));
|
|
12317
12368
|
const fmt = createFormatter({
|
|
@@ -18293,6 +18344,17 @@ function askOutcome(data) {
|
|
|
18293
18344
|
const answer = extractAnswer(data);
|
|
18294
18345
|
return answer.trim() === "" ? { kind: "empty" } : { kind: "ok", text: answer };
|
|
18295
18346
|
}
|
|
18347
|
+
function askSources(data, apiUrl) {
|
|
18348
|
+
if (!data || typeof data !== "object") return "";
|
|
18349
|
+
const hits = data.hits;
|
|
18350
|
+
if (!Array.isArray(hits)) return "";
|
|
18351
|
+
return formatSources(
|
|
18352
|
+
uniqueSources(
|
|
18353
|
+
hits.filter((h) => typeof h === "object" && h !== null),
|
|
18354
|
+
apiUrl
|
|
18355
|
+
)
|
|
18356
|
+
);
|
|
18357
|
+
}
|
|
18296
18358
|
function askCommand() {
|
|
18297
18359
|
const cmd = new Command("ask").description("Ask the orchestrator a question").argument("<question>", "The question to ask").option("--json", "Output raw response as JSON").option("--quiet", "Suppress decorative output").option("--no-color", "Disable color output").action(async (question, options, command) => {
|
|
18298
18360
|
const g = globalOutputOpts(command);
|
|
@@ -18329,6 +18391,10 @@ function askCommand() {
|
|
|
18329
18391
|
const outcome = askOutcome(result);
|
|
18330
18392
|
if (outcome.kind === "ok") {
|
|
18331
18393
|
process.stdout.write(outcome.text + "\n");
|
|
18394
|
+
const sources = g.quiet ? "" : askSources(result, auth.apiUrl);
|
|
18395
|
+
if (sources) process.stdout.write(`
|
|
18396
|
+
${sources}
|
|
18397
|
+
`);
|
|
18332
18398
|
} else if (outcome.kind === "error") {
|
|
18333
18399
|
fmt.warn(`Orchestrator error: ${outcome.message}`);
|
|
18334
18400
|
process.exitCode = 1;
|
|
@@ -20107,7 +20173,7 @@ __export(external_exports, {
|
|
|
20107
20173
|
hash: () => hash,
|
|
20108
20174
|
hex: () => hex2,
|
|
20109
20175
|
hostname: () => hostname4,
|
|
20110
|
-
httpUrl: () =>
|
|
20176
|
+
httpUrl: () => httpUrl2,
|
|
20111
20177
|
iban: () => iban2,
|
|
20112
20178
|
includes: () => _includes,
|
|
20113
20179
|
input: () => input,
|
|
@@ -37046,7 +37112,7 @@ __export(schemas_exports2, {
|
|
|
37046
37112
|
hash: () => hash,
|
|
37047
37113
|
hex: () => hex2,
|
|
37048
37114
|
hostname: () => hostname4,
|
|
37049
|
-
httpUrl: () =>
|
|
37115
|
+
httpUrl: () => httpUrl2,
|
|
37050
37116
|
iban: () => iban2,
|
|
37051
37117
|
instanceof: () => _instanceof,
|
|
37052
37118
|
int: () => int,
|
|
@@ -37594,7 +37660,7 @@ var ZodURL = /* @__PURE__ */ $constructor("ZodURL", (inst, def) => {
|
|
|
37594
37660
|
function url(params) {
|
|
37595
37661
|
return _url(ZodURL, params);
|
|
37596
37662
|
}
|
|
37597
|
-
function
|
|
37663
|
+
function httpUrl2(params) {
|
|
37598
37664
|
return _url(ZodURL, {
|
|
37599
37665
|
protocol: httpProtocol,
|
|
37600
37666
|
hostname: domain,
|
|
@@ -40894,9 +40960,9 @@ var ZodString2 = class _ZodString2 extends ZodType2 {
|
|
|
40894
40960
|
}
|
|
40895
40961
|
return { status: status.value, value: input2.data };
|
|
40896
40962
|
}
|
|
40897
|
-
_regex(regex2,
|
|
40963
|
+
_regex(regex2, validation2, message) {
|
|
40898
40964
|
return this.refinement((data) => regex2.test(data), {
|
|
40899
|
-
validation,
|
|
40965
|
+
validation: validation2,
|
|
40900
40966
|
code: ZodIssueCode2.invalid_string,
|
|
40901
40967
|
...errorUtil.errToObj(message)
|
|
40902
40968
|
});
|
|
@@ -50236,6 +50302,248 @@ function callCommand() {
|
|
|
50236
50302
|
});
|
|
50237
50303
|
}
|
|
50238
50304
|
|
|
50305
|
+
// src/commands/board.ts
|
|
50306
|
+
var TOOL = "board_autopilot";
|
|
50307
|
+
function asObject4(json3) {
|
|
50308
|
+
if (!json3.startsWith("{")) return null;
|
|
50309
|
+
try {
|
|
50310
|
+
const data = JSON.parse(json3);
|
|
50311
|
+
return data && typeof data === "object" && !Array.isArray(data) ? data : null;
|
|
50312
|
+
} catch (error62) {
|
|
50313
|
+
void error62;
|
|
50314
|
+
return null;
|
|
50315
|
+
}
|
|
50316
|
+
}
|
|
50317
|
+
function parseToolResult(result) {
|
|
50318
|
+
if (result && typeof result === "object" && !Array.isArray(result)) {
|
|
50319
|
+
return { text: "", data: result };
|
|
50320
|
+
}
|
|
50321
|
+
if (typeof result !== "string") return { text: "", data: null };
|
|
50322
|
+
const cut = result.lastIndexOf("\n");
|
|
50323
|
+
const tail = result.slice(cut + 1).trim();
|
|
50324
|
+
const candidates = [
|
|
50325
|
+
[result.slice(0, Math.max(cut, 0)), tail],
|
|
50326
|
+
["", result.trim()]
|
|
50327
|
+
];
|
|
50328
|
+
for (const [text3, json3] of candidates) {
|
|
50329
|
+
const data = asObject4(json3);
|
|
50330
|
+
if (data) return { text: text3, data };
|
|
50331
|
+
}
|
|
50332
|
+
return { text: result, data: null };
|
|
50333
|
+
}
|
|
50334
|
+
function validation(message, hint) {
|
|
50335
|
+
return new CliError(message, 3 /* VALIDATION_ERROR */, hint);
|
|
50336
|
+
}
|
|
50337
|
+
function hostedP90(plan) {
|
|
50338
|
+
const q = plan?.quotes?.find((x) => x.executor === "hosted");
|
|
50339
|
+
return typeof q?.p90Usd === "number" ? q.p90Usd : null;
|
|
50340
|
+
}
|
|
50341
|
+
function buildStartArgs(runId, plan, opts) {
|
|
50342
|
+
if (!opts.healthUrl)
|
|
50343
|
+
throw validation(
|
|
50344
|
+
"--yes needs --health-url <url>.",
|
|
50345
|
+
"The run watches this URL after every merge and rolls back when it fails."
|
|
50346
|
+
);
|
|
50347
|
+
if (!opts.versionUrl)
|
|
50348
|
+
throw validation(
|
|
50349
|
+
"--yes needs --version-url <url>.",
|
|
50350
|
+
"The run reads the serving version here to know a merge reached production."
|
|
50351
|
+
);
|
|
50352
|
+
let cap;
|
|
50353
|
+
if (opts.cap !== void 0) {
|
|
50354
|
+
cap = Number(opts.cap);
|
|
50355
|
+
if (!Number.isFinite(cap) || cap <= 0)
|
|
50356
|
+
throw validation("--cap must be a positive dollar amount.");
|
|
50357
|
+
} else {
|
|
50358
|
+
cap = hostedP90(plan);
|
|
50359
|
+
}
|
|
50360
|
+
if (cap === null)
|
|
50361
|
+
throw validation(
|
|
50362
|
+
"The plan carried no hosted quote to default the cap from.",
|
|
50363
|
+
"Pass --cap <usd>."
|
|
50364
|
+
);
|
|
50365
|
+
if (cap <= 0)
|
|
50366
|
+
throw validation(
|
|
50367
|
+
"The hosted quote is $0, so there is no cap to default to.",
|
|
50368
|
+
"Pass --cap <usd>."
|
|
50369
|
+
);
|
|
50370
|
+
const rejected = new Set(opts.reject ?? []);
|
|
50371
|
+
if (plan?.findings) {
|
|
50372
|
+
const known = new Set(plan.findings.map((f) => f.id));
|
|
50373
|
+
const unknown2 = [...rejected].filter((id) => !known.has(id));
|
|
50374
|
+
if (unknown2.length > 0)
|
|
50375
|
+
throw validation(
|
|
50376
|
+
`--reject: unknown finding id(s): ${unknown2.join(", ")}.`,
|
|
50377
|
+
"Run without --yes to list finding ids."
|
|
50378
|
+
);
|
|
50379
|
+
}
|
|
50380
|
+
const args = {
|
|
50381
|
+
action: "start",
|
|
50382
|
+
run_id: runId,
|
|
50383
|
+
accepted_finding_ids: (plan?.findings ?? []).map((f) => f.id).filter((id) => !rejected.has(id)),
|
|
50384
|
+
cap_usd: cap,
|
|
50385
|
+
notify: { email: opts.email !== false, push: opts.push !== false },
|
|
50386
|
+
health_check_url: opts.healthUrl,
|
|
50387
|
+
version_url: opts.versionUrl
|
|
50388
|
+
};
|
|
50389
|
+
if (opts.types)
|
|
50390
|
+
args.card_types = opts.types.split(",").map((t) => t.trim()).filter(Boolean);
|
|
50391
|
+
return args;
|
|
50392
|
+
}
|
|
50393
|
+
async function callBoard(client2, args) {
|
|
50394
|
+
let result;
|
|
50395
|
+
try {
|
|
50396
|
+
result = await client2.mcpCall("gad_call", gadCallArgs(TOOL, args));
|
|
50397
|
+
} catch (error62) {
|
|
50398
|
+
if (!(error62 instanceof McpToolError)) throw error62;
|
|
50399
|
+
throw validation(`${TOOL}: ${error62.message}`, error62.hint);
|
|
50400
|
+
}
|
|
50401
|
+
const failure2 = callFailure(result);
|
|
50402
|
+
if (failure2) {
|
|
50403
|
+
throw new CliError(
|
|
50404
|
+
`${TOOL}: ${failure2.message}`,
|
|
50405
|
+
failure2.code === "feature_disabled" || failure2.code === "insufficient_scope" ? 1 /* AUTH_ERROR */ : 3 /* VALIDATION_ERROR */
|
|
50406
|
+
);
|
|
50407
|
+
}
|
|
50408
|
+
return result;
|
|
50409
|
+
}
|
|
50410
|
+
function printPlan(fmt, plan) {
|
|
50411
|
+
const row = (r) => r;
|
|
50412
|
+
const f = plan.findings ?? [];
|
|
50413
|
+
const c = plan.cards ?? [];
|
|
50414
|
+
const q = plan.quotes ?? [];
|
|
50415
|
+
process.stdout.write(`
|
|
50416
|
+
Board cleanups (${f.length})
|
|
50417
|
+
`);
|
|
50418
|
+
fmt.table(f.map(row), [
|
|
50419
|
+
{ key: "id", header: "Finding" },
|
|
50420
|
+
{ key: "kind", header: "Kind" },
|
|
50421
|
+
{ key: "todoId", header: "Card" }
|
|
50422
|
+
]);
|
|
50423
|
+
process.stdout.write(`
|
|
50424
|
+
Cards (${c.length})
|
|
50425
|
+
`);
|
|
50426
|
+
fmt.table(
|
|
50427
|
+
c.map((x) => row({ ...x, completable: x.completable ? "yes" : "no" })),
|
|
50428
|
+
[
|
|
50429
|
+
{ key: "title", header: "Title" },
|
|
50430
|
+
{ key: "type", header: "Type" },
|
|
50431
|
+
{ key: "completable", header: "Runs alone" },
|
|
50432
|
+
{ key: "reason", header: "Why" }
|
|
50433
|
+
]
|
|
50434
|
+
);
|
|
50435
|
+
process.stdout.write("\nQuotes (USD)\n");
|
|
50436
|
+
fmt.table(
|
|
50437
|
+
q.map(
|
|
50438
|
+
(x) => row({
|
|
50439
|
+
...x,
|
|
50440
|
+
status: x.available ? "available" : x.comingSoon ? "soon" : "n/a"
|
|
50441
|
+
})
|
|
50442
|
+
),
|
|
50443
|
+
[
|
|
50444
|
+
{ key: "label", header: "Executor" },
|
|
50445
|
+
{ key: "status", header: "Status" },
|
|
50446
|
+
{ key: "p50Usd", header: "p50" },
|
|
50447
|
+
{ key: "p90Usd", header: "p90" }
|
|
50448
|
+
]
|
|
50449
|
+
);
|
|
50450
|
+
}
|
|
50451
|
+
function makeFormatter(command) {
|
|
50452
|
+
const g = globalOutputOpts(command);
|
|
50453
|
+
return {
|
|
50454
|
+
g,
|
|
50455
|
+
fmt: createFormatter({
|
|
50456
|
+
json: g.json,
|
|
50457
|
+
quiet: g.quiet,
|
|
50458
|
+
isTTY: isTTY(),
|
|
50459
|
+
noColor: g.noColor
|
|
50460
|
+
})
|
|
50461
|
+
};
|
|
50462
|
+
}
|
|
50463
|
+
async function makeClient() {
|
|
50464
|
+
const auth = await resolveAuth();
|
|
50465
|
+
return new GadClient({
|
|
50466
|
+
token: auth.token,
|
|
50467
|
+
getToken: auth.getToken,
|
|
50468
|
+
apiUrl: auth.apiUrl
|
|
50469
|
+
});
|
|
50470
|
+
}
|
|
50471
|
+
function emit(result, json3, quiet = false) {
|
|
50472
|
+
const { text: text3, data } = parseToolResult(result);
|
|
50473
|
+
if (json3) {
|
|
50474
|
+
process.stdout.write(
|
|
50475
|
+
`${typeof result === "string" ? result : JSON.stringify(result)}
|
|
50476
|
+
`
|
|
50477
|
+
);
|
|
50478
|
+
} else if (text3 && !quiet) {
|
|
50479
|
+
process.stdout.write(`${text3}
|
|
50480
|
+
`);
|
|
50481
|
+
}
|
|
50482
|
+
return data;
|
|
50483
|
+
}
|
|
50484
|
+
async function runClear(opts, command) {
|
|
50485
|
+
if (opts.yes)
|
|
50486
|
+
buildStartArgs(
|
|
50487
|
+
"pending",
|
|
50488
|
+
{ quotes: [{ executor: "hosted", p90Usd: 1 }] },
|
|
50489
|
+
opts
|
|
50490
|
+
);
|
|
50491
|
+
const { g, fmt } = makeFormatter(command);
|
|
50492
|
+
const client2 = await makeClient();
|
|
50493
|
+
const planResult = await callBoard(client2, {
|
|
50494
|
+
action: "plan",
|
|
50495
|
+
...opts.goal ? { goal_id: opts.goal } : {}
|
|
50496
|
+
});
|
|
50497
|
+
const data = emit(planResult, g.json && !opts.yes, g.quiet);
|
|
50498
|
+
const run4 = data?.run ?? null;
|
|
50499
|
+
if (!g.json && !g.quiet && run4?.plan) printPlan(fmt, run4.plan);
|
|
50500
|
+
if (!opts.yes) {
|
|
50501
|
+
if (!g.json && !g.quiet && run4?.id)
|
|
50502
|
+
process.stdout.write(
|
|
50503
|
+
`
|
|
50504
|
+
Nothing has changed. Start with: gad board clear${opts.goal ? ` --goal ${opts.goal}` : ""} --yes --health-url <url> --version-url <url>
|
|
50505
|
+
`
|
|
50506
|
+
);
|
|
50507
|
+
return;
|
|
50508
|
+
}
|
|
50509
|
+
if (!run4?.id) throw validation("The plan reply carried no run id.");
|
|
50510
|
+
const startResult = await callBoard(
|
|
50511
|
+
client2,
|
|
50512
|
+
buildStartArgs(run4.id, run4.plan, opts)
|
|
50513
|
+
);
|
|
50514
|
+
emit(startResult, g.json, g.quiet);
|
|
50515
|
+
}
|
|
50516
|
+
function actionCommand(action) {
|
|
50517
|
+
return new Command(action).description(`${action} a clear-the-board run`).option("--run <id>", "Run id (status defaults to the latest run)").option("--card <id>", "Undo only this card (undo)").action(async (opts, command) => {
|
|
50518
|
+
if (action !== "status" && !opts.run)
|
|
50519
|
+
throw validation(`${action} needs --run <id>.`);
|
|
50520
|
+
if (opts.card && action !== "undo")
|
|
50521
|
+
throw validation("--card only applies to undo.");
|
|
50522
|
+
const { g } = makeFormatter(command);
|
|
50523
|
+
const client2 = await makeClient();
|
|
50524
|
+
const result = await callBoard(client2, {
|
|
50525
|
+
action,
|
|
50526
|
+
...opts.run ? { run_id: opts.run } : {},
|
|
50527
|
+
...opts.card ? { card_id: opts.card } : {}
|
|
50528
|
+
});
|
|
50529
|
+
emit(result, g.json, g.quiet);
|
|
50530
|
+
});
|
|
50531
|
+
}
|
|
50532
|
+
function boardCommand() {
|
|
50533
|
+
const clear = new Command("clear").description("Preview, start, watch, stop or undo a clear-the-board run").option("--goal <id>", "Limit the run to one Goal").option("--yes", "Start the run after planning").option("--health-url <url>", "URL probed after each merge (needs --yes)").option(
|
|
50534
|
+
"--version-url <url>",
|
|
50535
|
+
"URL that reports the serving sha (needs --yes)"
|
|
50536
|
+
).option("--cap <usd>", "Spend cap in USD (default: hosted p90 quote)").option("--types <list>", "Comma-separated card types, e.g. code").option("--no-email", "Do not email when the run finishes").option("--no-push", "Do not push-notify when the run finishes").option(
|
|
50537
|
+
"--reject <findingId...>",
|
|
50538
|
+
"Finding ids to leave out of the accepted set"
|
|
50539
|
+
).option("--json", "Output the raw tool result");
|
|
50540
|
+
clear.action(runClear);
|
|
50541
|
+
clear.addCommand(actionCommand("status"));
|
|
50542
|
+
clear.addCommand(actionCommand("stop"));
|
|
50543
|
+
clear.addCommand(actionCommand("undo"));
|
|
50544
|
+
return new Command("board").description("Clear the board: tidy cards and run the safe ones").addCommand(clear);
|
|
50545
|
+
}
|
|
50546
|
+
|
|
50239
50547
|
// src/commands/keys.ts
|
|
50240
50548
|
import { createInterface as createInterface3 } from "node:readline";
|
|
50241
50549
|
import { Writable } from "node:stream";
|
|
@@ -55061,8 +55369,8 @@ var program2 = new Command().name("gad").description("Great Arrow Digital CLI \u
|
|
|
55061
55369
|
);
|
|
55062
55370
|
program2.hook(
|
|
55063
55371
|
"preAction",
|
|
55064
|
-
async (_thisCommand,
|
|
55065
|
-
const options =
|
|
55372
|
+
async (_thisCommand, actionCommand2) => {
|
|
55373
|
+
const options = actionCommand2.optsWithGlobals();
|
|
55066
55374
|
const config2 = await loadConfig();
|
|
55067
55375
|
setCommandWorkspaceTarget(options.workspace, config2.default_workspace);
|
|
55068
55376
|
}
|
|
@@ -55082,6 +55390,7 @@ program2.addCommand(todo_default);
|
|
|
55082
55390
|
program2.addCommand(nextCommand());
|
|
55083
55391
|
program2.addCommand(discoverCommand());
|
|
55084
55392
|
program2.addCommand(callCommand());
|
|
55393
|
+
program2.addCommand(boardCommand());
|
|
55085
55394
|
program2.addCommand(claim_default);
|
|
55086
55395
|
program2.addCommand(work_default());
|
|
55087
55396
|
program2.addCommand(worktree_default);
|