@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
|
@@ -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[];
|
package/dist/commands/attach.js
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { runOnPeer } from '../lib/session/remote-list.js';
|
|
3
|
-
import { sessionRecoveryPeer } from '../lib/session/recovery.js';
|
|
4
|
-
import { resolveSessionMetadataValue, resumeSessionInPlace } from './sessions.js';
|
|
5
|
-
import { readDetachRecord, clearDetachRecord, isHeadlessAlive } from '../lib/session/detached.js';
|
|
6
|
-
import { attachLocalLiveSelector } from '../lib/session/local-tmux-attach.js';
|
|
7
|
-
export function registerAttachCommand(program) {
|
|
8
|
-
// Deprecated: superseded by `agents sessions resume`, which detects the state
|
|
9
|
-
// (live pane / headless / ended) instead of making the caller pick a verb.
|
|
10
|
-
// Hidden from help; kept as a warned, functional alias for one release so old
|
|
11
|
-
// muscle-memory and scripts don't break.
|
|
12
|
-
program
|
|
13
|
-
.command('attach', { hidden: true })
|
|
14
|
-
.argument('<id>', 'Short or full id of the backgrounded/parked session to resume interactively')
|
|
15
|
-
.description('Deprecated — use `agents sessions resume <id>` instead.')
|
|
16
|
-
.action(async (id) => {
|
|
17
|
-
console.warn(chalk.yellow('`agents sessions attach` is deprecated — use `agents sessions resume` instead:'));
|
|
18
|
-
console.warn(chalk.gray(` agents sessions resume ${id}`));
|
|
19
|
-
await attachAction(id);
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
export async function attachAction(id) {
|
|
23
|
-
// PHNX-3292: this deprecated spelling still gets the local-pane fast path —
|
|
24
|
-
// a live tmux alias/short id on THIS box attaches with zero SSH, matching
|
|
25
|
-
// `sessions resume`. `attach` takes no `--device`, so hosts is always empty.
|
|
26
|
-
if (await attachLocalLiveSelector(id.trim(), [])) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
const outcome = await resolveSessionMetadataValue(id);
|
|
30
|
-
if (outcome.kind === 'partial') {
|
|
31
|
-
// RUSH-2492: an unreachable peer is a warning, not a hard failure. The
|
|
32
|
-
// resolver already resolves an id found on the reachable fleet (SES-9a), so
|
|
33
|
-
// reaching here means the session was not found on any device we COULD reach
|
|
34
|
-
// — it may live on one of the unreachable peers, which we could not check.
|
|
35
|
-
const offline = outcome.failedPeers;
|
|
36
|
-
console.error(chalk.yellow(`Warning: ${offline.length} device(s) unreachable, not checked: ${offline.join(', ')}`));
|
|
37
|
-
console.error(chalk.red(`No session matching "${id}" on any reachable device (${offline.length} unreachable, not checked).`));
|
|
38
|
-
console.error(chalk.gray(' If it lives on an offline box, wake it (agents devices) or run there: agents ssh <device>'));
|
|
39
|
-
process.exitCode = 1;
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
if (outcome.kind === 'not-found') {
|
|
43
|
-
console.error(chalk.red(`No session matching "${id}".`));
|
|
44
|
-
console.error(chalk.gray(' See your sessions: agents sessions'));
|
|
45
|
-
process.exitCode = 1;
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
if (outcome.kind === 'ambiguous') {
|
|
49
|
-
console.error(chalk.red(`"${id}" matches ${outcome.candidates.length} sessions. Pass the full session id.`));
|
|
50
|
-
process.exitCode = 1;
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const meta = outcome.session;
|
|
54
|
-
// Route the WHOLE attach operation to the origin, not just its eventual
|
|
55
|
-
// resume. The detach record and headless PID are device-local; clearing them
|
|
56
|
-
// here would leave the real background continuation running beside a second
|
|
57
|
-
// process on the owning machine.
|
|
58
|
-
const peer = sessionRecoveryPeer(meta);
|
|
59
|
-
if (peer) {
|
|
60
|
-
const routed = await runOnPeer(attachRecoveryArgs(meta), peer, { tty: true, sessionId: meta.id });
|
|
61
|
-
if (routed === 'no-target') {
|
|
62
|
-
console.error(chalk.red(`Cannot attach ${meta.shortId}: origin device ${peer} is not a registered reachable peer.`));
|
|
63
|
-
process.exitCode = 1;
|
|
64
|
-
}
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
// If it's backgrounded, stop the headless continuation first so two processes
|
|
68
|
-
// don't resume the same transcript at once.
|
|
69
|
-
const rec = readDetachRecord(meta.id);
|
|
70
|
-
if (rec) {
|
|
71
|
-
if (isHeadlessAlive(rec)) {
|
|
72
|
-
try {
|
|
73
|
-
process.kill(rec.headlessPid, 'SIGTERM');
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
/* already gone */
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
clearDetachRecord(meta.id);
|
|
80
|
-
}
|
|
81
|
-
console.log(chalk.gray(`Attaching ${meta.agent} ${meta.id.slice(0, 8)} — resuming interactively…`));
|
|
82
|
-
await resumeSessionInPlace(meta);
|
|
83
|
-
}
|
|
84
|
-
export function attachRecoveryArgs(session) {
|
|
85
|
-
return ['sessions', 'attach', session.id];
|
|
86
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared `mint` subcommand registered on both `agents auth` (the ticket
|
|
3
|
-
* surface) and `agents accounts` (the credential noun). Hidden on both:
|
|
4
|
-
* `agents accounts add <harness> [name]` / `agents accounts login <harness>#<name>`
|
|
5
|
-
* is the taught path. Implementation lives in lib/auth-mint.ts so neither
|
|
6
|
-
* command file owns the seed path.
|
|
7
|
-
*/
|
|
8
|
-
import type { Command } from 'commander';
|
|
9
|
-
import { type MintDriveHooks } from '../lib/auth-mint.js';
|
|
10
|
-
export declare function registerMintCommand(parent: Command, testHooks?: MintDriveHooks, opts?: {
|
|
11
|
-
hidden?: boolean;
|
|
12
|
-
}): Command;
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared `mint` subcommand registered on both `agents auth` (the ticket
|
|
3
|
-
* surface) and `agents accounts` (the credential noun). Hidden on both:
|
|
4
|
-
* `agents accounts add <harness> [name]` / `agents accounts login <harness>#<name>`
|
|
5
|
-
* is the taught path. Implementation lives in lib/auth-mint.ts so neither
|
|
6
|
-
* command file owns the seed path.
|
|
7
|
-
*/
|
|
8
|
-
import chalk from 'chalk';
|
|
9
|
-
import { setHelpSections } from '../lib/help.js';
|
|
10
|
-
import { readStdinSync, runOrDie } from '../lib/format.js';
|
|
11
|
-
import { isInteractiveTerminal } from './utils.js';
|
|
12
|
-
import { getMintFlow, listMintableHarnesses, mintAndSeed, } from '../lib/auth-mint.js';
|
|
13
|
-
const MINT_POINTER = 'agents accounts add <harness> [name] / agents accounts login <harness>#<name>';
|
|
14
|
-
function collect(value, previous) {
|
|
15
|
-
return [...previous, value];
|
|
16
|
-
}
|
|
17
|
-
function printResult(result, json) {
|
|
18
|
-
if (json) {
|
|
19
|
-
console.log(JSON.stringify({
|
|
20
|
-
harness: result.harness,
|
|
21
|
-
account: result.account,
|
|
22
|
-
email: result.email,
|
|
23
|
-
authBundleKey: result.authBundleKey,
|
|
24
|
-
rotated: result.rotated,
|
|
25
|
-
fleet: result.fleet,
|
|
26
|
-
}, null, 2));
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
const verb = result.rotated ? 'Rotated' : 'Minted';
|
|
30
|
-
console.log(chalk.green(`${verb} ${result.harness} setup-token for ${result.email} into account '${result.account}' and reserved auth bundle key ${result.authBundleKey}.`));
|
|
31
|
-
console.log(chalk.gray('The token is never printed. Native OAuth was not copied.'));
|
|
32
|
-
console.log(chalk.gray(`Run: agents run ${result.harness} --account ${result.account}`));
|
|
33
|
-
if (result.fleet.length) {
|
|
34
|
-
for (const row of result.fleet) {
|
|
35
|
-
console.log(chalk.green(` synced ${row.device} (${row.message})`));
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
export function registerMintCommand(parent, testHooks, opts) {
|
|
40
|
-
const hidden = opts?.hidden ?? true;
|
|
41
|
-
const mint = parent
|
|
42
|
-
.command('mint <harness>', { hidden })
|
|
43
|
-
.description('Mint a long-lived setup-token and seed it as a named account')
|
|
44
|
-
.option('--account <name-or-email>', 'Named account to create/rotate, or the account email')
|
|
45
|
-
.option('--email <email>', 'Email that keys the reserved auth bundle when --account is a name')
|
|
46
|
-
.option('--token-stdin', 'Seed an already-minted token from stdin (skip the PTY drive)')
|
|
47
|
-
.option('--code <code>', 'Authorization code to paste into the setup-token prompt')
|
|
48
|
-
.option('--no-open', 'Print the authorize URL instead of opening a browser')
|
|
49
|
-
.option('--fleet', 'Sync the minted account and reserved auth bundle to every other registered device')
|
|
50
|
-
.option('--device <name>', 'Sync to this device (repeatable)', collect, [])
|
|
51
|
-
.option('--json', 'Machine-readable result (never includes the token)')
|
|
52
|
-
.action((harness, o, command) => {
|
|
53
|
-
const json = !!o.json || !!command.optsWithGlobals().json;
|
|
54
|
-
return runOrDie(async () => {
|
|
55
|
-
getMintFlow(harness);
|
|
56
|
-
let token;
|
|
57
|
-
if (o.tokenStdin) {
|
|
58
|
-
token = readStdinSync();
|
|
59
|
-
if (!token)
|
|
60
|
-
throw new Error('No value received on stdin. Pass the setup-token on stdin with --token-stdin.');
|
|
61
|
-
}
|
|
62
|
-
else if (!isInteractiveTerminal() && !o.code) {
|
|
63
|
-
throw new Error(`Minting ${harness} interactively needs a TTY (or --token-stdin / --code). Supported harnesses: ${listMintableHarnesses().join(', ')}.`);
|
|
64
|
-
}
|
|
65
|
-
const result = await mintAndSeed({
|
|
66
|
-
harness,
|
|
67
|
-
account: o.account,
|
|
68
|
-
email: o.email,
|
|
69
|
-
token,
|
|
70
|
-
code: o.code,
|
|
71
|
-
open: o.open,
|
|
72
|
-
fleet: o.fleet,
|
|
73
|
-
devices: o.device,
|
|
74
|
-
json,
|
|
75
|
-
hooks: {
|
|
76
|
-
...testHooks,
|
|
77
|
-
...(o.tokenStdin || o.code || !isInteractiveTerminal()
|
|
78
|
-
? {}
|
|
79
|
-
: {
|
|
80
|
-
readCode: async () => {
|
|
81
|
-
const { input } = await import('@inquirer/prompts');
|
|
82
|
-
return input({ message: 'Paste the authorization code from the browser' });
|
|
83
|
-
},
|
|
84
|
-
}),
|
|
85
|
-
},
|
|
86
|
-
});
|
|
87
|
-
printResult(result, json);
|
|
88
|
-
}, { json });
|
|
89
|
-
});
|
|
90
|
-
if (hidden) {
|
|
91
|
-
mint.hook('preAction', () => {
|
|
92
|
-
console.error(chalk.gray(`'agents ${parent.name()} mint' is a hidden alias; use \`${MINT_POINTER}\` — still works this release.`));
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
setHelpSections(mint, {
|
|
96
|
-
examples: `agents accounts add claude work
|
|
97
|
-
agents accounts login claude#work
|
|
98
|
-
agents accounts mint claude --token-stdin < token.txt
|
|
99
|
-
agents accounts mint claude --code AUTHCODE --json
|
|
100
|
-
agents accounts mint claude --fleet`,
|
|
101
|
-
notes: `Hidden alias of the worker-credential step that \`agents accounts add <harness> [name]\` (mint during add) and \`agents accounts login <harness>#<name>\` (re-mint) now own. Claude is the only harness with an interactive long-lived setup-token (\`claude setup-token\`, ~1 year, shareable across machines). The command drives that flow in a PTY, opens the authorize URL, captures a well-formed sk-ant-oat01- token (refusing the #1767 TTY-banner capture), and seeds:
|
|
102
|
-
1. a named provider account (policy never) for \`agents run --account\` / \`agents accounts sync\`
|
|
103
|
-
2. the reserved FILE-BASED auth bundle keyed per email, which usage/probe reads
|
|
104
|
-
Native rotating OAuth is never copied. Other harnesses fail loud: device-code login is \`agents fleet login\`; API keys are \`agents accounts add\`.
|
|
105
|
-
Already have a token? \`--token-stdin\` skips the browser dance. \`agents auth mint\` and \`agents accounts mint\` are the same hidden command.`,
|
|
106
|
-
});
|
|
107
|
-
return mint;
|
|
108
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `agents reconnect [session-id]` — get me back into an agent terminal whose ssh
|
|
3
|
-
* link dropped.
|
|
4
|
-
*
|
|
5
|
-
* The auto-reconnect in lib/hosts/reconnect.ts already re-attaches a live remote
|
|
6
|
-
* pane over its own bounded backoff on a transient blink. This is the MANUAL
|
|
7
|
-
* recovery for after it gave up — a sustained outage, or a VS Code terminal tab
|
|
8
|
-
* that closed with the dead ssh client. One verb that always tries hardest to put
|
|
9
|
-
* you back into that agent: attach the live pane if it still exists, else resume
|
|
10
|
-
* the session; live pane > resumed copy > a clear message about what was lost.
|
|
11
|
-
*
|
|
12
|
-
* It delegates to `focus`, which already does exactly attach-else-resume for a
|
|
13
|
-
* resolved id ({@link focusAction} → `focusResolvedSession`), so there is no second
|
|
14
|
-
* recovery path to keep in sync. What `reconnect` adds is the recovery framing and,
|
|
15
|
-
* with no id, targeting the MOST RECENT session in this shell's directory — the one
|
|
16
|
-
* that most likely just dropped — instead of opening the full fleet picker.
|
|
17
|
-
*/
|
|
18
|
-
import type { Command } from 'commander';
|
|
19
|
-
import type { SessionMeta } from '../lib/session/types.js';
|
|
20
|
-
/**
|
|
21
|
-
* The recency signal a no-id reconnect targets: last activity if the scan
|
|
22
|
-
* computed one, else the creation time. A row with neither parseable sorts last.
|
|
23
|
-
* Pure so target selection is unit-tested without the scanner.
|
|
24
|
-
*/
|
|
25
|
-
export declare function sessionRecency(s: Pick<SessionMeta, 'lastActivity' | 'timestamp'>): number;
|
|
26
|
-
/**
|
|
27
|
-
* Pick the session to reconnect when the user gave no id: the most recently
|
|
28
|
-
* active one in scope — the terminal that most likely just dropped. Pure; returns
|
|
29
|
-
* undefined for an empty scope so the caller can print guidance.
|
|
30
|
-
*/
|
|
31
|
-
export declare function pickMostRecentSession(sessions: SessionMeta[]): SessionMeta | undefined;
|
|
32
|
-
/**
|
|
33
|
-
* Resolve the no-id target: prefer the most recent session started from THIS
|
|
34
|
-
* directory (the shell the user is reconnecting from), falling back to the most
|
|
35
|
-
* recent session anywhere when the current directory has none. Best-effort — a
|
|
36
|
-
* discovery failure yields undefined, never throws. Injectable `discover` keeps
|
|
37
|
-
* the two-step scope preference testable without touching the real scanner.
|
|
38
|
-
*/
|
|
39
|
-
export declare function resolveRecentTarget(cwd: string, discover?: (opts: {
|
|
40
|
-
cwd?: string;
|
|
41
|
-
all?: boolean;
|
|
42
|
-
since?: string;
|
|
43
|
-
limit?: number;
|
|
44
|
-
}) => Promise<SessionMeta[]>): Promise<SessionMeta | undefined>;
|
|
45
|
-
export declare function reconnectAction(id: string | undefined): Promise<void>;
|
|
46
|
-
export declare function registerReconnectCommand(program: Command): void;
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `agents reconnect [session-id]` — get me back into an agent terminal whose ssh
|
|
3
|
-
* link dropped.
|
|
4
|
-
*
|
|
5
|
-
* The auto-reconnect in lib/hosts/reconnect.ts already re-attaches a live remote
|
|
6
|
-
* pane over its own bounded backoff on a transient blink. This is the MANUAL
|
|
7
|
-
* recovery for after it gave up — a sustained outage, or a VS Code terminal tab
|
|
8
|
-
* that closed with the dead ssh client. One verb that always tries hardest to put
|
|
9
|
-
* you back into that agent: attach the live pane if it still exists, else resume
|
|
10
|
-
* the session; live pane > resumed copy > a clear message about what was lost.
|
|
11
|
-
*
|
|
12
|
-
* It delegates to `focus`, which already does exactly attach-else-resume for a
|
|
13
|
-
* resolved id ({@link focusAction} → `focusResolvedSession`), so there is no second
|
|
14
|
-
* recovery path to keep in sync. What `reconnect` adds is the recovery framing and,
|
|
15
|
-
* with no id, targeting the MOST RECENT session in this shell's directory — the one
|
|
16
|
-
* that most likely just dropped — instead of opening the full fleet picker.
|
|
17
|
-
*/
|
|
18
|
-
import chalk from 'chalk';
|
|
19
|
-
import { focusAction } from './focus.js';
|
|
20
|
-
import { discoverSessions } from '../lib/session/discover.js';
|
|
21
|
-
import { setHelpSections } from '../lib/help.js';
|
|
22
|
-
/**
|
|
23
|
-
* The recency signal a no-id reconnect targets: last activity if the scan
|
|
24
|
-
* computed one, else the creation time. A row with neither parseable sorts last.
|
|
25
|
-
* Pure so target selection is unit-tested without the scanner.
|
|
26
|
-
*/
|
|
27
|
-
export function sessionRecency(s) {
|
|
28
|
-
const t = Date.parse(s.lastActivity ?? s.timestamp ?? '');
|
|
29
|
-
return Number.isFinite(t) ? t : Number.NEGATIVE_INFINITY;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Pick the session to reconnect when the user gave no id: the most recently
|
|
33
|
-
* active one in scope — the terminal that most likely just dropped. Pure; returns
|
|
34
|
-
* undefined for an empty scope so the caller can print guidance.
|
|
35
|
-
*/
|
|
36
|
-
export function pickMostRecentSession(sessions) {
|
|
37
|
-
let best;
|
|
38
|
-
for (const s of sessions) {
|
|
39
|
-
if (!best || sessionRecency(s) > sessionRecency(best))
|
|
40
|
-
best = s;
|
|
41
|
-
}
|
|
42
|
-
return best;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Resolve the no-id target: prefer the most recent session started from THIS
|
|
46
|
-
* directory (the shell the user is reconnecting from), falling back to the most
|
|
47
|
-
* recent session anywhere when the current directory has none. Best-effort — a
|
|
48
|
-
* discovery failure yields undefined, never throws. Injectable `discover` keeps
|
|
49
|
-
* the two-step scope preference testable without touching the real scanner.
|
|
50
|
-
*/
|
|
51
|
-
export async function resolveRecentTarget(cwd, discover = discoverSessions) {
|
|
52
|
-
try {
|
|
53
|
-
const here = await discover({ cwd, since: '7d', limit: 200 });
|
|
54
|
-
const local = pickMostRecentSession(here);
|
|
55
|
-
if (local)
|
|
56
|
-
return local;
|
|
57
|
-
const any = await discover({ all: true, since: '7d', limit: 200 });
|
|
58
|
-
return pickMostRecentSession(any);
|
|
59
|
-
}
|
|
60
|
-
catch {
|
|
61
|
-
return undefined;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
export async function reconnectAction(id) {
|
|
65
|
-
if (id) {
|
|
66
|
-
// focus already attaches a live pane or recovers a dropped one for a resolved
|
|
67
|
-
// id — on the origin device for a remote session. Reconnect is that path with
|
|
68
|
-
// a recovery-first name; no reason to duplicate the resolution/attach logic.
|
|
69
|
-
await focusAction(id, {});
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
const recent = await resolveRecentTarget(process.cwd());
|
|
73
|
-
if (!recent) {
|
|
74
|
-
console.log(chalk.gray('No recent session to reconnect from here.'));
|
|
75
|
-
console.log(chalk.gray(' reconnect a specific one: agents reconnect <session-id>'));
|
|
76
|
-
console.log(chalk.gray(' or pick from the fleet: agents sessions'));
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
const where = recent.machine ? ` on ${recent.machine}` : '';
|
|
80
|
-
console.log(chalk.gray(`Reconnecting ${recent.shortId}${where} (most recent here)…`));
|
|
81
|
-
await focusAction(recent.id, {});
|
|
82
|
-
}
|
|
83
|
-
export function registerReconnectCommand(program) {
|
|
84
|
-
// Deprecated: superseded by `agents sessions resume`, which does the same
|
|
85
|
-
// attach-else-recover and additionally takes a tmux alias. Hidden + warned +
|
|
86
|
-
// functional for one release. Bare `reconnect` targeted the most recent
|
|
87
|
-
// session in this directory; that default now lives on `resume`'s picker.
|
|
88
|
-
const cmd = program
|
|
89
|
-
.command('reconnect', { hidden: true })
|
|
90
|
-
.argument('[session-id]', 'Session id/prefix to reconnect (default: the most recent session started here)')
|
|
91
|
-
.description('Deprecated — use `agents sessions resume` instead.')
|
|
92
|
-
.action(async (id) => {
|
|
93
|
-
console.warn(chalk.yellow('`agents reconnect` is deprecated — use `agents sessions resume` instead:'));
|
|
94
|
-
console.warn(chalk.gray(` agents sessions resume${id ? ` ${id}` : ''}`));
|
|
95
|
-
await reconnectAction(id);
|
|
96
|
-
});
|
|
97
|
-
setHelpSections(cmd, {
|
|
98
|
-
examples: `
|
|
99
|
-
# Reconnect the session that just dropped in this shell (most recent here)
|
|
100
|
-
agents reconnect
|
|
101
|
-
|
|
102
|
-
# Reconnect one specific agent terminal by id/prefix
|
|
103
|
-
agents reconnect 74b13b0b
|
|
104
|
-
|
|
105
|
-
# Same, spelled under the sessions group
|
|
106
|
-
agents sessions reconnect 74b13b0b
|
|
107
|
-
`,
|
|
108
|
-
notes: `
|
|
109
|
-
- Best-effort recovery: a living remote tmux pane is JOINED (a second client, no fork); a dropped one is RESUMED on its origin device (a copy if it was mid-run, a /continue if idle).
|
|
110
|
-
- With no id, targets the most recent session started from this directory (the terminal that most likely just dropped), not the full fleet picker. Falls back to the most recent session anywhere when this directory has none.
|
|
111
|
-
- This is the manual companion to the automatic reconnect that runs during a live 'agents run --device <box>' when the network blinks; use it after that gave up or the terminal tab closed.
|
|
112
|
-
- Deprecated: use 'agents sessions resume' — it attaches a live pane, foregrounds a headless session, or recovers an ended one.
|
|
113
|
-
`,
|
|
114
|
-
});
|
|
115
|
-
}
|