@phnx-labs/agents-cli 1.22.114 → 1.22.115
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/CHANGELOG.md +110 -0
- package/README.md +22 -102
- package/dist/browser.js +0 -0
- package/dist/cli/command-registry.js +0 -7
- package/dist/commands/accounts.d.ts +3 -77
- package/dist/commands/accounts.js +13 -366
- package/dist/commands/audit.js +1 -1
- package/dist/commands/auth.js +0 -2
- package/dist/commands/browser.d.ts +53 -0
- package/dist/commands/browser.js +199 -9
- package/dist/commands/doctor.d.ts +2 -3
- package/dist/commands/doctor.js +0 -11
- package/dist/commands/events.d.ts +1 -3
- package/dist/commands/events.js +4 -7
- package/dist/commands/exec.d.ts +0 -1
- package/dist/commands/exec.js +2 -7
- package/dist/commands/feed-watch.js +52 -8
- package/dist/commands/focus.js +1 -1
- package/dist/commands/go.d.ts +0 -17
- package/dist/commands/go.js +2 -19
- package/dist/commands/logs.js +1 -1
- package/dist/commands/mcp.js +8 -83
- package/dist/commands/memory.js +4 -47
- package/dist/commands/message.js +4 -4
- package/dist/commands/plugins.js +1 -93
- package/dist/commands/repo.js +0 -44
- package/dist/commands/resume.js +4 -1
- package/dist/commands/secrets-passthrough.js +2 -2
- package/dist/commands/send.d.ts +4 -4
- package/dist/commands/send.js +6 -51
- package/dist/commands/sessions-backup-setup.js +1 -1
- package/dist/commands/sessions-resume.js +0 -1
- package/dist/commands/sessions-share.d.ts +5 -7
- package/dist/commands/sessions-share.js +98 -49
- package/dist/commands/sessions.js +1 -8
- package/dist/commands/setup-browser.js +18 -2
- package/dist/commands/setup-computer.js +20 -6
- package/dist/commands/setup-secrets.js +24 -4
- package/dist/commands/setup-terminal.d.ts +3 -0
- package/dist/commands/setup-terminal.js +22 -0
- package/dist/commands/setup.d.ts +1 -1
- package/dist/commands/setup.js +20 -10
- package/dist/commands/skills.js +0 -8
- package/dist/commands/ssh.d.ts +6 -0
- package/dist/commands/ssh.js +92 -233
- package/dist/commands/sync.js +14 -5
- package/dist/commands/teams.js +1 -1
- package/dist/commands/traces.js +1 -1
- package/dist/lib/accounts/add.d.ts +0 -5
- package/dist/lib/accounts/add.js +1 -7
- package/dist/lib/artifacts-client.d.ts +20 -0
- package/dist/lib/artifacts-client.js +46 -0
- package/dist/lib/auth-mint.js +2 -2
- package/dist/lib/browser/runtime-state.d.ts +55 -0
- package/dist/lib/browser/runtime-state.js +99 -18
- package/dist/lib/browser/service.js +21 -1
- package/dist/lib/cli-resources.js +3 -1
- package/dist/lib/cloud/dispatch.js +1 -1
- package/dist/lib/cloudflare/creds.d.ts +10 -0
- package/dist/lib/cloudflare/creds.js +46 -0
- package/dist/lib/cloudflare/provision.d.ts +35 -0
- package/dist/lib/cloudflare/provision.js +144 -0
- package/dist/lib/computer/sessions-list.d.ts +55 -0
- package/dist/lib/computer/sessions-list.js +168 -1
- package/dist/lib/daemon/daemon.js +8 -1
- package/dist/lib/daemon/feed-stream-service.d.ts +23 -0
- package/dist/lib/daemon/feed-stream-service.js +40 -0
- package/dist/lib/daemon-services.d.ts +1 -1
- package/dist/lib/daemon-services.js +5 -0
- package/dist/lib/devices/connect.d.ts +49 -5
- package/dist/lib/devices/connect.js +169 -21
- package/dist/lib/feed/envelope.d.ts +79 -0
- package/dist/lib/feed/envelope.js +23 -0
- package/dist/lib/feed/events.d.ts +6 -0
- package/dist/lib/feed/events.js +8 -0
- package/dist/lib/feed/hub-server.d.ts +86 -0
- package/dist/lib/feed/hub-server.js +334 -0
- package/dist/lib/feed/hub.d.ts +95 -0
- package/dist/lib/feed/hub.js +255 -0
- package/dist/lib/feed/tool-activity.d.ts +108 -0
- package/dist/lib/feed/tool-activity.js +313 -0
- package/dist/lib/feed/tools.d.ts +198 -0
- package/dist/lib/feed/tools.js +265 -0
- package/dist/lib/feed/watch.d.ts +50 -50
- package/dist/lib/feed/watch.js +147 -16
- package/dist/lib/format.d.ts +1 -1
- package/dist/lib/format.js +1 -1
- package/dist/lib/git.d.ts +0 -16
- package/dist/lib/git.js +0 -58
- package/dist/lib/helper-versions.js +1 -1
- package/dist/lib/hosts/remote-cmd.d.ts +51 -1
- package/dist/lib/hosts/remote-cmd.js +125 -8
- package/dist/lib/hosts/remote-cmd.test-fixture.d.ts +2 -0
- package/dist/lib/hosts/remote-cmd.test-fixture.js +22 -0
- package/dist/lib/mcp.js +17 -11
- package/dist/lib/probe.d.ts +4 -1
- package/dist/lib/probe.js +5 -2
- package/dist/lib/pwsh.d.ts +33 -0
- package/dist/lib/pwsh.js +56 -0
- package/dist/lib/redact.d.ts +8 -0
- package/dist/lib/redact.js +11 -0
- package/dist/lib/refresh.d.ts +6 -2
- package/dist/lib/refresh.js +92 -72
- package/dist/lib/secrets-cli.d.ts +11 -0
- package/dist/lib/secrets-cli.js +30 -0
- package/dist/lib/secrets-client.js +3 -2
- package/dist/lib/session/detached.d.ts +7 -0
- package/dist/lib/session/detached.js +29 -0
- package/dist/lib/session/remote/peer-stream.d.ts +24 -2
- package/dist/lib/session/remote/peer-stream.js +33 -6
- package/dist/lib/session/sync/backend.d.ts +3 -3
- package/dist/lib/session/sync/backend.js +3 -3
- package/dist/lib/session/sync/provision.d.ts +1 -1
- package/dist/lib/session/sync/provision.js +2 -2
- package/dist/lib/sessions-client.js +0 -3
- package/dist/lib/setup-tool-install.d.ts +3 -0
- package/dist/lib/setup-tool-install.js +26 -0
- package/dist/lib/setup-tool-status.d.ts +22 -0
- package/dist/lib/setup-tool-status.js +215 -0
- package/dist/lib/share-runtime.d.ts +11 -0
- package/dist/lib/share-runtime.js +63 -0
- package/dist/lib/smart-launch.d.ts +1 -5
- package/dist/lib/smart-launch.js +3 -11
- package/dist/lib/ssh-exec.d.ts +44 -0
- package/dist/lib/ssh-exec.js +119 -0
- package/dist/lib/startup/command-registry.d.ts +6 -4
- package/dist/lib/startup/command-registry.js +10 -7
- package/dist/lib/state.js +2 -2
- package/dist/lib/storage/selection.d.ts +2 -2
- package/dist/lib/storage/selection.js +2 -2
- package/dist/lib/sync-umbrella.d.ts +5 -0
- package/dist/lib/sync-umbrella.js +18 -10
- package/dist/lib/traces/backend.d.ts +1 -2
- package/dist/lib/traces/backend.js +1 -2
- package/dist/lib/traces/provision.d.ts +1 -1
- package/dist/lib/traces/provision.js +2 -2
- package/dist/lib/types.d.ts +8 -6
- package/package.json +2 -3
- package/dist/commands/artifacts-setup.d.ts +0 -53
- package/dist/commands/artifacts-setup.js +0 -161
- package/dist/commands/artifacts.d.ts +0 -18
- package/dist/commands/artifacts.js +0 -58
- package/dist/commands/attach.d.ts +0 -12
- package/dist/commands/attach.js +0 -86
- package/dist/commands/auth-mint.d.ts +0 -12
- package/dist/commands/auth-mint.js +0 -108
- package/dist/commands/reconnect.d.ts +0 -46
- package/dist/commands/reconnect.js +0 -115
- package/dist/commands/share.d.ts +0 -293
- package/dist/commands/share.js +0 -1424
- package/dist/lib/share/analytics.d.ts +0 -13
- package/dist/lib/share/analytics.js +0 -45
- package/dist/lib/share/backend.d.ts +0 -120
- package/dist/lib/share/backend.js +0 -176
- package/dist/lib/share/capture.d.ts +0 -31
- package/dist/lib/share/capture.js +0 -174
- package/dist/lib/share/config.d.ts +0 -72
- package/dist/lib/share/config.js +0 -211
- package/dist/lib/share/delete.d.ts +0 -123
- package/dist/lib/share/delete.js +0 -173
- package/dist/lib/share/html.d.ts +0 -20
- package/dist/lib/share/html.js +0 -88
- package/dist/lib/share/http-error.d.ts +0 -53
- package/dist/lib/share/http-error.js +0 -65
- package/dist/lib/share/og.d.ts +0 -26
- package/dist/lib/share/og.js +0 -84
- package/dist/lib/share/provision.d.ts +0 -127
- package/dist/lib/share/provision.js +0 -285
- package/dist/lib/share/publish.d.ts +0 -379
- package/dist/lib/share/publish.js +0 -818
- package/dist/lib/share/worker-template.d.ts +0 -27
- package/dist/lib/share/worker-template.js +0 -2424
- package/dist/lib/storage/index.d.ts +0 -14
- package/dist/lib/storage/index.js +0 -14
- package/dist/lib/storage/visibility.d.ts +0 -82
- package/dist/lib/storage/visibility.js +0 -99
package/dist/lib/ssh-exec.js
CHANGED
|
@@ -317,6 +317,125 @@ export function sshExecRaw(target, remoteCmd, opts = {}) {
|
|
|
317
317
|
* offset-resumed log following where a UTF-8 decode boundary must not shift the
|
|
318
318
|
* byte cursor.
|
|
319
319
|
*/
|
|
320
|
+
/** Grace between SIGTERM and SIGKILL for a stream that will not stop. */
|
|
321
|
+
export const SSH_STREAM_KILL_GRACE_MS = 3_000;
|
|
322
|
+
/** Bytes of a stream's stderr retained; the rest is dropped, with a note. */
|
|
323
|
+
export const SSH_STREAM_MAX_STDERR = 8 * 1024;
|
|
324
|
+
/**
|
|
325
|
+
* Stream one ssh command's stdout, with the args and env a CALLER built.
|
|
326
|
+
*
|
|
327
|
+
* This exists because {@link sshExecRawStream} assembles its own ssh args, which
|
|
328
|
+
* means it cannot carry a device's canonical auth — the askpass shim for a
|
|
329
|
+
* password-auth box, `-i`/`IdentitiesOnly` for an explicit identity file, or the
|
|
330
|
+
* managed known-hosts pinning. A caller that has already built those through
|
|
331
|
+
* `buildSshInvocation` needs a way to run them, and duplicating the transport to
|
|
332
|
+
* get it would be the worse answer. So this takes `args`/`env` verbatim and adds
|
|
333
|
+
* only the lifecycle guarantees:
|
|
334
|
+
*
|
|
335
|
+
* - **SIGTERM then SIGKILL.** A timeout or abort that only sends SIGTERM leaks a
|
|
336
|
+
* child that ignores it — ssh does, mid-handshake — and the promise never
|
|
337
|
+
* settles. After {@link SSH_STREAM_KILL_GRACE_MS} the child is SIGKILLed and
|
|
338
|
+
* `killed` says so.
|
|
339
|
+
* - **Bounded stderr.** A peer that writes endlessly to stderr would otherwise
|
|
340
|
+
* grow this buffer without limit; it is capped and `stderrTruncated` says so.
|
|
341
|
+
* - **`onStdout` cannot break the caller's cleanup.** A throw from the consumer
|
|
342
|
+
* is captured and re-thrown by the awaiting caller, so a write failure ends the
|
|
343
|
+
* transfer instead of escaping as an unhandled error inside a stream event.
|
|
344
|
+
*/
|
|
345
|
+
export function sshStreamWithArgs(opts) {
|
|
346
|
+
const maxStderr = opts.maxStderrBytes ?? SSH_STREAM_MAX_STDERR;
|
|
347
|
+
const grace = opts.killGraceMs ?? SSH_STREAM_KILL_GRACE_MS;
|
|
348
|
+
return new Promise((resolve, reject) => {
|
|
349
|
+
const child = spawn(opts.sshBin ?? 'ssh', opts.args, {
|
|
350
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
351
|
+
env: opts.env ? { ...process.env, ...opts.env } : process.env,
|
|
352
|
+
windowsHide: true,
|
|
353
|
+
// Own process group on POSIX so a kill reaches the whole tree. Killing only
|
|
354
|
+
// the ssh pid is not enough: a descendant that inherited stdout keeps the
|
|
355
|
+
// pipe open, `'close'` never fires, and the promise hangs for as long as
|
|
356
|
+
// that grandchild lives — which defeats the timeout entirely.
|
|
357
|
+
detached: process.platform !== 'win32',
|
|
358
|
+
});
|
|
359
|
+
const stderr = [];
|
|
360
|
+
let stderrBytes = 0;
|
|
361
|
+
let stderrTruncated = false;
|
|
362
|
+
let timedOut = false;
|
|
363
|
+
let killed = false;
|
|
364
|
+
let consumerError;
|
|
365
|
+
let settled = false;
|
|
366
|
+
let killTimer;
|
|
367
|
+
/** Signal the whole group where the platform supports it, else just the child. */
|
|
368
|
+
const signal = (sig) => {
|
|
369
|
+
try {
|
|
370
|
+
if (process.platform !== 'win32' && child.pid)
|
|
371
|
+
process.kill(-child.pid, sig);
|
|
372
|
+
else
|
|
373
|
+
child.kill(sig);
|
|
374
|
+
}
|
|
375
|
+
catch { /* already gone */ }
|
|
376
|
+
};
|
|
377
|
+
const escalate = () => {
|
|
378
|
+
signal('SIGTERM');
|
|
379
|
+
// Escalation, not a second polite ask: a child still alive after the grace
|
|
380
|
+
// is one that is not going to honour SIGTERM.
|
|
381
|
+
killTimer = setTimeout(() => { killed = true; signal('SIGKILL'); }, grace);
|
|
382
|
+
killTimer.unref?.();
|
|
383
|
+
};
|
|
384
|
+
const stop = () => escalate();
|
|
385
|
+
const finish = (code) => {
|
|
386
|
+
if (settled)
|
|
387
|
+
return;
|
|
388
|
+
settled = true;
|
|
389
|
+
if (timer)
|
|
390
|
+
clearTimeout(timer);
|
|
391
|
+
if (killTimer)
|
|
392
|
+
clearTimeout(killTimer);
|
|
393
|
+
opts.signal?.removeEventListener('abort', stop);
|
|
394
|
+
if (consumerError !== undefined) {
|
|
395
|
+
reject(consumerError);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
resolve({ code, stderr: Buffer.concat(stderr), timedOut, killed, stderrTruncated });
|
|
399
|
+
};
|
|
400
|
+
const timer = opts.timeoutMs
|
|
401
|
+
? setTimeout(() => { timedOut = true; escalate(); }, opts.timeoutMs)
|
|
402
|
+
: null;
|
|
403
|
+
child.stdout.on('data', (chunk) => {
|
|
404
|
+
if (consumerError !== undefined)
|
|
405
|
+
return;
|
|
406
|
+
try {
|
|
407
|
+
opts.onStdout(chunk);
|
|
408
|
+
}
|
|
409
|
+
catch (error) {
|
|
410
|
+
// Captured, not thrown: a throw here would surface as an unhandled error
|
|
411
|
+
// on the stream and skip the caller's cleanup entirely.
|
|
412
|
+
consumerError = error;
|
|
413
|
+
escalate();
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
child.stderr.on('data', (chunk) => {
|
|
417
|
+
const room = maxStderr - stderrBytes;
|
|
418
|
+
if (room <= 0) {
|
|
419
|
+
stderrTruncated = true;
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
if (chunk.length > room) {
|
|
423
|
+
stderrTruncated = true;
|
|
424
|
+
stderr.push(chunk.subarray(0, room));
|
|
425
|
+
stderrBytes = maxStderr;
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
stderr.push(chunk);
|
|
429
|
+
stderrBytes += chunk.length;
|
|
430
|
+
});
|
|
431
|
+
child.once('error', () => finish(null));
|
|
432
|
+
child.once('close', finish);
|
|
433
|
+
if (opts.signal?.aborted)
|
|
434
|
+
escalate();
|
|
435
|
+
else
|
|
436
|
+
opts.signal?.addEventListener('abort', stop, { once: true });
|
|
437
|
+
});
|
|
438
|
+
}
|
|
320
439
|
export function sshExecRawStream(target, remoteCmd, opts) {
|
|
321
440
|
assertValidSshTarget(target);
|
|
322
441
|
const mux = opts.multiplex === false ? [] : controlOpts();
|
|
@@ -17,15 +17,17 @@ export declare const KNOWN_TOP_LEVEL_COMMANDS: ReadonlySet<string>;
|
|
|
17
17
|
* name is gone, the spellchecker finds a neighbour, and the CLI runs something
|
|
18
18
|
* the user never asked for instead of saying the command is gone.
|
|
19
19
|
*
|
|
20
|
-
* `set` moved under `agents models`/`agents config` (RUSH-2579); `share
|
|
21
|
-
*
|
|
20
|
+
* `set` moved under `agents models`/`agents config` (RUSH-2579); `share`,
|
|
21
|
+
* `unshare`, and the whole `artifacts` group moved OUT to the standalone
|
|
22
|
+
* `artifacts` CLI (`@phnx-labs/artifacts-cli`, PHNX-3992) — artifact sharing is
|
|
23
|
+
* no longer an agents-cli surface at all. login/logout/budget/bench/mine/
|
|
22
24
|
* cost/output/profiles/snapshot/cp/resume/roster moved under nested homes
|
|
23
25
|
* (cli-surface-consolidate). `timeline` was removed as a duplicated surface —
|
|
24
26
|
* use `agents feed --filter updates` (RUSH-2692). `status` moved under
|
|
25
27
|
* `agents sync status` (RUSH-2864). `tickets` was removed — use `linear`
|
|
26
28
|
* (linear-cli) (RUSH-2932). `alias` moved under `agents setup alias` (RUSH-2965).
|
|
27
|
-
* `inbox` was a pure alias of `agents feed` (RUSH-2984). `
|
|
28
|
-
* `agents
|
|
29
|
+
* `inbox` was a pure alias of `agents feed` (RUSH-2984). `audit` nested under
|
|
30
|
+
* `agents events audit`.
|
|
29
31
|
* `trends` was removed with the insights recipe collapse — the one counter
|
|
30
32
|
* surface is `agents insights mix` (PHNX-3391). `serve` (the
|
|
31
33
|
* read-only local web companion + `--control` anchor) was removed with the
|
|
@@ -2,14 +2,14 @@ const LOADED_COMMAND_NAMES = [
|
|
|
2
2
|
'accounts', 'auth', 'view', 'inspect', 'feedback', 'commands', 'hooks', 'skills', 'rules', 'memory',
|
|
3
3
|
'permissions', 'mcp', 'clis', 'subagents', 'plugins', 'workflows', 'add', 'use',
|
|
4
4
|
'remove', 'rm', 'purge', 'update', 'prune', 'import', 'registry', 'search', 'install', 'packages',
|
|
5
|
-
'routines', 'monitors', 'projects', 'run', '_callback', 'open', '
|
|
5
|
+
'routines', 'monitors', 'projects', 'run', '_callback', 'open', 'fork', 'config',
|
|
6
6
|
'models', 'modes', 'trash', 'restore', 'doctor',
|
|
7
7
|
'route', 'routes', 'harness', 'harnesses', 'secrets', 'menubar', 'sync',
|
|
8
8
|
'refresh-rules', 'factory', 'insights', 'trace', 'reminders',
|
|
9
9
|
'tmux', 'watchdog', 'browser', 'computer', 'logs', 'events',
|
|
10
10
|
'ssh', 'devices', 'fleet', 'repos', 'repo', 'setup', 'uninstall', 'upgrade', 'sessions',
|
|
11
|
-
'teams', 'cloud', 'message', 'send', '
|
|
12
|
-
'mailboxes', 'mailbox', '
|
|
11
|
+
'teams', 'cloud', 'message', 'send', 'feed',
|
|
12
|
+
'mailboxes', 'mailbox', 'webhooks',
|
|
13
13
|
'humans', 'daemon', 'traces',
|
|
14
14
|
];
|
|
15
15
|
const INLINE_COMMAND_NAMES = [
|
|
@@ -37,15 +37,17 @@ export const KNOWN_TOP_LEVEL_COMMANDS = new Set([
|
|
|
37
37
|
* name is gone, the spellchecker finds a neighbour, and the CLI runs something
|
|
38
38
|
* the user never asked for instead of saying the command is gone.
|
|
39
39
|
*
|
|
40
|
-
* `set` moved under `agents models`/`agents config` (RUSH-2579); `share
|
|
41
|
-
*
|
|
40
|
+
* `set` moved under `agents models`/`agents config` (RUSH-2579); `share`,
|
|
41
|
+
* `unshare`, and the whole `artifacts` group moved OUT to the standalone
|
|
42
|
+
* `artifacts` CLI (`@phnx-labs/artifacts-cli`, PHNX-3992) — artifact sharing is
|
|
43
|
+
* no longer an agents-cli surface at all. login/logout/budget/bench/mine/
|
|
42
44
|
* cost/output/profiles/snapshot/cp/resume/roster moved under nested homes
|
|
43
45
|
* (cli-surface-consolidate). `timeline` was removed as a duplicated surface —
|
|
44
46
|
* use `agents feed --filter updates` (RUSH-2692). `status` moved under
|
|
45
47
|
* `agents sync status` (RUSH-2864). `tickets` was removed — use `linear`
|
|
46
48
|
* (linear-cli) (RUSH-2932). `alias` moved under `agents setup alias` (RUSH-2965).
|
|
47
|
-
* `inbox` was a pure alias of `agents feed` (RUSH-2984). `
|
|
48
|
-
* `agents
|
|
49
|
+
* `inbox` was a pure alias of `agents feed` (RUSH-2984). `audit` nested under
|
|
50
|
+
* `agents events audit`.
|
|
49
51
|
* `trends` was removed with the insights recipe collapse — the one counter
|
|
50
52
|
* surface is `agents insights mix` (PHNX-3391). `serve` (the
|
|
51
53
|
* read-only local web companion + `--control` anchor) was removed with the
|
|
@@ -81,6 +83,7 @@ export const RETIRED_TOP_LEVEL_COMMANDS = new Set([
|
|
|
81
83
|
'roster',
|
|
82
84
|
'set',
|
|
83
85
|
'share',
|
|
86
|
+
'artifacts',
|
|
84
87
|
'timeline',
|
|
85
88
|
'status',
|
|
86
89
|
'tickets',
|
package/dist/lib/state.js
CHANGED
|
@@ -215,8 +215,8 @@ export function getOptionalUserAgentsDir() {
|
|
|
215
215
|
* Origin `owner/repo` slug (lowercased, `.git` stripped) of a git checkout, or
|
|
216
216
|
* null when `dir` isn't a git repo / has no origin. Extracts the slug from any
|
|
217
217
|
* remote URL form: `git@host:owner/repo.git`, `https://host/owner/repo.git`,
|
|
218
|
-
* `ssh://git@host/owner/repo`. Sync (
|
|
219
|
-
* can be used from the synchronous getProjectAgentsDir walk.
|
|
218
|
+
* `ssh://git@host/owner/repo`. Sync (uses `execFileSync`, not the async git
|
|
219
|
+
* helpers) so it can be used from the synchronous getProjectAgentsDir walk.
|
|
220
220
|
*/
|
|
221
221
|
function gitOriginSlug(dir) {
|
|
222
222
|
let url;
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* covers — those differ (share uses an email-handle namespace with public reads
|
|
14
14
|
* and covers; a traces/sessions adapter uses the userId and differs again). Each
|
|
15
15
|
* surface keeps its own DISCRIMINATED, typed adapter that reads this decision and
|
|
16
|
-
* returns its own `kind`-tagged backend. See `lib/
|
|
17
|
-
*
|
|
16
|
+
* returns its own `kind`-tagged backend. See `lib/traces/backend.ts` for a
|
|
17
|
+
* concrete adapter.
|
|
18
18
|
*/
|
|
19
19
|
import { type PhoenixSession } from '../identity/client.js';
|
|
20
20
|
/** The two legitimate principals any managed-capable surface can resolve to. */
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* covers — those differ (share uses an email-handle namespace with public reads
|
|
14
14
|
* and covers; a traces/sessions adapter uses the userId and differs again). Each
|
|
15
15
|
* surface keeps its own DISCRIMINATED, typed adapter that reads this decision and
|
|
16
|
-
* returns its own `kind`-tagged backend. See `lib/
|
|
17
|
-
*
|
|
16
|
+
* returns its own `kind`-tagged backend. See `lib/traces/backend.ts` for a
|
|
17
|
+
* concrete adapter.
|
|
18
18
|
*/
|
|
19
19
|
import { readSession } from '../identity/client.js';
|
|
20
20
|
/**
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* arrives with `agents secrets vault unlock`, #366/#367)
|
|
16
16
|
* reconcile-> refresh({ skipPrompts }) — re-materialize resources into homes
|
|
17
17
|
*/
|
|
18
|
+
import type { ResourceSelection } from './installations/versions.js';
|
|
18
19
|
/** The umbrella flags off `agents sync`. */
|
|
19
20
|
export interface UmbrellaFlags {
|
|
20
21
|
repos?: boolean;
|
|
@@ -87,6 +88,10 @@ interface RunUmbrellaArgs {
|
|
|
87
88
|
* `agents sync --json` / fleet fan-out leave stdout as a single JSON object.
|
|
88
89
|
*/
|
|
89
90
|
quiet?: boolean;
|
|
91
|
+
/** Optional resource-only reconcile across installed versions. */
|
|
92
|
+
selection?: ResourceSelection;
|
|
93
|
+
/** Explicit consent for selected plugins that add executable surfaces. */
|
|
94
|
+
allowExecSurfaces?: boolean;
|
|
90
95
|
}
|
|
91
96
|
/**
|
|
92
97
|
* Execute the planned stages in order: repos -> secrets -> reconcile.
|
|
@@ -53,7 +53,7 @@ export function planUmbrellaStages(f) {
|
|
|
53
53
|
* reconcile — `agents sync` should make as much current as it can in one pass.
|
|
54
54
|
*/
|
|
55
55
|
export async function runUmbrellaSync(args) {
|
|
56
|
-
const { flags, log, yes, passphrase, quiet = false } = args;
|
|
56
|
+
const { flags, log, yes, passphrase, quiet = false, selection, allowExecSurfaces = false } = args;
|
|
57
57
|
const plan = planUmbrellaStages(flags);
|
|
58
58
|
const result = { plan, reconciled: false, declined: [], reconciledVersions: [] };
|
|
59
59
|
if (plan.fetchRepos) {
|
|
@@ -131,7 +131,13 @@ export async function runUmbrellaSync(args) {
|
|
|
131
131
|
}
|
|
132
132
|
if (plan.reconcile) {
|
|
133
133
|
const { refresh } = await import('./refresh.js');
|
|
134
|
-
const refreshed = await refresh({
|
|
134
|
+
const refreshed = await refresh({
|
|
135
|
+
skipPrompts: yes,
|
|
136
|
+
quiet,
|
|
137
|
+
skipClis: selection !== undefined,
|
|
138
|
+
selection,
|
|
139
|
+
allowExecSurfaces,
|
|
140
|
+
});
|
|
135
141
|
result.reconciled = true;
|
|
136
142
|
result.declined = refreshed.declined;
|
|
137
143
|
result.reconciledVersions = refreshed.reconciled;
|
|
@@ -140,14 +146,16 @@ export async function runUmbrellaSync(args) {
|
|
|
140
146
|
// rather than silently adding them (refresh mode). Soft: a machine without
|
|
141
147
|
// tailscale is a clean no-op, never a sync failure. First-run population is
|
|
142
148
|
// `agents setup` / manual `agents devices sync` (bootstrap).
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
if (!selection) {
|
|
150
|
+
const { runDeviceSync } = await import('./devices/sync.js');
|
|
151
|
+
const { reconcilePendingSentinels } = await import('./devices/pending.js');
|
|
152
|
+
const dev = await runDeviceSync({ soft: true, mode: 'refresh' });
|
|
153
|
+
if (dev.ok)
|
|
154
|
+
await reconcilePendingSentinels(dev.pending);
|
|
155
|
+
result.devices = { synced: dev.synced, pending: dev.pending.length, skipped: !dev.ok };
|
|
156
|
+
if (dev.ok) {
|
|
157
|
+
log(`devices: ${dev.synced} refreshed${dev.pending.length ? `, ${dev.pending.length} new pending` : ''}`);
|
|
158
|
+
}
|
|
151
159
|
}
|
|
152
160
|
}
|
|
153
161
|
return result;
|
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
* `traces.agents-cli.sh` Worker. Zero Cloudflare setup.
|
|
7
7
|
*
|
|
8
8
|
* BYO path (future): TRACES_BASE_URL + TRACES_WRITE_TOKEN env vars. Not
|
|
9
|
-
* exposed in the CLI for M1 — follow-on milestone
|
|
10
|
-
* `agents artifacts setup`.
|
|
9
|
+
* exposed in the CLI for M1 — follow-on milestone.
|
|
11
10
|
*/
|
|
12
11
|
export declare const DEFAULT_TRACES_DOMAIN = "traces.agents-cli.sh";
|
|
13
12
|
export interface TracesBackend {
|
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
* `traces.agents-cli.sh` Worker. Zero Cloudflare setup.
|
|
7
7
|
*
|
|
8
8
|
* BYO path (future): TRACES_BASE_URL + TRACES_WRITE_TOKEN env vars. Not
|
|
9
|
-
* exposed in the CLI for M1 — follow-on milestone
|
|
10
|
-
* `agents artifacts setup`.
|
|
9
|
+
* exposed in the CLI for M1 — follow-on milestone.
|
|
11
10
|
*/
|
|
12
11
|
import { readSession } from '../identity/client.js';
|
|
13
12
|
import { selectStorageBackendKind } from '../storage/selection.js';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Cloudflare orchestration for the private agents-traces store. The generic
|
|
2
|
-
// request primitives live in
|
|
2
|
+
// request primitives live in cloudflare/provision; only the isolated traces resource
|
|
3
3
|
// choices and Worker template belong here.
|
|
4
4
|
import { randomBytes } from 'node:crypto';
|
|
5
|
-
import { addCustomDomain, createBucket, deployWorker, enableWorkersDev, findZoneId, putWorkerSecret, } from '../
|
|
5
|
+
import { addCustomDomain, createBucket, deployWorker, enableWorkersDev, findZoneId, putWorkerSecret, } from '../cloudflare/provision.js';
|
|
6
6
|
import { DEFAULT_TRACES_DOMAIN } from './backend.js';
|
|
7
7
|
import { renderTracesWorkerScript } from './worker-template.js';
|
|
8
8
|
/** Bind the Phoenix identity base URL used to verify every trace read and write. */
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -1142,9 +1142,12 @@ export interface Meta {
|
|
|
1142
1142
|
discovery?: Record<string, 'approved' | 'ignored'>;
|
|
1143
1143
|
ignored?: import('./fleet/types.js').IgnoredDeviceEntry[];
|
|
1144
1144
|
};
|
|
1145
|
-
/**
|
|
1146
|
-
*
|
|
1147
|
-
*
|
|
1145
|
+
/** Legacy artifact-share endpoint (Cloudflare R2 + Worker), synced fleet-wide
|
|
1146
|
+
* via `agents repo push/pull`. Artifact sharing moved to the standalone
|
|
1147
|
+
* `artifacts` CLI (PHNX-3992), so agents-cli no longer writes this — but
|
|
1148
|
+
* `shareRuntimeEnv` (`lib/share-runtime.ts`) still reads `baseUrl` to decide
|
|
1149
|
+
* whether to inject the `share` bundle's write token into spawned agents. The
|
|
1150
|
+
* write token lives in the `share` secrets bundle, not here. */
|
|
1148
1151
|
share?: {
|
|
1149
1152
|
baseUrl?: string;
|
|
1150
1153
|
accountId?: string;
|
|
@@ -1153,9 +1156,8 @@ export interface Meta {
|
|
|
1153
1156
|
domain?: string;
|
|
1154
1157
|
/** Cloudflare Web Analytics token injected into published HTML pages. */
|
|
1155
1158
|
analyticsToken?: string;
|
|
1156
|
-
/** sha256 of the Worker script deployed at the last provision/update
|
|
1157
|
-
*
|
|
1158
|
-
* from before this field existed has no hash — always "unknown"). */
|
|
1159
|
+
/** sha256 of the Worker script deployed at the last provision/update
|
|
1160
|
+
* (legacy; a config from before this field existed has no hash). */
|
|
1159
1161
|
templateHash?: string;
|
|
1160
1162
|
};
|
|
1161
1163
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phnx-labs/agents-cli",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.115",
|
|
4
4
|
"description": "One CLI for all your AI coding agents - versions, config, cloud dispatch, sessions, and teams (now with first-class Grok Build CLI support)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"bin": {
|
|
18
18
|
"agents": "dist/index.js",
|
|
19
|
-
"ag": "dist/index.js"
|
|
20
|
-
"browser": "dist/browser.js"
|
|
19
|
+
"ag": "dist/index.js"
|
|
21
20
|
},
|
|
22
21
|
"files": [
|
|
23
22
|
"dist/**/*.js",
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `agents artifacts setup` — configure the artifact share endpoint (Cloudflare
|
|
3
|
-
* R2 + Worker) that backs `agents artifacts share`.
|
|
4
|
-
*
|
|
5
|
-
* One door, two modes, because it replaces two commands that used to be
|
|
6
|
-
* separate (RUSH-2580): the interactive wizard formerly at `agents setup share`
|
|
7
|
-
* and the flag-driven provisioner formerly at `agents share setup`. On a TTY
|
|
8
|
-
* with no provisioning flags TYPED it runs the wizard (provision or join, and
|
|
9
|
-
* offers a Worker update when an endpoint already exists); with any provisioning
|
|
10
|
-
* flag typed, or on a non-TTY, it provisions directly. Both modes call the same
|
|
11
|
-
* `runShareProvision` / `runShareJoin` in commands/share.ts, so there is a
|
|
12
|
-
* single source of truth for provisioning.
|
|
13
|
-
*
|
|
14
|
-
* "Typed", not "present", is load-bearing — see {@link isDirectProvisionRequest}.
|
|
15
|
-
*
|
|
16
|
-
* Idempotent: re-running shows the current endpoint and offers to reconfigure.
|
|
17
|
-
*/
|
|
18
|
-
import type { Command } from 'commander';
|
|
19
|
-
/**
|
|
20
|
-
* Interactive share setup. Returns true if the user configured (or already had)
|
|
21
|
-
* an endpoint, false if they skipped. Never throws on user cancel — callers
|
|
22
|
-
* (the `agents setup` hub) rely on that to keep the fresh-machine flow going.
|
|
23
|
-
*/
|
|
24
|
-
export declare function runShareWizard(): Promise<boolean>;
|
|
25
|
-
/** Parsed `agents artifacts setup` options — the retired `agents share setup` flag set. */
|
|
26
|
-
interface ArtifactsSetupOpts {
|
|
27
|
-
bundle: string;
|
|
28
|
-
worker: string;
|
|
29
|
-
bucket: string;
|
|
30
|
-
account?: string;
|
|
31
|
-
token?: string;
|
|
32
|
-
domain?: string;
|
|
33
|
-
analyticsToken?: string;
|
|
34
|
-
}
|
|
35
|
-
/** The provisioning flags, by their commander option-value keys. */
|
|
36
|
-
declare const PROVISION_FLAGS: readonly ["bundle", "worker", "bucket", "account", "token", "domain", "analyticsToken"];
|
|
37
|
-
/**
|
|
38
|
-
* True when the invocation named a Cloudflare endpoint detail, i.e. the caller
|
|
39
|
-
* is driving the old `agents share setup` provisioning path rather than asking
|
|
40
|
-
* for the wizard.
|
|
41
|
-
*
|
|
42
|
-
* `--bundle`/`--worker`/`--bucket` carry commander defaults, so their mere
|
|
43
|
-
* PRESENCE proves nothing — the question is whether the user typed them, which
|
|
44
|
-
* only `wasTyped` (backed by commander's `getOptionValueSource`) can answer.
|
|
45
|
-
* Reading presence alone would classify `agents artifacts setup --bundle
|
|
46
|
-
* cloudflare-work` as a wizard run and then silently provision against the
|
|
47
|
-
* DEFAULT bundle, i.e. someone else's Cloudflare account. The other four flags
|
|
48
|
-
* have no default, so presence is proof for them.
|
|
49
|
-
*/
|
|
50
|
-
export declare function isDirectProvisionRequest(opts: ArtifactsSetupOpts, wasTyped?: (flag: (typeof PROVISION_FLAGS)[number]) => boolean): boolean;
|
|
51
|
-
/** Register `agents artifacts setup` under the parent `artifacts` command. */
|
|
52
|
-
export declare function registerArtifactsSetupCommand(artifactsCmd: Command): void;
|
|
53
|
-
export {};
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `agents artifacts setup` — configure the artifact share endpoint (Cloudflare
|
|
3
|
-
* R2 + Worker) that backs `agents artifacts share`.
|
|
4
|
-
*
|
|
5
|
-
* One door, two modes, because it replaces two commands that used to be
|
|
6
|
-
* separate (RUSH-2580): the interactive wizard formerly at `agents setup share`
|
|
7
|
-
* and the flag-driven provisioner formerly at `agents share setup`. On a TTY
|
|
8
|
-
* with no provisioning flags TYPED it runs the wizard (provision or join, and
|
|
9
|
-
* offers a Worker update when an endpoint already exists); with any provisioning
|
|
10
|
-
* flag typed, or on a non-TTY, it provisions directly. Both modes call the same
|
|
11
|
-
* `runShareProvision` / `runShareJoin` in commands/share.ts, so there is a
|
|
12
|
-
* single source of truth for provisioning.
|
|
13
|
-
*
|
|
14
|
-
* "Typed", not "present", is load-bearing — see {@link isDirectProvisionRequest}.
|
|
15
|
-
*
|
|
16
|
-
* Idempotent: re-running shows the current endpoint and offers to reconfigure.
|
|
17
|
-
*/
|
|
18
|
-
import chalk from 'chalk';
|
|
19
|
-
import { DEFAULT_BUCKET_NAME, DEFAULT_CF_BUNDLE, DEFAULT_SHARE_DOMAIN, DEFAULT_WORKER_NAME, readShareConfig, } from '../lib/share/config.js';
|
|
20
|
-
import { runShareProvision, runShareJoin, runShareUpdate, shareTemplateStatus } from './share.js';
|
|
21
|
-
import { isInteractiveTerminal, isPromptCancelled } from './utils.js';
|
|
22
|
-
/**
|
|
23
|
-
* Interactive share setup. Returns true if the user configured (or already had)
|
|
24
|
-
* an endpoint, false if they skipped. Never throws on user cancel — callers
|
|
25
|
-
* (the `agents setup` hub) rely on that to keep the fresh-machine flow going.
|
|
26
|
-
*/
|
|
27
|
-
export async function runShareWizard() {
|
|
28
|
-
if (!isInteractiveTerminal()) {
|
|
29
|
-
console.error(chalk.red('The artifact share wizard needs an interactive terminal. ' +
|
|
30
|
-
'Non-interactively, use `agents artifacts setup --account <id> --token <t>` (provision) ' +
|
|
31
|
-
'or `agents artifacts share join <baseUrl> --token <t>`.'));
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
const existing = readShareConfig();
|
|
35
|
-
if (existing) {
|
|
36
|
-
console.log(chalk.dim(`Share is already configured → ${chalk.green(existing.baseUrl)}`));
|
|
37
|
-
console.log(chalk.dim(` worker ${existing.workerName} · bucket ${existing.bucketName} · account ${existing.accountId}`));
|
|
38
|
-
const templateStatus = shareTemplateStatus(existing);
|
|
39
|
-
console.log(chalk.dim(` template ${templateStatus}`));
|
|
40
|
-
const { select } = await import('@inquirer/prompts');
|
|
41
|
-
const action = await select({
|
|
42
|
-
message: 'Share is already configured. What do you want to do?',
|
|
43
|
-
choices: [
|
|
44
|
-
{ name: 'Keep as is', value: 'keep' },
|
|
45
|
-
{
|
|
46
|
-
name: 'Update the deployed Worker to the latest template',
|
|
47
|
-
value: 'update',
|
|
48
|
-
description: templateStatus === 'current'
|
|
49
|
-
? 'Already current — this re-deploys anyway and refreshes the token in place.'
|
|
50
|
-
: 'Re-deploys the Worker script on your existing endpoint (same account/worker/bucket, same write token).',
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
name: 'Reconfigure from scratch (provision or join again)',
|
|
54
|
-
value: 'reconfigure',
|
|
55
|
-
},
|
|
56
|
-
],
|
|
57
|
-
default: templateStatus === 'outdated' || templateStatus === 'unknown' ? 'update' : 'keep',
|
|
58
|
-
});
|
|
59
|
-
if (action === 'keep') {
|
|
60
|
-
console.log(chalk.dim('Keeping the current endpoint.'));
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
if (action === 'update') {
|
|
64
|
-
// When the template is already current, the description below promises a
|
|
65
|
-
// re-deploy anyway — force it, or runShareUpdate's own no-op would silently
|
|
66
|
-
// contradict what was just said.
|
|
67
|
-
const result = await runShareUpdate({ force: templateStatus === 'current' });
|
|
68
|
-
console.log(result.updated
|
|
69
|
-
? chalk.green(`Worker '${result.workerName}' updated → template ${result.templateHash.slice(0, 12)}…`)
|
|
70
|
-
: chalk.dim(`Worker '${result.workerName}' already matches the current template — no-op.`));
|
|
71
|
-
return true;
|
|
72
|
-
}
|
|
73
|
-
// action === 'reconfigure' — fall through to the provision/join flow below.
|
|
74
|
-
}
|
|
75
|
-
const { select } = await import('@inquirer/prompts');
|
|
76
|
-
const mode = await select({
|
|
77
|
-
message: 'How do you want to publish shared links?',
|
|
78
|
-
choices: [
|
|
79
|
-
{
|
|
80
|
-
name: 'Provision my own (Cloudflare R2 + Worker)',
|
|
81
|
-
value: 'provision',
|
|
82
|
-
description: 'One-time: creates a bucket + Worker on your Cloudflare account (~$0). Needs a Cloudflare API token.',
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
name: 'Join an existing endpoint (a teammate already provisioned one)',
|
|
86
|
-
value: 'join',
|
|
87
|
-
description: 'Use synced config when present, or paste the base URL + write token from the endpoint owner.',
|
|
88
|
-
},
|
|
89
|
-
],
|
|
90
|
-
});
|
|
91
|
-
if (mode === 'provision') {
|
|
92
|
-
await runShareProvision({
|
|
93
|
-
bundle: DEFAULT_CF_BUNDLE,
|
|
94
|
-
worker: DEFAULT_WORKER_NAME,
|
|
95
|
-
bucket: DEFAULT_BUCKET_NAME,
|
|
96
|
-
});
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
const { input } = await import('@inquirer/prompts');
|
|
100
|
-
const baseUrl = await input({
|
|
101
|
-
message: 'Endpoint base URL (e.g. https://share.getrush.ai)',
|
|
102
|
-
validate: (v) => (v.trim().startsWith('http') ? true : 'Enter the full https:// URL of the endpoint.'),
|
|
103
|
-
});
|
|
104
|
-
await runShareJoin(baseUrl.trim());
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
/** The provisioning flags, by their commander option-value keys. */
|
|
108
|
-
const PROVISION_FLAGS = ['bundle', 'worker', 'bucket', 'account', 'token', 'domain', 'analyticsToken'];
|
|
109
|
-
/**
|
|
110
|
-
* True when the invocation named a Cloudflare endpoint detail, i.e. the caller
|
|
111
|
-
* is driving the old `agents share setup` provisioning path rather than asking
|
|
112
|
-
* for the wizard.
|
|
113
|
-
*
|
|
114
|
-
* `--bundle`/`--worker`/`--bucket` carry commander defaults, so their mere
|
|
115
|
-
* PRESENCE proves nothing — the question is whether the user typed them, which
|
|
116
|
-
* only `wasTyped` (backed by commander's `getOptionValueSource`) can answer.
|
|
117
|
-
* Reading presence alone would classify `agents artifacts setup --bundle
|
|
118
|
-
* cloudflare-work` as a wizard run and then silently provision against the
|
|
119
|
-
* DEFAULT bundle, i.e. someone else's Cloudflare account. The other four flags
|
|
120
|
-
* have no default, so presence is proof for them.
|
|
121
|
-
*/
|
|
122
|
-
export function isDirectProvisionRequest(opts, wasTyped = () => false) {
|
|
123
|
-
if (opts.account || opts.token || opts.domain || opts.analyticsToken)
|
|
124
|
-
return true;
|
|
125
|
-
return PROVISION_FLAGS.some((flag) => wasTyped(flag));
|
|
126
|
-
}
|
|
127
|
-
/** Register `agents artifacts setup` under the parent `artifacts` command. */
|
|
128
|
-
export function registerArtifactsSetupCommand(artifactsCmd) {
|
|
129
|
-
artifactsCmd
|
|
130
|
-
.command('setup')
|
|
131
|
-
.description('Provision (or join) the Cloudflare R2 + Worker endpoint that backs `agents artifacts share`.')
|
|
132
|
-
.option('--bundle <name>', 'secrets bundle holding the Cloudflare API token', DEFAULT_CF_BUNDLE)
|
|
133
|
-
.option('--worker <name>', 'Worker name', DEFAULT_WORKER_NAME)
|
|
134
|
-
.option('--bucket <name>', 'R2 bucket name', DEFAULT_BUCKET_NAME)
|
|
135
|
-
.option('--account <id>', 'Cloudflare account id (else read from the bundle / prompt)')
|
|
136
|
-
.option('--token <t>', 'Cloudflare API token (else read from the --bundle)')
|
|
137
|
-
.option('--domain <host>', `custom domain to map (default: ${DEFAULT_SHARE_DOMAIN}; workers.dev if zone is not visible)`)
|
|
138
|
-
.option('--analytics-token <token>', 'Cloudflare Web Analytics token to inject into published HTML pages')
|
|
139
|
-
.action(async (opts, cmd) => {
|
|
140
|
-
try {
|
|
141
|
-
// Named endpoint details, or no terminal to prompt on, means provision
|
|
142
|
-
// directly — the wizard has nothing to ask that was not already given,
|
|
143
|
-
// and it would provision against its own hardcoded defaults, dropping
|
|
144
|
-
// whatever the caller named.
|
|
145
|
-
const wasTyped = (flag) => cmd.getOptionValueSource(flag) === 'cli';
|
|
146
|
-
if (isDirectProvisionRequest(opts, wasTyped) || !isInteractiveTerminal()) {
|
|
147
|
-
await runShareProvision(opts);
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
await runShareWizard();
|
|
151
|
-
}
|
|
152
|
-
catch (err) {
|
|
153
|
-
if (isPromptCancelled(err)) {
|
|
154
|
-
console.log(chalk.yellow('\nCancelled'));
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
console.error(chalk.red(err.message));
|
|
158
|
-
process.exitCode = 1;
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `agents artifacts` — the group that owns everything an agent publishes for a
|
|
3
|
-
* human to open: HTML plans, reports, rendered visuals, screenshots.
|
|
4
|
-
*
|
|
5
|
-
* RUSH-2580 nested the former top-level `agents share` here. `artifacts` is the
|
|
6
|
-
* noun, `share` is the action on it, so the surface reads noun-then-action like
|
|
7
|
-
* the rest of the CLI:
|
|
8
|
-
*
|
|
9
|
-
* agents artifacts share <file> publish
|
|
10
|
-
* agents artifacts share list|delete|analytics|join|status|update
|
|
11
|
-
* agents artifacts setup provision (or join) the endpoint
|
|
12
|
-
*
|
|
13
|
-
* The subtree itself lives in commands/share.ts (publish + its subcommands) and
|
|
14
|
-
* commands/artifacts-setup.ts (the provisioning door); this module only assembles
|
|
15
|
-
* the group, so there is one place that says what `agents artifacts` contains.
|
|
16
|
-
*/
|
|
17
|
-
import type { Command } from 'commander';
|
|
18
|
-
export declare function registerArtifactsCommands(program: Command): void;
|