@phnx-labs/agents-cli 1.22.114 → 1.22.116
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 +245 -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 +210 -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 +214 -148
- package/dist/commands/feed-watch.js +52 -8
- package/dist/commands/feed.js +65 -14
- 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-picker.d.ts +11 -0
- package/dist/commands/sessions-picker.js +88 -7
- 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.d.ts +21 -2
- package/dist/commands/sessions.js +158 -11
- package/dist/commands/setup-browser.js +18 -2
- package/dist/commands/setup-computer.js +20 -6
- package/dist/commands/setup-secrets.d.ts +2 -2
- package/dist/commands/setup-secrets.js +24 -4
- package/dist/commands/setup-term.d.ts +24 -0
- package/dist/commands/setup-term.js +70 -0
- 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 +29 -11
- package/dist/commands/skills.js +0 -8
- package/dist/commands/ssh.d.ts +6 -0
- package/dist/commands/ssh.js +93 -302
- package/dist/commands/sync.js +14 -5
- package/dist/commands/teams.js +1 -1
- package/dist/commands/traces.js +1 -1
- package/dist/lib/accounting/rotate.d.ts +63 -1
- package/dist/lib/accounting/rotate.js +56 -0
- package/dist/lib/accounts/add.d.ts +0 -5
- package/dist/lib/accounts/add.js +3 -9
- package/dist/lib/accounts/slots.js +32 -2
- package/dist/lib/answer-router.d.ts +11 -2
- package/dist/lib/answer-router.js +26 -2
- package/dist/lib/artifacts-client.d.ts +20 -0
- package/dist/lib/artifacts-client.js +46 -0
- package/dist/lib/auth-mint.d.ts +5 -4
- package/dist/lib/auth-mint.js +6 -5
- package/dist/lib/browser/drivers/arc.d.ts +1 -1
- package/dist/lib/browser/runtime-state.d.ts +55 -0
- package/dist/lib/browser/runtime-state.js +99 -18
- package/dist/lib/browser/service.d.ts +10 -0
- package/dist/lib/browser/service.js +229 -37
- package/dist/lib/browser/types.d.ts +18 -0
- 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/config-keys.d.ts +1 -1
- package/dist/lib/config-keys.js +5 -0
- 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/device-config.js +61 -0
- package/dist/lib/devices/connect.d.ts +49 -5
- package/dist/lib/devices/connect.js +169 -21
- package/dist/lib/devices/doctor-findings.js +2 -6
- package/dist/lib/feed/answer.d.ts +153 -4
- package/dist/lib/feed/answer.js +716 -105
- 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/feed.d.ts +61 -1
- package/dist/lib/feed/feed.js +226 -14
- package/dist/lib/feed/hub-server.d.ts +141 -0
- package/dist/lib/feed/hub-server.js +586 -0
- package/dist/lib/feed/hub.d.ts +95 -0
- package/dist/lib/feed/hub.js +255 -0
- package/dist/lib/feed/pr-status.d.ts +8 -0
- package/dist/lib/feed/pr-status.js +9 -1
- 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/feed-outcome.d.ts +1 -1
- package/dist/lib/feed-outcome.js +9 -2
- package/dist/lib/feed-policy.js +9 -3
- package/dist/lib/fleet/auth-sync.d.ts +2 -55
- package/dist/lib/fleet/auth-sync.js +2 -89
- 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/harness-auth-capabilities.js +7 -2
- package/dist/lib/helper-versions.js +1 -1
- package/dist/lib/hosts/dispatch.d.ts +20 -1
- package/dist/lib/hosts/dispatch.js +52 -30
- package/dist/lib/hosts/remote-cmd.d.ts +72 -1
- package/dist/lib/hosts/remote-cmd.js +151 -10
- 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/mailbox.d.ts +12 -0
- package/dist/lib/mailbox.js +16 -2
- package/dist/lib/mcp.js +17 -11
- package/dist/lib/menubar/snapshot.d.ts +51 -0
- package/dist/lib/menubar/snapshot.js +42 -3
- package/dist/lib/open-url.js +2 -2
- package/dist/lib/probe.d.ts +4 -1
- package/dist/lib/probe.js +5 -2
- package/dist/lib/projects.d.ts +23 -0
- package/dist/lib/projects.js +78 -0
- 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/active.d.ts +1 -0
- package/dist/lib/session/active.js +8 -0
- package/dist/lib/session/db.d.ts +67 -3
- package/dist/lib/session/db.js +381 -126
- package/dist/lib/session/detached.d.ts +7 -0
- package/dist/lib/session/detached.js +29 -0
- package/dist/lib/session/prompt.d.ts +23 -7
- package/dist/lib/session/prompt.js +46 -8
- 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/remote/remote-list.d.ts +20 -0
- package/dist/lib/session/remote/remote-list.js +22 -6
- package/dist/lib/session/remote/watch.d.ts +12 -0
- package/dist/lib/session/remote/watch.js +9 -0
- package/dist/lib/session/remote-preview-cache.d.ts +29 -0
- package/dist/lib/session/remote-preview-cache.js +373 -0
- 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/session/tail.d.ts +50 -0
- package/dist/lib/session/tail.js +219 -0
- 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 +27 -0
- package/dist/lib/setup-tool-status.d.ts +22 -0
- package/dist/lib/setup-tool-status.js +220 -0
- package/dist/lib/share-runtime.d.ts +11 -0
- package/dist/lib/share-runtime.js +63 -0
- package/dist/lib/signin-badge.d.ts +19 -4
- package/dist/lib/signin-badge.js +29 -11
- 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/term-driver.d.ts +24 -0
- package/dist/lib/term-driver.js +36 -0
- package/dist/lib/terminal/index.d.ts +1 -1
- package/dist/lib/terminal/index.js +1 -1
- package/dist/lib/terminal/inject.d.ts +38 -0
- package/dist/lib/terminal/inject.js +55 -9
- package/dist/lib/terminal/transport.d.ts +15 -5
- package/dist/lib/terminal/transport.js +61 -11
- 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/fleet/remote-login.d.ts +0 -170
- package/dist/lib/fleet/remote-login.js +0 -568
- 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
|
@@ -53,6 +53,24 @@ function backendConfirmsDelivery(backend) {
|
|
|
53
53
|
}
|
|
54
54
|
/** Carriage return — what Enter delivers into a raw PTY/tmux byte stream. */
|
|
55
55
|
const CR = '\r';
|
|
56
|
+
/**
|
|
57
|
+
* Bracketed-paste framing (DEC mode 2004) — the pty contract for "insert this
|
|
58
|
+
* verbatim, do not submit". A readline/Ink composer that sees the start marker
|
|
59
|
+
* buffers every byte up to the end marker, so an embedded newline lands as a
|
|
60
|
+
* literal newline in the draft instead of submitting the partial line.
|
|
61
|
+
*/
|
|
62
|
+
export const BRACKETED_PASTE_START = '\u001b[200~';
|
|
63
|
+
export const BRACKETED_PASTE_END = '\u001b[201~';
|
|
64
|
+
/**
|
|
65
|
+
* Only tmux can carry the framing: `send-keys -l` writes the marker bytes
|
|
66
|
+
* straight to the pty. ghostty simulates keystrokes, vscodium hands a JSON
|
|
67
|
+
* payload to the extension, and iTerm's AppleScript `write text` cannot encode
|
|
68
|
+
* a raw ESC byte — so a paste request on those is refused rather than
|
|
69
|
+
* half-delivered as one submit per line.
|
|
70
|
+
*/
|
|
71
|
+
export function backendCarriesPaste(backend) {
|
|
72
|
+
return backend === 'tmux';
|
|
73
|
+
}
|
|
56
74
|
// --- tmux -------------------------------------------------------------------
|
|
57
75
|
/**
|
|
58
76
|
* argv for `tmux send-keys` targeting a pane by id. Starts with `tmux` (like the
|
|
@@ -191,12 +209,21 @@ export function vscodiumInjectSpec(target, text, opts) {
|
|
|
191
209
|
export async function injectIntoTerminal(target, text, opts = {}) {
|
|
192
210
|
const enter = opts.enter !== false;
|
|
193
211
|
const combined = opts.combined === true;
|
|
212
|
+
// Fail loud at the rail boundary: a backend that cannot carry the markers must
|
|
213
|
+
// not silently deliver the raw text, which submits once per embedded newline.
|
|
214
|
+
if (opts.paste === true && !backendCarriesPaste(target.backend)) {
|
|
215
|
+
return {
|
|
216
|
+
ok: false, confirmed: false, backend: target.backend, writes: 0, started: 0, specs: [],
|
|
217
|
+
error: `The ${target.backend} rail cannot deliver a bracketed paste — open the session and paste it there.`,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
const payload = opts.paste === true ? `${BRACKETED_PASTE_START}${text}${BRACKETED_PASTE_END}` : text;
|
|
194
221
|
// tmux + AppleScript + editor-CLI backends all run through the engine transport.
|
|
195
222
|
const specs = target.backend === 'tmux'
|
|
196
|
-
? tmuxInjectSpecs(target,
|
|
223
|
+
? tmuxInjectSpecs(target, payload, { enter, combined, socket: opts.socket })
|
|
197
224
|
: target.backend === 'vscodium'
|
|
198
|
-
? [vscodiumInjectSpec(target,
|
|
199
|
-
: [appleScriptInjectSpec(target,
|
|
225
|
+
? [vscodiumInjectSpec(target, payload, { enter, combined })]
|
|
226
|
+
: [appleScriptInjectSpec(target, payload, enter, combined)];
|
|
200
227
|
// Discrete writes delivered on the far side. tmux counts its send-keys calls.
|
|
201
228
|
// iterm/vscodium honor `combined` (text+Enter fused into one write). ghostty's
|
|
202
229
|
// coarse keystroke path ignores `combined` (it always emits keystroke + a
|
|
@@ -208,7 +235,7 @@ export async function injectIntoTerminal(target, text, opts = {}) {
|
|
|
208
235
|
: enter && !combined ? 2 : 1;
|
|
209
236
|
const confirmed = backendConfirmsDelivery(target.backend);
|
|
210
237
|
if (opts.dryRun)
|
|
211
|
-
return { ok: true, confirmed, backend: target.backend, writes, specs };
|
|
238
|
+
return { ok: true, confirmed, backend: target.backend, writes, started: 0, specs };
|
|
212
239
|
// AppleScript backends: guard on the backend's own availability, but only for a
|
|
213
240
|
// LOCAL run (a remote host is assumed to have the app — its ssh leg reports failure).
|
|
214
241
|
if (target.backend === 'iterm' || target.backend === 'ghostty') {
|
|
@@ -216,14 +243,33 @@ export async function injectIntoTerminal(target, text, opts = {}) {
|
|
|
216
243
|
const backend = target.backend === 'iterm' ? itermBackend : ghosttyBackend;
|
|
217
244
|
const ctx = opts.ctx ?? currentContext();
|
|
218
245
|
if (!backend.isAvailable(ctx)) {
|
|
219
|
-
return { ok: false, confirmed: false, backend: target.backend, writes: 0, specs, error: `${backend.label} is not available here (platform ${ctx.platform})` };
|
|
246
|
+
return { ok: false, confirmed: false, backend: target.backend, writes: 0, started: 0, specs, error: `${backend.label} is not available here (platform ${ctx.platform})` };
|
|
220
247
|
}
|
|
221
248
|
}
|
|
222
249
|
}
|
|
250
|
+
const endMs = opts.deadlineMs === undefined ? undefined : Date.now() + opts.deadlineMs;
|
|
251
|
+
let sent = 0;
|
|
252
|
+
let started = 0;
|
|
223
253
|
for (const spec of specs) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
254
|
+
// Never START a spec the budget can no longer cover. Racing the caller's
|
|
255
|
+
// promise instead let a write begin AFTER the operator had already been told
|
|
256
|
+
// the answer timed out.
|
|
257
|
+
const remaining = endMs === undefined ? undefined : endMs - Date.now();
|
|
258
|
+
if (remaining !== undefined && remaining <= 0) {
|
|
259
|
+
return {
|
|
260
|
+
ok: false, confirmed: false, backend: target.backend, writes: sent, started, specs,
|
|
261
|
+
error: `injection ran out of budget after ${sent} of ${specs.length} write(s)`,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
started += 1;
|
|
265
|
+
const res = await runSpec(spec, opts.host, opts.resolveHost, remaining);
|
|
266
|
+
if (!res.ok) {
|
|
267
|
+
// `writes` counts specs that COMPLETED; `started` counts specs that began.
|
|
268
|
+
// The failing spec may have written bytes before dying, so the caller must
|
|
269
|
+
// branch on `started`, not on `writes`.
|
|
270
|
+
return { ok: false, confirmed: false, backend: target.backend, writes: sent, started, specs, error: res.error };
|
|
271
|
+
}
|
|
272
|
+
sent += 1;
|
|
227
273
|
}
|
|
228
|
-
return { ok: true, confirmed, backend: target.backend, writes, specs };
|
|
274
|
+
return { ok: true, confirmed, backend: target.backend, writes, started, specs };
|
|
229
275
|
}
|
|
@@ -5,11 +5,21 @@ export interface RunResult {
|
|
|
5
5
|
ok: boolean;
|
|
6
6
|
error?: string;
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
9
|
-
export declare
|
|
8
|
+
/** Grace between SIGTERM and SIGKILL when a deadline cancels a launcher. */
|
|
9
|
+
export declare const SPEC_KILL_GRACE_MS = 250;
|
|
10
|
+
/**
|
|
11
|
+
* Run the spec on this machine: spawn the launcher, resolve when it exits.
|
|
12
|
+
*
|
|
13
|
+
* `timeoutMs` makes the call genuinely bounded rather than merely raced: the
|
|
14
|
+
* child is spawned in its OWN process group (`detached`) and the whole group is
|
|
15
|
+
* signalled on expiry, so a launcher that itself spawned something (osascript →
|
|
16
|
+
* the app, tmux → the server) cannot keep running after the caller has given up.
|
|
17
|
+
* Racing the promise alone leaves the process behind (PHNX-3999).
|
|
18
|
+
*/
|
|
19
|
+
export declare function runLocal(spec: LaunchSpec, timeoutMs?: number): Promise<RunResult>;
|
|
10
20
|
/** Serialize a launch argv into a single POSIX-quoted shell command string. */
|
|
11
21
|
export declare function remoteCommand(spec: LaunchSpec): string;
|
|
12
|
-
/** Run the spec on a remote host over SSH. */
|
|
13
|
-
export declare function runRemote(spec: LaunchSpec, target: string): RunResult;
|
|
22
|
+
/** Run the spec on a remote host over SSH. `timeoutMs` bounds the ssh client. */
|
|
23
|
+
export declare function runRemote(spec: LaunchSpec, target: string, timeoutMs?: number): RunResult;
|
|
14
24
|
/** Run a spec locally (no host / 'local') or on a resolved remote host. */
|
|
15
|
-
export declare function runSpec(spec: LaunchSpec, host?: string, resolveHost?: HostResolver): Promise<RunResult>;
|
|
25
|
+
export declare function runSpec(spec: LaunchSpec, host?: string, resolveHost?: HostResolver, timeoutMs?: number): Promise<RunResult>;
|
|
@@ -11,30 +11,80 @@
|
|
|
11
11
|
import { spawn } from 'child_process';
|
|
12
12
|
import { sshExec } from '../ssh-exec.js';
|
|
13
13
|
import { shellQuote } from './quote.js';
|
|
14
|
-
/**
|
|
15
|
-
export
|
|
14
|
+
/** Grace between SIGTERM and SIGKILL when a deadline cancels a launcher. */
|
|
15
|
+
export const SPEC_KILL_GRACE_MS = 250;
|
|
16
|
+
/**
|
|
17
|
+
* Run the spec on this machine: spawn the launcher, resolve when it exits.
|
|
18
|
+
*
|
|
19
|
+
* `timeoutMs` makes the call genuinely bounded rather than merely raced: the
|
|
20
|
+
* child is spawned in its OWN process group (`detached`) and the whole group is
|
|
21
|
+
* signalled on expiry, so a launcher that itself spawned something (osascript →
|
|
22
|
+
* the app, tmux → the server) cannot keep running after the caller has given up.
|
|
23
|
+
* Racing the promise alone leaves the process behind (PHNX-3999).
|
|
24
|
+
*/
|
|
25
|
+
export function runLocal(spec, timeoutMs) {
|
|
16
26
|
return new Promise((resolve) => {
|
|
17
|
-
const child = spawn(spec.argv[0], spec.argv.slice(1), { stdio: 'ignore' });
|
|
18
|
-
|
|
19
|
-
|
|
27
|
+
const child = spawn(spec.argv[0], spec.argv.slice(1), { stdio: 'ignore', detached: !!timeoutMs });
|
|
28
|
+
let settled = false;
|
|
29
|
+
let killTimer = null;
|
|
30
|
+
// NOTE: the pending SIGKILL is deliberately NOT cancelled here. Resolving
|
|
31
|
+
// the promise is the CALLER giving up; it is not the child exiting. Clearing
|
|
32
|
+
// the kill timer on the timeout path (which resolves immediately after
|
|
33
|
+
// arming it) meant a SIGTERM-ignoring child was never killed and simply
|
|
34
|
+
// survived the bound this function exists to enforce.
|
|
35
|
+
const done = (result) => {
|
|
36
|
+
if (settled)
|
|
37
|
+
return;
|
|
38
|
+
settled = true;
|
|
39
|
+
if (timer)
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
resolve(result);
|
|
42
|
+
};
|
|
43
|
+
const signalGroup = (signal) => {
|
|
44
|
+
try {
|
|
45
|
+
if (child.pid)
|
|
46
|
+
process.kill(timeoutMs ? -child.pid : child.pid, signal);
|
|
47
|
+
}
|
|
48
|
+
catch { /* already gone */ }
|
|
49
|
+
};
|
|
50
|
+
const timer = timeoutMs
|
|
51
|
+
? setTimeout(() => {
|
|
52
|
+
signalGroup('SIGTERM');
|
|
53
|
+
killTimer = setTimeout(() => signalGroup('SIGKILL'), SPEC_KILL_GRACE_MS);
|
|
54
|
+
killTimer.unref?.();
|
|
55
|
+
done({ ok: false, error: `${spec.argv[0]} did not finish in ${timeoutMs}ms` });
|
|
56
|
+
}, timeoutMs)
|
|
57
|
+
: null;
|
|
58
|
+
// Only the child ACTUALLY exiting retires the pending SIGKILL.
|
|
59
|
+
const childGone = () => { if (killTimer) {
|
|
60
|
+
clearTimeout(killTimer);
|
|
61
|
+
killTimer = null;
|
|
62
|
+
} };
|
|
63
|
+
child.on('error', (err) => { childGone(); done({ ok: false, error: err.message }); });
|
|
64
|
+
child.on('close', (code) => {
|
|
65
|
+
childGone();
|
|
66
|
+
done(code === 0 ? { ok: true } : { ok: false, error: `${spec.argv[0]} exited with code ${code}` });
|
|
67
|
+
});
|
|
20
68
|
});
|
|
21
69
|
}
|
|
22
70
|
/** Serialize a launch argv into a single POSIX-quoted shell command string. */
|
|
23
71
|
export function remoteCommand(spec) {
|
|
24
72
|
return spec.argv.map(shellQuote).join(' ');
|
|
25
73
|
}
|
|
26
|
-
/** Run the spec on a remote host over SSH. */
|
|
27
|
-
export function runRemote(spec, target) {
|
|
28
|
-
const res = sshExec(target, remoteCommand(spec), { multiplex:
|
|
74
|
+
/** Run the spec on a remote host over SSH. `timeoutMs` bounds the ssh client. */
|
|
75
|
+
export function runRemote(spec, target, timeoutMs) {
|
|
76
|
+
const res = sshExec(target, remoteCommand(spec), { multiplex: !timeoutMs, timeoutMs });
|
|
77
|
+
if (res.timedOut)
|
|
78
|
+
return { ok: false, error: `ssh to ${target} did not finish in ${timeoutMs}ms` };
|
|
29
79
|
if (res.code === 0)
|
|
30
80
|
return { ok: true };
|
|
31
81
|
const err = (res.stderr || '').trim();
|
|
32
82
|
return { ok: false, error: err || `ssh exited with code ${res.code}` };
|
|
33
83
|
}
|
|
34
84
|
/** Run a spec locally (no host / 'local') or on a resolved remote host. */
|
|
35
|
-
export async function runSpec(spec, host, resolveHost) {
|
|
85
|
+
export async function runSpec(spec, host, resolveHost, timeoutMs) {
|
|
36
86
|
if (!host || host === 'local')
|
|
37
|
-
return runLocal(spec);
|
|
87
|
+
return runLocal(spec, timeoutMs);
|
|
38
88
|
const target = resolveHost ? resolveHost(host) : host;
|
|
39
|
-
return runRemote(spec, target);
|
|
89
|
+
return runRemote(spec, target, timeoutMs);
|
|
40
90
|
}
|
|
@@ -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.116",
|
|
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;
|
|
@@ -1,58 +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 { setHelpSections } from '../lib/help.js';
|
|
18
|
-
import { registerShareCommands, registerUnshareCommand } from './share.js';
|
|
19
|
-
import { registerArtifactsSetupCommand } from './artifacts-setup.js';
|
|
20
|
-
export function registerArtifactsCommands(program) {
|
|
21
|
-
const artifactsCmd = program
|
|
22
|
-
.command('artifacts')
|
|
23
|
-
.description('Publish agent-made artifacts (plans, reports, visuals) to a shareable link — managed if signed in, otherwise your Cloudflare R2.');
|
|
24
|
-
registerArtifactsSetupCommand(artifactsCmd);
|
|
25
|
-
registerShareCommands(artifactsCmd);
|
|
26
|
-
setHelpSections(artifactsCmd, {
|
|
27
|
-
examples: `
|
|
28
|
-
# Signed in? Just publish — no Cloudflare setup
|
|
29
|
-
agents auth login
|
|
30
|
-
agents artifacts share ./out/plan.html
|
|
31
|
-
|
|
32
|
-
# Or provision your own Cloudflare endpoint (or join a teammate's)
|
|
33
|
-
agents artifacts setup
|
|
34
|
-
agents artifacts share join https://share.getrush.ai
|
|
35
|
-
|
|
36
|
-
# What's live in your namespace, and taking one down
|
|
37
|
-
agents artifacts share list
|
|
38
|
-
agents artifacts unshare my-plan-a1b2
|
|
39
|
-
|
|
40
|
-
# Endpoint health, and pushing a new Worker template to it
|
|
41
|
-
agents artifacts share status
|
|
42
|
-
agents artifacts share update
|
|
43
|
-
`,
|
|
44
|
-
notes: `
|
|
45
|
-
agents artifacts share is the publish action; agents artifacts setup is the
|
|
46
|
-
one-time endpoint provisioning. It runs the interactive wizard only when you
|
|
47
|
-
type NO endpoint flag on a TTY; type any of --bundle/--worker/--bucket/
|
|
48
|
-
--account/--token/--domain/--analytics-token, or run non-interactively, and it
|
|
49
|
-
provisions directly with what you named.
|
|
50
|
-
|
|
51
|
-
agents artifacts unshare <targets...> is the nested alias of
|
|
52
|
-
agents artifacts share delete. Top-level \`agents unshare\` is gone.
|
|
53
|
-
|
|
54
|
-
Architecture: cli/docs/observability.md.
|
|
55
|
-
`,
|
|
56
|
-
});
|
|
57
|
-
registerUnshareCommand(artifactsCmd);
|
|
58
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `agents sessions attach <id>` — bring a backgrounded (or parked) agent session
|
|
3
|
-
* back to the foreground: stop its headless continuation, then resume it
|
|
4
|
-
* interactively in this terminal. The resume is version-pinned native resume
|
|
5
|
-
* (claude/codex) or a `/continue` replay (others) — the same session, full
|
|
6
|
-
* history, the exact inverse of `agents sessions detach`.
|
|
7
|
-
*/
|
|
8
|
-
import type { Command } from 'commander';
|
|
9
|
-
import type { SessionMeta } from '../lib/session/types.js';
|
|
10
|
-
export declare function registerAttachCommand(program: Command): void;
|
|
11
|
-
export declare function attachAction(id: string): Promise<void>;
|
|
12
|
-
export declare function attachRecoveryArgs(session: Pick<SessionMeta, 'id'>): string[];
|