@great-arrow/cli 0.1.65 → 0.1.66
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 +3 -1
- package/dist/index.js +277 -43
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,7 +31,9 @@ gad login
|
|
|
31
31
|
gad login --no-browser
|
|
32
32
|
|
|
33
33
|
# Direct personal token (CI/CD, headless). Stored as-is; no auto-refresh.
|
|
34
|
-
|
|
34
|
+
# Over a signed-in OAuth session it takes a gad_v1_ token, keeps the session
|
|
35
|
+
# when handed the session's own access token, and otherwise needs --force.
|
|
36
|
+
gad login --token gad_v1_xxxxx
|
|
35
37
|
|
|
36
38
|
# Check who you are (shows auth type + access-token expiry)
|
|
37
39
|
gad whoami
|
package/dist/index.js
CHANGED
|
@@ -9437,7 +9437,7 @@ function isNodeError(value) {
|
|
|
9437
9437
|
|
|
9438
9438
|
// src/lib/version.ts
|
|
9439
9439
|
var CLI_PACKAGE_NAME = "@great-arrow/cli";
|
|
9440
|
-
var CLI_VERSION = "0.1.
|
|
9440
|
+
var CLI_VERSION = "0.1.66";
|
|
9441
9441
|
var GAD_INSTALL_VERSION = "2026.08.08";
|
|
9442
9442
|
var GAD_INSTALL_MIN_VERSION = "2026.06.22";
|
|
9443
9443
|
var GAD_INSTALL_HEADER = "X-GAD-Install-Version";
|
|
@@ -9594,6 +9594,17 @@ async function clearStoredCredential() {
|
|
|
9594
9594
|
await deleteToken();
|
|
9595
9595
|
}
|
|
9596
9596
|
|
|
9597
|
+
// src/lib/token-login-guard.ts
|
|
9598
|
+
function decideTokenLogin(input2) {
|
|
9599
|
+
const { token, stored, force } = input2;
|
|
9600
|
+
if (stored?.kind !== "oauth") return { action: "store" };
|
|
9601
|
+
if (token === stored.credential.accessToken) {
|
|
9602
|
+
return { action: "keep-oauth", reason: "same-access-token" };
|
|
9603
|
+
}
|
|
9604
|
+
if (token.startsWith("gad_v1_") || force) return { action: "store" };
|
|
9605
|
+
return { action: "refuse", reason: "would-replace-oauth" };
|
|
9606
|
+
}
|
|
9607
|
+
|
|
9597
9608
|
// src/lib/cli-locator.ts
|
|
9598
9609
|
import {
|
|
9599
9610
|
chmodSync,
|
|
@@ -10369,7 +10380,10 @@ var loginCommand = new Command("login").description("Authenticate the CLI with y
|
|
|
10369
10380
|
).option(
|
|
10370
10381
|
"--no-browser",
|
|
10371
10382
|
"Print the authorize URL instead of opening a browser"
|
|
10372
|
-
).option("--scope <list>", "OAuth scope to request", "mcp").
|
|
10383
|
+
).option("--scope <list>", "OAuth scope to request", "mcp").option(
|
|
10384
|
+
"--force",
|
|
10385
|
+
"With --token: replace a signed-in OAuth session even if the token may be short-lived"
|
|
10386
|
+
).action(
|
|
10373
10387
|
async (options) => {
|
|
10374
10388
|
const fmt = createFormatter({
|
|
10375
10389
|
json: false,
|
|
@@ -10380,6 +10394,24 @@ var loginCommand = new Command("login").description("Authenticate the CLI with y
|
|
|
10380
10394
|
const config2 = await loadConfig();
|
|
10381
10395
|
const apiUrl = DEFAULT_API_URL;
|
|
10382
10396
|
if (options.token) {
|
|
10397
|
+
const decision = decideTokenLogin({
|
|
10398
|
+
token: options.token,
|
|
10399
|
+
stored: await loadStoredCredential(),
|
|
10400
|
+
force: options.force === true
|
|
10401
|
+
});
|
|
10402
|
+
if (decision.action === "keep-oauth") {
|
|
10403
|
+
fmt.success(
|
|
10404
|
+
"Already signed in: that is your OAuth session's current access token. Keeping the self-refreshing session."
|
|
10405
|
+
);
|
|
10406
|
+
return;
|
|
10407
|
+
}
|
|
10408
|
+
if (decision.action === "refuse") {
|
|
10409
|
+
fmt.error(
|
|
10410
|
+
"You are signed in with a self-refreshing OAuth session, and this token is not a personal API token (gad_v1_\u2026). Storing it would replace the session, and if it is an OAuth access token it stops working within the hour. Use a gad_v1_ token, or pass --force to replace the session anyway."
|
|
10411
|
+
);
|
|
10412
|
+
process.exitCode = 1;
|
|
10413
|
+
return;
|
|
10414
|
+
}
|
|
10383
10415
|
const stored = await savePatToken(options.token);
|
|
10384
10416
|
if (!stored) {
|
|
10385
10417
|
fmt.error(
|
|
@@ -11072,7 +11104,7 @@ function getCommandWorkspaceTarget(options = {}) {
|
|
|
11072
11104
|
}
|
|
11073
11105
|
|
|
11074
11106
|
// ../local-runtime/src/abortable.ts
|
|
11075
|
-
function abortable(
|
|
11107
|
+
function abortable(run4, signal) {
|
|
11076
11108
|
return new Promise((resolve5, reject) => {
|
|
11077
11109
|
const abort = () => {
|
|
11078
11110
|
signal.removeEventListener("abort", abort);
|
|
@@ -11082,11 +11114,11 @@ function abortable(run3, signal) {
|
|
|
11082
11114
|
signal.addEventListener("abort", abort, { once: true });
|
|
11083
11115
|
Promise.resolve().then(() => {
|
|
11084
11116
|
signal.throwIfAborted();
|
|
11085
|
-
return
|
|
11117
|
+
return run4();
|
|
11086
11118
|
}).then(resolve5, reject).finally(() => signal.removeEventListener("abort", abort));
|
|
11087
11119
|
});
|
|
11088
11120
|
}
|
|
11089
|
-
async function withLocalDeadline(deadlineMs,
|
|
11121
|
+
async function withLocalDeadline(deadlineMs, run4, parentSignal) {
|
|
11090
11122
|
if (!Number.isSafeInteger(deadlineMs) || deadlineMs <= 0 || deadlineMs > 36e5)
|
|
11091
11123
|
throw new Error("Invalid local operation deadline");
|
|
11092
11124
|
const controller = new AbortController();
|
|
@@ -11096,7 +11128,7 @@ async function withLocalDeadline(deadlineMs, run3, parentSignal) {
|
|
|
11096
11128
|
deadlineMs
|
|
11097
11129
|
);
|
|
11098
11130
|
try {
|
|
11099
|
-
return await abortable(() =>
|
|
11131
|
+
return await abortable(() => run4(signal), signal);
|
|
11100
11132
|
} finally {
|
|
11101
11133
|
clearTimeout(timer);
|
|
11102
11134
|
}
|
|
@@ -11258,6 +11290,7 @@ async function withNativeResponse(context2, path10, init, consume, parentSignal)
|
|
|
11258
11290
|
|
|
11259
11291
|
// src/lib/client.ts
|
|
11260
11292
|
var DEFAULT_TIMEOUT_MS2 = 3e4;
|
|
11293
|
+
var PRESENCE_TIMEOUT_MS = 4e4;
|
|
11261
11294
|
var MAX_RETRIES = 5;
|
|
11262
11295
|
var BASE_DELAY_MS = 1e3;
|
|
11263
11296
|
function detectGitOrigin() {
|
|
@@ -11649,6 +11682,47 @@ var GadClient = class {
|
|
|
11649
11682
|
})();
|
|
11650
11683
|
}
|
|
11651
11684
|
}
|
|
11685
|
+
/**
|
|
11686
|
+
* One request with NO retry, bounded by `AbortSignal.timeout`. For the
|
|
11687
|
+
* agent-presence routes: a replayed long-poll doubles a hold and the caller
|
|
11688
|
+
* already owns the loop and its backoff. Returns the status and parsed body
|
|
11689
|
+
* (null when not JSON) so the caller can read a 404 itself; a timeout or
|
|
11690
|
+
* network failure throws.
|
|
11691
|
+
*/
|
|
11692
|
+
async requestOnce(method, path10, opts = {}) {
|
|
11693
|
+
const qs = opts.params && Object.keys(opts.params).length > 0 ? `?${new URLSearchParams(opts.params).toString()}` : "";
|
|
11694
|
+
const signal = AbortSignal.timeout(opts.timeoutMs ?? PRESENCE_TIMEOUT_MS);
|
|
11695
|
+
const headers = this.buildHeaders();
|
|
11696
|
+
if (method === "GET") delete headers["Content-Type"];
|
|
11697
|
+
if (this.getToken) {
|
|
11698
|
+
const getToken2 = this.getToken;
|
|
11699
|
+
headers.Authorization = `Bearer ${await new Promise(
|
|
11700
|
+
(resolve5, reject) => {
|
|
11701
|
+
signal.addEventListener(
|
|
11702
|
+
"abort",
|
|
11703
|
+
() => reject(networkError("Session renewal timed out.")),
|
|
11704
|
+
{ once: true }
|
|
11705
|
+
);
|
|
11706
|
+
getToken2().then(resolve5, reject);
|
|
11707
|
+
}
|
|
11708
|
+
)}`;
|
|
11709
|
+
}
|
|
11710
|
+
const response = await fetch(`${this.apiUrl}${path10}${qs}`, {
|
|
11711
|
+
method,
|
|
11712
|
+
headers,
|
|
11713
|
+
...opts.body !== void 0 && { body: JSON.stringify(opts.body) },
|
|
11714
|
+
redirect: "error",
|
|
11715
|
+
cache: "no-store",
|
|
11716
|
+
signal
|
|
11717
|
+
});
|
|
11718
|
+
let body = null;
|
|
11719
|
+
try {
|
|
11720
|
+
body = await response.json();
|
|
11721
|
+
} catch {
|
|
11722
|
+
body = null;
|
|
11723
|
+
}
|
|
11724
|
+
return { status: response.status, body };
|
|
11725
|
+
}
|
|
11652
11726
|
/**
|
|
11653
11727
|
* Make a GET request to a REST API endpoint.
|
|
11654
11728
|
*
|
|
@@ -12393,8 +12467,8 @@ function text(value) {
|
|
|
12393
12467
|
}
|
|
12394
12468
|
function formatTodoDetail(todo) {
|
|
12395
12469
|
const assignees = Array.isArray(todo.assignees) ? todo.assignees.map((a) => `${text(a.displayName)} (${text(a.type)})`).join(", ") : "";
|
|
12396
|
-
const
|
|
12397
|
-
const lastRun =
|
|
12470
|
+
const run4 = todo.lastRun ?? null;
|
|
12471
|
+
const lastRun = run4 ? `${text(run4.status)} \u2014 ${text(run4.agentName)}` : "";
|
|
12398
12472
|
return {
|
|
12399
12473
|
id: text(todo.id),
|
|
12400
12474
|
title: text(todo.title),
|
|
@@ -16668,10 +16742,10 @@ async function mcpJsonAtRiskOfCommit(dir) {
|
|
|
16668
16742
|
try {
|
|
16669
16743
|
const { execFile: execFile5 } = await import("node:child_process");
|
|
16670
16744
|
const { promisify: promisify2 } = await import("node:util");
|
|
16671
|
-
const
|
|
16672
|
-
await
|
|
16745
|
+
const run4 = promisify2(execFile5);
|
|
16746
|
+
await run4("git", ["rev-parse", "--is-inside-work-tree"], { cwd: dir });
|
|
16673
16747
|
try {
|
|
16674
|
-
await
|
|
16748
|
+
await run4("git", ["check-ignore", "-q", ".mcp.json"], { cwd: dir });
|
|
16675
16749
|
return false;
|
|
16676
16750
|
} catch {
|
|
16677
16751
|
return true;
|
|
@@ -17191,9 +17265,9 @@ async function resolveProxyScript(override) {
|
|
|
17191
17265
|
async function runProxyDiagnostics(scriptPath) {
|
|
17192
17266
|
const { execFile: execFile5 } = await import("node:child_process");
|
|
17193
17267
|
const { promisify: promisify2 } = await import("node:util");
|
|
17194
|
-
const
|
|
17268
|
+
const run4 = promisify2(execFile5);
|
|
17195
17269
|
try {
|
|
17196
|
-
const { stdout } = await
|
|
17270
|
+
const { stdout } = await run4(
|
|
17197
17271
|
process.execPath,
|
|
17198
17272
|
[scriptPath, "--print-diagnostics"],
|
|
17199
17273
|
{ timeout: 1e4, maxBuffer: 1024 * 1024 }
|
|
@@ -17219,8 +17293,8 @@ async function findLegacyStores(cwd) {
|
|
|
17219
17293
|
try {
|
|
17220
17294
|
const { execFile: execFile5 } = await import("node:child_process");
|
|
17221
17295
|
const { promisify: promisify2 } = await import("node:util");
|
|
17222
|
-
const
|
|
17223
|
-
const { stdout } = await
|
|
17296
|
+
const run4 = promisify2(execFile5);
|
|
17297
|
+
const { stdout } = await run4("git", ["worktree", "list", "--porcelain"], {
|
|
17224
17298
|
cwd,
|
|
17225
17299
|
timeout: 5e3
|
|
17226
17300
|
});
|
|
@@ -17749,6 +17823,137 @@ var agentsCommand = new Command("agents").description(
|
|
|
17749
17823
|
process.stdout.write(renderAgentsNow(result) + "\n");
|
|
17750
17824
|
});
|
|
17751
17825
|
|
|
17826
|
+
// src/commands/inbox.ts
|
|
17827
|
+
var BACKOFF_BASE_MS = 15e3;
|
|
17828
|
+
var BACKOFF_MAX_MS = 12e4;
|
|
17829
|
+
var DEFAULT_MAX_MINUTES = 50;
|
|
17830
|
+
var PRESENCE_NOT_ENABLED = "Agent presence is not enabled.";
|
|
17831
|
+
function waitBackoffMs(emptyHolds) {
|
|
17832
|
+
if (emptyHolds < 3) return 0;
|
|
17833
|
+
return Math.min(2 ** (emptyHolds - 3) * BACKOFF_BASE_MS, BACKOFF_MAX_MS);
|
|
17834
|
+
}
|
|
17835
|
+
function asMessage(body) {
|
|
17836
|
+
if (!body || typeof body !== "object") return null;
|
|
17837
|
+
const b = body;
|
|
17838
|
+
return b.status === "message" && typeof b.messageId === "string" && typeof b.block === "string" ? { messageId: b.messageId, block: b.block } : null;
|
|
17839
|
+
}
|
|
17840
|
+
async function runInboxWait(o) {
|
|
17841
|
+
const sleep2 = o.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
17842
|
+
const now = o.now ?? Date.now;
|
|
17843
|
+
const write = o.write ?? ((t) => void process.stdout.write(t));
|
|
17844
|
+
const writeErr = o.writeErr ?? ((t) => void process.stderr.write(t));
|
|
17845
|
+
const stopAt = now() + (o.maxMinutes ?? DEFAULT_MAX_MINUTES) * 6e4;
|
|
17846
|
+
let emptyHolds = 0;
|
|
17847
|
+
while (now() < stopAt) {
|
|
17848
|
+
const params = { as: o.as };
|
|
17849
|
+
if (o.after) params.after = o.after;
|
|
17850
|
+
if (o.waitingOn !== void 0) params.waiting_on = o.waitingOn;
|
|
17851
|
+
let res = null;
|
|
17852
|
+
try {
|
|
17853
|
+
res = await o.request(params);
|
|
17854
|
+
} catch {
|
|
17855
|
+
res = null;
|
|
17856
|
+
}
|
|
17857
|
+
if (res?.status === 404) {
|
|
17858
|
+
writeErr(`${PRESENCE_NOT_ENABLED}
|
|
17859
|
+
`);
|
|
17860
|
+
return 2;
|
|
17861
|
+
}
|
|
17862
|
+
const msg = res && res.status === 200 ? asMessage(res.body) : null;
|
|
17863
|
+
if (msg) {
|
|
17864
|
+
const block = msg.block.endsWith("\n") ? msg.block : `${msg.block}
|
|
17865
|
+
`;
|
|
17866
|
+
write(`${block}after=${msg.messageId}
|
|
17867
|
+
`);
|
|
17868
|
+
return 0;
|
|
17869
|
+
}
|
|
17870
|
+
const gap = Math.min(waitBackoffMs(emptyHolds++), stopAt - now());
|
|
17871
|
+
if (gap > 0) await sleep2(gap);
|
|
17872
|
+
}
|
|
17873
|
+
return 3;
|
|
17874
|
+
}
|
|
17875
|
+
function parseMaxMinutes(raw) {
|
|
17876
|
+
const n = Number(raw);
|
|
17877
|
+
return Number.isFinite(n) && n > 0 ? n : DEFAULT_MAX_MINUTES;
|
|
17878
|
+
}
|
|
17879
|
+
var waitCommand = new Command("wait").description(
|
|
17880
|
+
"Wait for a peer's message to this connection; run as a background task"
|
|
17881
|
+
).requiredOption("--as <id>", "Your connection id (from agent_inbox)").option("--after <id>", "Only wake for messages newer than this id").option("--waiting-on <text>", "What you are waiting on, shown to peers").option("--max-minutes <n>", "Give up after this many minutes", "50").action(
|
|
17882
|
+
async (opts) => {
|
|
17883
|
+
const auth = await resolveAuth();
|
|
17884
|
+
const client2 = new GadClient({
|
|
17885
|
+
token: auth.token,
|
|
17886
|
+
getToken: auth.getToken,
|
|
17887
|
+
apiUrl: auth.apiUrl
|
|
17888
|
+
});
|
|
17889
|
+
process.exitCode = await runInboxWait({
|
|
17890
|
+
request: (params) => client2.requestOnce("GET", "/api/agent-comms/wait", { params }),
|
|
17891
|
+
as: opts.as,
|
|
17892
|
+
after: opts.after,
|
|
17893
|
+
waitingOn: opts.waitingOn,
|
|
17894
|
+
maxMinutes: parseMaxMinutes(opts.maxMinutes)
|
|
17895
|
+
});
|
|
17896
|
+
}
|
|
17897
|
+
);
|
|
17898
|
+
var inboxCommand = new Command("inbox").description("Agent inbox \u2014 wait for a peer's message").addCommand(waitCommand);
|
|
17899
|
+
|
|
17900
|
+
// src/commands/presence.ts
|
|
17901
|
+
function doNotDisturbBody(raw, as) {
|
|
17902
|
+
if (raw.trim().toLowerCase() === "off") {
|
|
17903
|
+
return { action: "do_not_disturb", as, minutes: null };
|
|
17904
|
+
}
|
|
17905
|
+
const minutes = Number(raw);
|
|
17906
|
+
if (!Number.isFinite(minutes) || minutes <= 0) {
|
|
17907
|
+
throw new CliError(
|
|
17908
|
+
`Expected a number of minutes or "off", got "${raw}".`,
|
|
17909
|
+
3 /* VALIDATION_ERROR */
|
|
17910
|
+
);
|
|
17911
|
+
}
|
|
17912
|
+
return { action: "do_not_disturb", as, minutes };
|
|
17913
|
+
}
|
|
17914
|
+
async function sendPresence(o) {
|
|
17915
|
+
const write = o.write ?? ((t) => void process.stdout.write(t));
|
|
17916
|
+
const writeErr = o.writeErr ?? ((t) => void process.stderr.write(t));
|
|
17917
|
+
const res = await o.request(o.body);
|
|
17918
|
+
if (res.status === 404) {
|
|
17919
|
+
writeErr(`${PRESENCE_NOT_ENABLED}
|
|
17920
|
+
`);
|
|
17921
|
+
return 2;
|
|
17922
|
+
}
|
|
17923
|
+
if (res.status < 200 || res.status >= 300) {
|
|
17924
|
+
writeErr(`Presence update failed (HTTP ${res.status}).
|
|
17925
|
+
`);
|
|
17926
|
+
return res.status === 401 || res.status === 403 ? 1 /* AUTH_ERROR */ : res.status === 400 ? 3 /* VALIDATION_ERROR */ : 2 /* NETWORK_ERROR */;
|
|
17927
|
+
}
|
|
17928
|
+
const b = o.body;
|
|
17929
|
+
write(
|
|
17930
|
+
b.action === "sign_off" ? "Signed off.\n" : b.minutes === null ? "Do not disturb is off.\n" : `Do not disturb for ${b.minutes} minutes.
|
|
17931
|
+
`
|
|
17932
|
+
);
|
|
17933
|
+
return 0;
|
|
17934
|
+
}
|
|
17935
|
+
async function run2(body) {
|
|
17936
|
+
const auth = await resolveAuth();
|
|
17937
|
+
const client2 = new GadClient({
|
|
17938
|
+
token: auth.token,
|
|
17939
|
+
getToken: auth.getToken,
|
|
17940
|
+
apiUrl: auth.apiUrl
|
|
17941
|
+
});
|
|
17942
|
+
process.exitCode = await sendPresence({
|
|
17943
|
+
request: (b) => client2.requestOnce("POST", "/api/agent-comms/presence", { body: b }),
|
|
17944
|
+
body
|
|
17945
|
+
});
|
|
17946
|
+
}
|
|
17947
|
+
var presenceCommand = new Command("presence").description("Tell peers you are away: do not disturb, or sign off").addCommand(
|
|
17948
|
+
new Command("do-not-disturb").description("Tell peers not to disturb you for a while, or turn it off").argument("<minutes|off>", "Minutes (up to 480), or off").requiredOption("--as <id>", "Your connection id (from agent_inbox)").action(async (raw, opts) => {
|
|
17949
|
+
await run2(doNotDisturbBody(raw, opts.as));
|
|
17950
|
+
})
|
|
17951
|
+
).addCommand(
|
|
17952
|
+
new Command("sign-off").description("Mark this connection as signed off").requiredOption("--as <id>", "Your connection id (from agent_inbox)").action(async (opts) => {
|
|
17953
|
+
await run2({ action: "sign_off", as: opts.as });
|
|
17954
|
+
})
|
|
17955
|
+
);
|
|
17956
|
+
|
|
17752
17957
|
// src/commands/ask.ts
|
|
17753
17958
|
var ORCHESTRATOR_TIMEOUT_MS = 9e4;
|
|
17754
17959
|
var ANSWER_FIELDS = [
|
|
@@ -38970,7 +39175,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
38970
39175
|
return h ? h(node2, rewritten) : node2;
|
|
38971
39176
|
};
|
|
38972
39177
|
const cache = /* @__PURE__ */ new Map();
|
|
38973
|
-
function
|
|
39178
|
+
function run4(s2) {
|
|
38974
39179
|
const cached2 = cache.get(s2);
|
|
38975
39180
|
if (cached2 === RESOLVING) {
|
|
38976
39181
|
return new $ZodLazy({
|
|
@@ -38996,21 +39201,21 @@ function visit(schema, fnOrHandlers) {
|
|
|
38996
39201
|
let changed = false;
|
|
38997
39202
|
const newShape = {};
|
|
38998
39203
|
for (const k of keys) {
|
|
38999
|
-
const mapped =
|
|
39204
|
+
const mapped = run4(oldShape[k]);
|
|
39000
39205
|
if (mapped !== oldShape[k])
|
|
39001
39206
|
changed = true;
|
|
39002
39207
|
newShape[k] = mapped;
|
|
39003
39208
|
}
|
|
39004
39209
|
let newCatchall = def.catchall;
|
|
39005
39210
|
if (def.catchall) {
|
|
39006
|
-
newCatchall =
|
|
39211
|
+
newCatchall = run4(def.catchall);
|
|
39007
39212
|
if (newCatchall !== def.catchall)
|
|
39008
39213
|
changed = true;
|
|
39009
39214
|
}
|
|
39010
39215
|
return changed ? clone(s2, { ...def, shape: newShape, catchall: newCatchall }) : s2;
|
|
39011
39216
|
}
|
|
39012
39217
|
case "array": {
|
|
39013
|
-
const mapped =
|
|
39218
|
+
const mapped = run4(def.element);
|
|
39014
39219
|
return mapped === def.element ? s2 : clone(s2, { ...def, element: mapped });
|
|
39015
39220
|
}
|
|
39016
39221
|
case "tuple": {
|
|
@@ -39018,14 +39223,14 @@ function visit(schema, fnOrHandlers) {
|
|
|
39018
39223
|
let changed = false;
|
|
39019
39224
|
const newItems = [];
|
|
39020
39225
|
for (const item of oldItems) {
|
|
39021
|
-
const mapped =
|
|
39226
|
+
const mapped = run4(item);
|
|
39022
39227
|
if (mapped !== item)
|
|
39023
39228
|
changed = true;
|
|
39024
39229
|
newItems.push(mapped);
|
|
39025
39230
|
}
|
|
39026
39231
|
let newRest = def.rest;
|
|
39027
39232
|
if (def.rest) {
|
|
39028
|
-
newRest =
|
|
39233
|
+
newRest = run4(def.rest);
|
|
39029
39234
|
if (newRest !== def.rest)
|
|
39030
39235
|
changed = true;
|
|
39031
39236
|
}
|
|
@@ -39033,12 +39238,12 @@ function visit(schema, fnOrHandlers) {
|
|
|
39033
39238
|
}
|
|
39034
39239
|
case "record":
|
|
39035
39240
|
case "map": {
|
|
39036
|
-
const newKey =
|
|
39037
|
-
const newVal =
|
|
39241
|
+
const newKey = run4(def.keyType);
|
|
39242
|
+
const newVal = run4(def.valueType);
|
|
39038
39243
|
return newKey === def.keyType && newVal === def.valueType ? s2 : clone(s2, { ...def, keyType: newKey, valueType: newVal });
|
|
39039
39244
|
}
|
|
39040
39245
|
case "set": {
|
|
39041
|
-
const newVal =
|
|
39246
|
+
const newVal = run4(def.valueType);
|
|
39042
39247
|
return newVal === def.valueType ? s2 : clone(s2, { ...def, valueType: newVal });
|
|
39043
39248
|
}
|
|
39044
39249
|
case "union": {
|
|
@@ -39046,7 +39251,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
39046
39251
|
let changed = false;
|
|
39047
39252
|
const newOptions = [];
|
|
39048
39253
|
for (const opt of oldOptions) {
|
|
39049
|
-
const mapped =
|
|
39254
|
+
const mapped = run4(opt);
|
|
39050
39255
|
if (mapped !== opt)
|
|
39051
39256
|
changed = true;
|
|
39052
39257
|
newOptions.push(mapped);
|
|
@@ -39054,8 +39259,8 @@ function visit(schema, fnOrHandlers) {
|
|
|
39054
39259
|
return changed ? clone(s2, { ...def, options: newOptions }) : s2;
|
|
39055
39260
|
}
|
|
39056
39261
|
case "intersection": {
|
|
39057
|
-
const newLeft =
|
|
39058
|
-
const newRight =
|
|
39262
|
+
const newLeft = run4(def.left);
|
|
39263
|
+
const newRight = run4(def.right);
|
|
39059
39264
|
return newLeft === def.left && newRight === def.right ? s2 : clone(s2, { ...def, left: newLeft, right: newRight });
|
|
39060
39265
|
}
|
|
39061
39266
|
case "optional":
|
|
@@ -39067,23 +39272,23 @@ function visit(schema, fnOrHandlers) {
|
|
|
39067
39272
|
case "nonoptional":
|
|
39068
39273
|
case "promise":
|
|
39069
39274
|
case "success": {
|
|
39070
|
-
const newInner =
|
|
39275
|
+
const newInner = run4(def.innerType);
|
|
39071
39276
|
return newInner === def.innerType ? s2 : clone(s2, { ...def, innerType: newInner });
|
|
39072
39277
|
}
|
|
39073
39278
|
case "pipe": {
|
|
39074
|
-
const newIn =
|
|
39075
|
-
const newOut =
|
|
39279
|
+
const newIn = run4(def.in);
|
|
39280
|
+
const newOut = run4(def.out);
|
|
39076
39281
|
return newIn === def.in && newOut === def.out ? s2 : clone(s2, { ...def, in: newIn, out: newOut });
|
|
39077
39282
|
}
|
|
39078
39283
|
case "function": {
|
|
39079
|
-
const newInput =
|
|
39080
|
-
const newOutput =
|
|
39284
|
+
const newInput = run4(def.input);
|
|
39285
|
+
const newOutput = run4(def.output);
|
|
39081
39286
|
return newInput === def.input && newOutput === def.output ? s2 : clone(s2, { ...def, input: newInput, output: newOutput });
|
|
39082
39287
|
}
|
|
39083
39288
|
case "lazy": {
|
|
39084
39289
|
const original = def.getter;
|
|
39085
39290
|
const { _cachedInner, ...rest } = def;
|
|
39086
|
-
return clone(s2, { ...rest, getter: () =>
|
|
39291
|
+
return clone(s2, { ...rest, getter: () => run4(original()) });
|
|
39087
39292
|
}
|
|
39088
39293
|
// A leaf by choice: `parts` are regex fragments, not data positions.
|
|
39089
39294
|
case "template_literal":
|
|
@@ -39114,7 +39319,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
39114
39319
|
}
|
|
39115
39320
|
}
|
|
39116
39321
|
}
|
|
39117
|
-
return
|
|
39322
|
+
return run4(schema);
|
|
39118
39323
|
}
|
|
39119
39324
|
|
|
39120
39325
|
// ../../node_modules/zod/v4/classic/deep-partial.js
|
|
@@ -50304,7 +50509,7 @@ function helperKind(raw) {
|
|
|
50304
50509
|
if (/^store\b/.test(v)) return "store";
|
|
50305
50510
|
return "other";
|
|
50306
50511
|
}
|
|
50307
|
-
function
|
|
50512
|
+
function run3(file2, args) {
|
|
50308
50513
|
return new Promise((done) => {
|
|
50309
50514
|
execFile4(
|
|
50310
50515
|
file2,
|
|
@@ -50315,10 +50520,10 @@ function run2(file2, args) {
|
|
|
50315
50520
|
});
|
|
50316
50521
|
}
|
|
50317
50522
|
async function detectGhCli() {
|
|
50318
|
-
return await
|
|
50523
|
+
return await run3("gh", ["--version"]) !== null;
|
|
50319
50524
|
}
|
|
50320
50525
|
async function detectGitHelper() {
|
|
50321
|
-
const out2 = await
|
|
50526
|
+
const out2 = await run3("git", [
|
|
50322
50527
|
"config",
|
|
50323
50528
|
"--get-urlmatch",
|
|
50324
50529
|
"credential.helper",
|
|
@@ -50547,29 +50752,29 @@ function statusCommand4() {
|
|
|
50547
50752
|
const runId = requireRunId(runArg);
|
|
50548
50753
|
const { client: client2, apiUrl } = await keysContext();
|
|
50549
50754
|
const res = await client2.get(`/api/key-rotation/runs/${runId}`);
|
|
50550
|
-
const
|
|
50755
|
+
const run4 = res?.run ?? {};
|
|
50551
50756
|
if (g.json) {
|
|
50552
|
-
out(JSON.stringify(
|
|
50757
|
+
out(JSON.stringify(run4));
|
|
50553
50758
|
return;
|
|
50554
50759
|
}
|
|
50555
50760
|
const c = createColor(g.noColor || g.quiet);
|
|
50556
50761
|
out(
|
|
50557
|
-
`${c.bold(`Run ${runId}`)} ${s(
|
|
50762
|
+
`${c.bold(`Run ${runId}`)} ${s(run4.state)}` + (s(run4.waitingOn) ? c.dim(` waiting on ${s(run4.waitingOn)}`) : "")
|
|
50558
50763
|
);
|
|
50559
|
-
for (const st of
|
|
50764
|
+
for (const st of run4.steps ?? []) {
|
|
50560
50765
|
const detail = s(st.detailCode);
|
|
50561
50766
|
out(
|
|
50562
50767
|
` ${s(st.step)} ${c.dim(s(st.targetKind))} ${s(st.status)}` + (detail ? c.dim(` (${detail})`) : "")
|
|
50563
50768
|
);
|
|
50564
50769
|
}
|
|
50565
|
-
const open4 = (
|
|
50770
|
+
const open4 = (run4.checklist ?? []).filter((i) => i.ticked !== true);
|
|
50566
50771
|
if (open4.length > 0) {
|
|
50567
50772
|
out(c.yellow("Checklist (tick these in the browser):"));
|
|
50568
50773
|
for (const item of open4) {
|
|
50569
50774
|
out(` \u2610 ${s(item.label)} ${c.cyan(s(item.href))}`);
|
|
50570
50775
|
}
|
|
50571
50776
|
}
|
|
50572
|
-
for (const d of
|
|
50777
|
+
for (const d of run4.devices ?? []) {
|
|
50573
50778
|
out(` device ${s(d.label)} ${s(d.state)}`);
|
|
50574
50779
|
}
|
|
50575
50780
|
out(c.dim(`${apiUrl}${keyRotationRunPath(runId)}`));
|
|
@@ -50910,6 +51115,8 @@ var COMMANDS = [
|
|
|
50910
51115
|
"smoke",
|
|
50911
51116
|
"agent",
|
|
50912
51117
|
"ask",
|
|
51118
|
+
"inbox",
|
|
51119
|
+
"presence",
|
|
50913
51120
|
"runtime",
|
|
50914
51121
|
"open",
|
|
50915
51122
|
"completions"
|
|
@@ -50951,6 +51158,12 @@ _gad_completions() {
|
|
|
50951
51158
|
agent)
|
|
50952
51159
|
COMPREPLY=( $(compgen -W "list invoke" -- "\${cur}") )
|
|
50953
51160
|
;;
|
|
51161
|
+
inbox)
|
|
51162
|
+
COMPREPLY=( $(compgen -W "wait" -- "\${cur}") )
|
|
51163
|
+
;;
|
|
51164
|
+
presence)
|
|
51165
|
+
COMPREPLY=( $(compgen -W "do-not-disturb sign-off" -- "\${cur}") )
|
|
51166
|
+
;;
|
|
50954
51167
|
runtime)
|
|
50955
51168
|
COMPREPLY=( $(compgen -W "status set sync policy" -- "\${cur}") )
|
|
50956
51169
|
;;
|
|
@@ -50986,6 +51199,8 @@ _gad() {
|
|
|
50986
51199
|
'smoke:Run smoke tests'
|
|
50987
51200
|
'agent:Manage agents (list, invoke)'
|
|
50988
51201
|
'ask:Ask the orchestrator a question'
|
|
51202
|
+
'inbox:Agent inbox (wait)'
|
|
51203
|
+
'presence:Agent presence (do-not-disturb, sign-off)'
|
|
50989
51204
|
'runtime:Choose your computer or the cloud per lane'
|
|
50990
51205
|
'open:Open an app surface in the browser'
|
|
50991
51206
|
'completions:Generate shell completions'
|
|
@@ -51021,6 +51236,14 @@ _gad() {
|
|
|
51021
51236
|
subcommands=('list:List agents' 'invoke:Invoke an agent')
|
|
51022
51237
|
_describe -t subcommands 'agent subcommands' subcommands
|
|
51023
51238
|
;;
|
|
51239
|
+
inbox)
|
|
51240
|
+
subcommands=('wait:Wait for a peer message')
|
|
51241
|
+
_describe -t subcommands 'inbox subcommands' subcommands
|
|
51242
|
+
;;
|
|
51243
|
+
presence)
|
|
51244
|
+
subcommands=('do-not-disturb:Do not disturb for a while, or off' 'sign-off:Sign off this connection')
|
|
51245
|
+
_describe -t subcommands 'presence subcommands' subcommands
|
|
51246
|
+
;;
|
|
51024
51247
|
runtime)
|
|
51025
51248
|
subcommands=('status:Where each lane runs' 'set:Set a lane' 'sync:Apply to this checkout' 'policy:Workspace policy')
|
|
51026
51249
|
_describe -t subcommands 'runtime subcommands' subcommands
|
|
@@ -51049,6 +51272,8 @@ function generateFish() {
|
|
|
51049
51272
|
smoke: "Run smoke tests",
|
|
51050
51273
|
agent: "Manage agents",
|
|
51051
51274
|
ask: "Ask the orchestrator a question",
|
|
51275
|
+
inbox: "Agent inbox",
|
|
51276
|
+
presence: "Agent presence",
|
|
51052
51277
|
runtime: "Choose your computer or the cloud per lane",
|
|
51053
51278
|
open: "Open an app surface in the browser",
|
|
51054
51279
|
completions: "Generate shell completions"
|
|
@@ -51087,6 +51312,13 @@ function generateFish() {
|
|
|
51087
51312
|
list: "List agents",
|
|
51088
51313
|
invoke: "Invoke an agent"
|
|
51089
51314
|
},
|
|
51315
|
+
inbox: {
|
|
51316
|
+
wait: "Wait for a peer message"
|
|
51317
|
+
},
|
|
51318
|
+
presence: {
|
|
51319
|
+
"do-not-disturb": "Do not disturb for a while, or off",
|
|
51320
|
+
"sign-off": "Sign off this connection"
|
|
51321
|
+
},
|
|
51090
51322
|
runtime: {
|
|
51091
51323
|
status: "Where each lane runs",
|
|
51092
51324
|
set: "Set a lane",
|
|
@@ -54566,6 +54798,8 @@ program2.addCommand(integrations_default);
|
|
|
54566
54798
|
program2.addCommand(mcp_default);
|
|
54567
54799
|
program2.addCommand(agentCommand);
|
|
54568
54800
|
program2.addCommand(agentsCommand);
|
|
54801
|
+
program2.addCommand(inboxCommand);
|
|
54802
|
+
program2.addCommand(presenceCommand);
|
|
54569
54803
|
program2.addCommand(askCommand());
|
|
54570
54804
|
program2.addCommand(localCommand());
|
|
54571
54805
|
program2.addCommand(runtimeCommand());
|