agent-relay 6.0.22 → 6.2.0
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/dist/index.cjs +338 -49
- package/dist/src/cli/bootstrap.d.ts.map +1 -1
- package/dist/src/cli/bootstrap.js +62 -0
- package/dist/src/cli/bootstrap.js.map +1 -1
- package/dist/src/cli/commands/agent-management.d.ts +8 -0
- package/dist/src/cli/commands/agent-management.d.ts.map +1 -1
- package/dist/src/cli/commands/agent-management.js +34 -0
- package/dist/src/cli/commands/agent-management.js.map +1 -1
- package/dist/src/cli/commands/drive.d.ts +222 -0
- package/dist/src/cli/commands/drive.d.ts.map +1 -0
- package/dist/src/cli/commands/drive.js +565 -0
- package/dist/src/cli/commands/drive.js.map +1 -0
- package/dist/src/cli/commands/messaging.d.ts +25 -0
- package/dist/src/cli/commands/messaging.d.ts.map +1 -1
- package/dist/src/cli/commands/messaging.js +702 -138
- package/dist/src/cli/commands/messaging.js.map +1 -1
- package/dist/src/cli/commands/new.d.ts +112 -0
- package/dist/src/cli/commands/new.d.ts.map +1 -0
- package/dist/src/cli/commands/new.js +189 -0
- package/dist/src/cli/commands/new.js.map +1 -0
- package/dist/src/cli/commands/on/provision.d.ts +1 -1
- package/dist/src/cli/commands/on/provision.d.ts.map +1 -1
- package/dist/src/cli/commands/on/provision.js +1 -1
- package/dist/src/cli/commands/on/provision.js.map +1 -1
- package/dist/src/cli/commands/on/start.d.ts +1 -1
- package/dist/src/cli/commands/on/start.d.ts.map +1 -1
- package/dist/src/cli/commands/on/start.js +2 -2
- package/dist/src/cli/commands/on/start.js.map +1 -1
- package/dist/src/cli/commands/passthrough.d.ts +142 -0
- package/dist/src/cli/commands/passthrough.d.ts.map +1 -0
- package/dist/src/cli/commands/passthrough.js +398 -0
- package/dist/src/cli/commands/passthrough.js.map +1 -0
- package/dist/src/cli/commands/rm.d.ts +52 -0
- package/dist/src/cli/commands/rm.d.ts.map +1 -0
- package/dist/src/cli/commands/rm.js +96 -0
- package/dist/src/cli/commands/rm.js.map +1 -0
- package/dist/src/cli/commands/view.d.ts +98 -0
- package/dist/src/cli/commands/view.d.ts.map +1 -0
- package/dist/src/cli/commands/view.js +238 -0
- package/dist/src/cli/commands/view.js.map +1 -0
- package/dist/src/cli/lib/agent-management-listing.d.ts +35 -7
- package/dist/src/cli/lib/agent-management-listing.d.ts.map +1 -1
- package/dist/src/cli/lib/agent-management-listing.js +188 -40
- package/dist/src/cli/lib/agent-management-listing.js.map +1 -1
- package/dist/src/cli/lib/attach.d.ts +56 -0
- package/dist/src/cli/lib/attach.d.ts.map +1 -0
- package/dist/src/cli/lib/attach.js +73 -0
- package/dist/src/cli/lib/attach.js.map +1 -0
- package/dist/src/cli/lib/broker-connection.d.ts +40 -0
- package/dist/src/cli/lib/broker-connection.d.ts.map +1 -0
- package/dist/src/cli/lib/broker-connection.js +82 -0
- package/dist/src/cli/lib/broker-connection.js.map +1 -0
- package/dist/src/cli/lib/formatting.d.ts +4 -0
- package/dist/src/cli/lib/formatting.d.ts.map +1 -1
- package/dist/src/cli/lib/formatting.js +31 -1
- package/dist/src/cli/lib/formatting.js.map +1 -1
- package/dist/src/cli/lib/sdk-client.d.ts +9 -0
- package/dist/src/cli/lib/sdk-client.d.ts.map +1 -0
- package/dist/src/cli/lib/sdk-client.js +28 -0
- package/dist/src/cli/lib/sdk-client.js.map +1 -0
- package/dist/src/cli/lib/spawn-and-attach.d.ts +132 -0
- package/dist/src/cli/lib/spawn-and-attach.d.ts.map +1 -0
- package/dist/src/cli/lib/spawn-and-attach.js +334 -0
- package/dist/src/cli/lib/spawn-and-attach.js.map +1 -0
- package/package.json +12 -10
- package/dist/packages/cloud/src/api-client.d.ts +0 -33
- package/dist/packages/cloud/src/api-client.d.ts.map +0 -1
- package/dist/packages/cloud/src/api-client.js +0 -123
- package/dist/packages/cloud/src/api-client.js.map +0 -1
- package/dist/packages/cloud/src/auth.d.ts +0 -13
- package/dist/packages/cloud/src/auth.d.ts.map +0 -1
- package/dist/packages/cloud/src/auth.js +0 -299
- package/dist/packages/cloud/src/auth.js.map +0 -1
- package/dist/packages/cloud/src/connect.d.ts +0 -45
- package/dist/packages/cloud/src/connect.d.ts.map +0 -1
- package/dist/packages/cloud/src/connect.js +0 -166
- package/dist/packages/cloud/src/connect.js.map +0 -1
- package/dist/packages/cloud/src/index.d.ts +0 -10
- package/dist/packages/cloud/src/index.d.ts.map +0 -1
- package/dist/packages/cloud/src/index.js +0 -10
- package/dist/packages/cloud/src/index.js.map +0 -1
- package/dist/packages/cloud/src/lib/ssh-interactive.d.ts +0 -70
- package/dist/packages/cloud/src/lib/ssh-interactive.d.ts.map +0 -1
- package/dist/packages/cloud/src/lib/ssh-interactive.js +0 -440
- package/dist/packages/cloud/src/lib/ssh-interactive.js.map +0 -1
- package/dist/packages/cloud/src/lib/ssh-runtime.d.ts +0 -35
- package/dist/packages/cloud/src/lib/ssh-runtime.d.ts.map +0 -1
- package/dist/packages/cloud/src/lib/ssh-runtime.js +0 -52
- package/dist/packages/cloud/src/lib/ssh-runtime.js.map +0 -1
- package/dist/packages/cloud/src/proactive-runtime.d.ts +0 -24
- package/dist/packages/cloud/src/proactive-runtime.d.ts.map +0 -1
- package/dist/packages/cloud/src/proactive-runtime.js +0 -315
- package/dist/packages/cloud/src/proactive-runtime.js.map +0 -1
- package/dist/packages/cloud/src/types.d.ts +0 -200
- package/dist/packages/cloud/src/types.d.ts.map +0 -1
- package/dist/packages/cloud/src/types.js +0 -12
- package/dist/packages/cloud/src/types.js.map +0 -1
- package/dist/packages/cloud/src/workflows.d.ts +0 -65
- package/dist/packages/cloud/src/workflows.d.ts.map +0 -1
- package/dist/packages/cloud/src/workflows.js +0 -892
- package/dist/packages/cloud/src/workflows.js.map +0 -1
- package/dist/packages/cloud/src/workspaces.d.ts +0 -11
- package/dist/packages/cloud/src/workspaces.d.ts.map +0 -1
- package/dist/packages/cloud/src/workspaces.js +0 -146
- package/dist/packages/cloud/src/workspaces.js.map +0 -1
- package/dist/packages/sdk/src/provisioner/local-jwks.d.ts +0 -25
- package/dist/packages/sdk/src/provisioner/local-jwks.d.ts.map +0 -1
- package/dist/packages/sdk/src/provisioner/local-jwks.js +0 -70
- package/dist/packages/sdk/src/provisioner/local-jwks.js.map +0 -1
- package/dist/packages/sdk/src/provisioner/seeder.d.ts +0 -17
- package/dist/packages/sdk/src/provisioner/seeder.d.ts.map +0 -1
- package/dist/packages/sdk/src/provisioner/seeder.js +0 -419
- package/dist/packages/sdk/src/provisioner/seeder.js.map +0 -1
- package/dist/packages/sdk/src/provisioner/token.d.ts +0 -41
- package/dist/packages/sdk/src/provisioner/token.d.ts.map +0 -1
- package/dist/packages/sdk/src/provisioner/token.js +0 -77
- package/dist/packages/sdk/src/provisioner/token.js.map +0 -1
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agent-relay passthrough <name>` — read-write attach in passthrough session.
|
|
3
|
+
*
|
|
4
|
+
* The broker auto-injects inbound relay messages into the agent's PTY
|
|
5
|
+
* while the human also types; both writers race. That's the point —
|
|
6
|
+
* passthrough is for observe-and-occasionally-nudge sessions
|
|
7
|
+
* while the broker does its coordination thing. For exclusive
|
|
8
|
+
* deterministic control with no auto-inject, use `drive` instead.
|
|
9
|
+
*
|
|
10
|
+
* On attach, ensures the worker is in `auto_inject` delivery mode (it's the
|
|
11
|
+
* broker default, but if someone left a `drive` session the worker may
|
|
12
|
+
* be in `manual_flush` mode — `passthrough` flips it back for the session's
|
|
13
|
+
* duration and restores the prior mode on detach). On detach, restores
|
|
14
|
+
* the prior mode and leaves the agent running.
|
|
15
|
+
*
|
|
16
|
+
* The session loop (snapshot-on-attach, raw stdin, resize forwarding,
|
|
17
|
+
* detach keybind, Ctrl+C-as-detach safety alias) mirrors the shape of
|
|
18
|
+
* `drive.ts` minus the pending-queue UI and `Ctrl+G` flush binding
|
|
19
|
+
* (there's no queue in passthrough session). `drive.ts` is the more
|
|
20
|
+
* heavily-commented version of the shared shape; this module
|
|
21
|
+
* duplicates rather than abstracts because the trimmed surface is
|
|
22
|
+
* small enough that an extra layer of indirection would cost more
|
|
23
|
+
* clarity than it saves.
|
|
24
|
+
*/
|
|
25
|
+
import { Buffer } from 'node:buffer';
|
|
26
|
+
import WebSocket from 'ws';
|
|
27
|
+
import { captureAndRenderSnapshot, } from '../lib/attach.js';
|
|
28
|
+
import { defaultStateDir, readConnectionFileFromDisk, resolveBrokerConnection, toWsUrl, } from '../lib/broker-connection.js';
|
|
29
|
+
import { defaultExit, runSignalHandler } from '../lib/exit.js';
|
|
30
|
+
import { getInboundDeliveryMode, resizeWorker, sendInput, setInboundDeliveryMode, } from './drive.js';
|
|
31
|
+
function withDefaults(overrides = {}) {
|
|
32
|
+
return {
|
|
33
|
+
readConnectionFile: readConnectionFileFromDisk,
|
|
34
|
+
getDefaultStateDir: defaultStateDir,
|
|
35
|
+
env: process.env,
|
|
36
|
+
createWebSocket: (url, headers) => new WebSocket(url, { headers }),
|
|
37
|
+
writeChunk: (chunk) => {
|
|
38
|
+
process.stdout.write(chunk);
|
|
39
|
+
},
|
|
40
|
+
onSignal: (signal, handler) => {
|
|
41
|
+
process.on(signal, () => runSignalHandler(handler));
|
|
42
|
+
},
|
|
43
|
+
log: (...args) => console.error(...args),
|
|
44
|
+
error: (...args) => console.error(...args),
|
|
45
|
+
exit: defaultExit,
|
|
46
|
+
fetch: (input, init) => fetch(input, init),
|
|
47
|
+
captureAndRenderSnapshot,
|
|
48
|
+
stdin: process.stdin,
|
|
49
|
+
terminal: {
|
|
50
|
+
getSize: () => {
|
|
51
|
+
const stdout = process.stdout;
|
|
52
|
+
if (!stdout.isTTY)
|
|
53
|
+
return null;
|
|
54
|
+
const rows = stdout.rows;
|
|
55
|
+
const cols = stdout.columns;
|
|
56
|
+
if (typeof rows !== 'number' || typeof cols !== 'number')
|
|
57
|
+
return null;
|
|
58
|
+
return { rows, cols };
|
|
59
|
+
},
|
|
60
|
+
onResize: (handler) => {
|
|
61
|
+
process.stdout.on('resize', handler);
|
|
62
|
+
return () => process.stdout.off('resize', handler);
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
...overrides,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** ----- WS message classification ----- */
|
|
69
|
+
function isStringObject(value) {
|
|
70
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Inspect a single WebSocket frame and classify it relative to the
|
|
74
|
+
* agent we're following. Non-matching / malformed frames return
|
|
75
|
+
* `{ kind: 'other' }` so the caller can ignore them cheaply.
|
|
76
|
+
*/
|
|
77
|
+
export function classifyWsEvent(rawMessage, name) {
|
|
78
|
+
let parsed;
|
|
79
|
+
try {
|
|
80
|
+
parsed = JSON.parse(rawMessage);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return { kind: 'other' };
|
|
84
|
+
}
|
|
85
|
+
if (!isStringObject(parsed))
|
|
86
|
+
return { kind: 'other' };
|
|
87
|
+
if (parsed.name !== name)
|
|
88
|
+
return { kind: 'other' };
|
|
89
|
+
if (parsed.kind === 'worker_stream') {
|
|
90
|
+
const chunk = parsed.chunk;
|
|
91
|
+
if (typeof chunk !== 'string')
|
|
92
|
+
return { kind: 'other' };
|
|
93
|
+
return { kind: 'worker_stream', chunk };
|
|
94
|
+
}
|
|
95
|
+
return { kind: 'other' };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Stateful parser for the passthrough client's keybind vocabulary.
|
|
99
|
+
* Smaller than `drive`'s because there's no queue to flush — no
|
|
100
|
+
* `Ctrl+G` binding.
|
|
101
|
+
*
|
|
102
|
+
* Semantics:
|
|
103
|
+
* - `Ctrl+C` (0x03) → emit `detach`, never forwarded.
|
|
104
|
+
* - `Ctrl+B` (0x02) → swallow, arm the prefix state.
|
|
105
|
+
* Next byte:
|
|
106
|
+
* - 'd' / 'D' / 0x04 (Ctrl+D) → emit `detach`.
|
|
107
|
+
* - '?' → emit `toggle_help`.
|
|
108
|
+
* - anything else → forward `Ctrl+B` + the byte so
|
|
109
|
+
* TUI apps using `Ctrl+B` themselves
|
|
110
|
+
* aren't deprived.
|
|
111
|
+
*/
|
|
112
|
+
export class PassthroughKeybindParser {
|
|
113
|
+
pendingPrefix = false;
|
|
114
|
+
feed(chunk) {
|
|
115
|
+
const forward = [];
|
|
116
|
+
const actions = [];
|
|
117
|
+
for (const byte of chunk) {
|
|
118
|
+
if (this.pendingPrefix) {
|
|
119
|
+
this.pendingPrefix = false;
|
|
120
|
+
if (byte === 0x44 /* 'D' */ || byte === 0x64 /* 'd' */ || byte === 0x04 /* Ctrl+D */) {
|
|
121
|
+
actions.push('detach');
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (byte === 0x3f /* '?' */) {
|
|
125
|
+
actions.push('toggle_help');
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
forward.push(0x02);
|
|
129
|
+
forward.push(byte);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (byte === 0x03 /* Ctrl+C */) {
|
|
133
|
+
actions.push('detach');
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (byte === 0x02 /* Ctrl+B */) {
|
|
137
|
+
this.pendingPrefix = true;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
forward.push(byte);
|
|
141
|
+
}
|
|
142
|
+
return { forward: Buffer.from(forward), actions };
|
|
143
|
+
}
|
|
144
|
+
reset() {
|
|
145
|
+
this.pendingPrefix = false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** ----- Status line rendering ----- */
|
|
149
|
+
/**
|
|
150
|
+
* Render the bottom-of-terminal status line for `passthrough`. Same
|
|
151
|
+
* save/restore-cursor trick as `drive`, no pending counter (there
|
|
152
|
+
* isn't one in passthrough session).
|
|
153
|
+
*/
|
|
154
|
+
export function renderStatusLine(opts) {
|
|
155
|
+
const row = Math.max(opts.rows ?? 24, 1);
|
|
156
|
+
const help = opts.showHelp ? ' | Ctrl+B D detach | Ctrl+B ? hide help' : ' | Ctrl+B D detach';
|
|
157
|
+
const text = `[passthrough ${opts.name} | delivery=${opts.mode}${help}]`;
|
|
158
|
+
return `\x1b7\x1b[${row};1H\x1b[2K\x1b[7m${text}\x1b[0m\x1b8`;
|
|
159
|
+
}
|
|
160
|
+
/** ----- Main session runner ----- */
|
|
161
|
+
/**
|
|
162
|
+
* Open a `passthrough` session. Resolves with the exit code the CLI
|
|
163
|
+
* should propagate. Cleans up its own stdin raw-mode and best-effort
|
|
164
|
+
* restores the worker's previous inbound delivery mode on any exit path.
|
|
165
|
+
*/
|
|
166
|
+
export async function runPassthroughSession(agentName, options, deps) {
|
|
167
|
+
// Normalize once so every downstream broker call, WS-event match,
|
|
168
|
+
// status-line label, and error message uses the same trimmed value.
|
|
169
|
+
// Without this a stray space in the raw input turns into a silent
|
|
170
|
+
// 404 (the broker stores names verbatim).
|
|
171
|
+
const name = agentName.trim();
|
|
172
|
+
if (!name) {
|
|
173
|
+
deps.error('Error: agent name is required');
|
|
174
|
+
return 1;
|
|
175
|
+
}
|
|
176
|
+
const connection = resolveBrokerConnection(options, deps);
|
|
177
|
+
if (!connection) {
|
|
178
|
+
deps.error('Error: could not locate broker connection. Pass --broker-url, set RELAY_BROKER_URL, ' +
|
|
179
|
+
'or run from a directory containing .agent-relay/connection.json.');
|
|
180
|
+
return 1;
|
|
181
|
+
}
|
|
182
|
+
// Remember the worker's prior mode so we can restore on detach.
|
|
183
|
+
// `null` means we couldn't read it (broker hiccup or worker missing);
|
|
184
|
+
// we default the restore target to `auto_inject` in that case (which
|
|
185
|
+
// is also our preferred final state).
|
|
186
|
+
const previousMode = await getInboundDeliveryMode(connection, name, deps.fetch);
|
|
187
|
+
// If the worker is in `manual_flush` mode (e.g. someone left a `drive`
|
|
188
|
+
// session), flip it back to `auto_inject` for the duration of our
|
|
189
|
+
// session. This matches the verb's intent: `agent-relay passthrough alice`
|
|
190
|
+
// means "watch alice with auto-inject on". If the worker is already
|
|
191
|
+
// in `auto_inject` we still issue the PUT — it's idempotent on the
|
|
192
|
+
// broker and gives us an early hard-failure on missing-agent before
|
|
193
|
+
// we touch the terminal.
|
|
194
|
+
const flip = await setInboundDeliveryMode(connection, name, 'auto_inject', deps.fetch);
|
|
195
|
+
if (!flip.ok) {
|
|
196
|
+
if (flip.status === 404) {
|
|
197
|
+
deps.error(`Error: no agent named '${name}'`);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
deps.error(`Error: could not ensure '${name}' is in passthrough session: ${flip.message ?? 'unknown error'}`);
|
|
201
|
+
}
|
|
202
|
+
return 1;
|
|
203
|
+
}
|
|
204
|
+
const snapshot = await deps.captureAndRenderSnapshot({ url: connection.url, apiKey: connection.apiKey }, name, { fetch: deps.fetch, writeChunk: deps.writeChunk });
|
|
205
|
+
switch (snapshot.status) {
|
|
206
|
+
case 'ok':
|
|
207
|
+
break;
|
|
208
|
+
case 'not_found':
|
|
209
|
+
await setInboundDeliveryMode(connection, name, previousMode ?? 'auto_inject', deps.fetch);
|
|
210
|
+
deps.error(`Error: ${snapshot.message ?? `no agent named '${name}'`}`);
|
|
211
|
+
return 1;
|
|
212
|
+
case 'no_pty':
|
|
213
|
+
await setInboundDeliveryMode(connection, name, previousMode ?? 'auto_inject', deps.fetch);
|
|
214
|
+
deps.error(`Error: ${snapshot.message ?? `agent '${name}' has no PTY to attach to`}`);
|
|
215
|
+
return 1;
|
|
216
|
+
case 'unavailable':
|
|
217
|
+
case 'transport_error':
|
|
218
|
+
deps.log(`[passthrough] could not capture initial screen (${snapshot.message ?? snapshot.status}); streaming live output only`);
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
let showHelp = false;
|
|
222
|
+
const initialLocalSize = deps.terminal.getSize();
|
|
223
|
+
let terminalRows = initialLocalSize?.rows ??
|
|
224
|
+
(typeof snapshot.rows === 'number' && snapshot.rows > 0 ? snapshot.rows : undefined);
|
|
225
|
+
const paintStatus = () => {
|
|
226
|
+
deps.writeChunk(renderStatusLine({ name, mode: 'auto_inject', showHelp, rows: terminalRows }));
|
|
227
|
+
};
|
|
228
|
+
paintStatus();
|
|
229
|
+
if (initialLocalSize) {
|
|
230
|
+
const initialResize = await resizeWorker(connection, name, initialLocalSize.rows, initialLocalSize.cols, deps.fetch);
|
|
231
|
+
if (!initialResize.ok) {
|
|
232
|
+
deps.log(`[passthrough] could not sync agent PTY size to local terminal (${initialResize.message ?? 'unknown'}); continuing`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const wsUrl = toWsUrl(connection.url);
|
|
236
|
+
const headers = {};
|
|
237
|
+
if (connection.apiKey) {
|
|
238
|
+
headers['X-API-Key'] = connection.apiKey;
|
|
239
|
+
}
|
|
240
|
+
return new Promise((resolve) => {
|
|
241
|
+
let settled = false;
|
|
242
|
+
let rawModeWasSet = false;
|
|
243
|
+
let unsubscribeResize = null;
|
|
244
|
+
const parser = new PassthroughKeybindParser();
|
|
245
|
+
const resizeHandler = () => {
|
|
246
|
+
const size = deps.terminal.getSize();
|
|
247
|
+
if (!size)
|
|
248
|
+
return;
|
|
249
|
+
terminalRows = size.rows;
|
|
250
|
+
void resizeWorker(connection, name, size.rows, size.cols, deps.fetch).then((res) => {
|
|
251
|
+
if (!res.ok) {
|
|
252
|
+
deps.log(`[passthrough] resize forward failed: ${res.message ?? 'unknown error'}`);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
paintStatus();
|
|
256
|
+
};
|
|
257
|
+
const stdinDataHandler = (chunk) => {
|
|
258
|
+
const outcome = parser.feed(chunk);
|
|
259
|
+
if (outcome.forward.length > 0) {
|
|
260
|
+
void sendInput(connection, name, outcome.forward.toString('utf-8'), deps.fetch).then((res) => {
|
|
261
|
+
if (!res.ok) {
|
|
262
|
+
deps.log(`[passthrough] input send failed: ${res.message ?? 'unknown error'}`);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
for (const action of outcome.actions) {
|
|
267
|
+
switch (action) {
|
|
268
|
+
case 'detach':
|
|
269
|
+
finish(0);
|
|
270
|
+
return;
|
|
271
|
+
case 'toggle_help':
|
|
272
|
+
showHelp = !showHelp;
|
|
273
|
+
paintStatus();
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
const teardownStdin = () => {
|
|
279
|
+
try {
|
|
280
|
+
if (deps.stdin.off) {
|
|
281
|
+
deps.stdin.off('data', stdinDataHandler);
|
|
282
|
+
}
|
|
283
|
+
else if (deps.stdin.removeListener) {
|
|
284
|
+
deps.stdin.removeListener('data', stdinDataHandler);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
// best effort
|
|
289
|
+
}
|
|
290
|
+
try {
|
|
291
|
+
if (rawModeWasSet && typeof deps.stdin.setRawMode === 'function') {
|
|
292
|
+
deps.stdin.setRawMode(false);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
// best effort
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
deps.stdin.pause();
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
// best effort
|
|
303
|
+
}
|
|
304
|
+
try {
|
|
305
|
+
if (unsubscribeResize) {
|
|
306
|
+
unsubscribeResize();
|
|
307
|
+
unsubscribeResize = null;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
// best effort
|
|
312
|
+
}
|
|
313
|
+
rawModeWasSet = false;
|
|
314
|
+
};
|
|
315
|
+
const finish = (code) => {
|
|
316
|
+
if (settled)
|
|
317
|
+
return;
|
|
318
|
+
settled = true;
|
|
319
|
+
teardownStdin();
|
|
320
|
+
try {
|
|
321
|
+
socket.close(1000, 'passthrough client exiting');
|
|
322
|
+
}
|
|
323
|
+
catch {
|
|
324
|
+
// best effort
|
|
325
|
+
}
|
|
326
|
+
// Restore the worker's previous mode (no-op if it was already
|
|
327
|
+
// auto-inject, which is the common case).
|
|
328
|
+
void setInboundDeliveryMode(connection, name, previousMode ?? 'auto_inject', deps.fetch).finally(() => {
|
|
329
|
+
resolve(code);
|
|
330
|
+
});
|
|
331
|
+
};
|
|
332
|
+
const socket = deps.createWebSocket(wsUrl, headers);
|
|
333
|
+
deps.onSignal('SIGINT', () => finish(0));
|
|
334
|
+
deps.onSignal('SIGTERM', () => finish(0));
|
|
335
|
+
socket.on('open', () => {
|
|
336
|
+
deps.log(`[passthrough] attached to ${name} via ${connection.url} (Ctrl+B D to detach)`);
|
|
337
|
+
try {
|
|
338
|
+
if (typeof deps.stdin.setRawMode === 'function' && deps.stdin.isTTY !== false) {
|
|
339
|
+
deps.stdin.setRawMode(true);
|
|
340
|
+
rawModeWasSet = true;
|
|
341
|
+
}
|
|
342
|
+
deps.stdin.resume();
|
|
343
|
+
deps.stdin.on('data', stdinDataHandler);
|
|
344
|
+
unsubscribeResize = deps.terminal.onResize(resizeHandler);
|
|
345
|
+
}
|
|
346
|
+
catch (err) {
|
|
347
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
348
|
+
deps.error(`[passthrough] could not enable raw input mode: ${message}`);
|
|
349
|
+
finish(1);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
socket.on('message', (data) => {
|
|
353
|
+
const text = typeof data === 'string' ? data : Buffer.isBuffer(data) ? data.toString('utf-8') : String(data);
|
|
354
|
+
const event = classifyWsEvent(text, name);
|
|
355
|
+
switch (event.kind) {
|
|
356
|
+
case 'worker_stream':
|
|
357
|
+
deps.writeChunk(event.chunk);
|
|
358
|
+
paintStatus();
|
|
359
|
+
break;
|
|
360
|
+
case 'other':
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
socket.on('error', (err) => {
|
|
365
|
+
deps.error(`[passthrough] WebSocket error: ${err.message}`);
|
|
366
|
+
});
|
|
367
|
+
socket.on('close', (code, reason) => {
|
|
368
|
+
if (settled)
|
|
369
|
+
return;
|
|
370
|
+
const reasonText = reason && reason.length > 0 ? reason.toString('utf-8') : '';
|
|
371
|
+
if (code === 1000 || code === 1005) {
|
|
372
|
+
finish(0);
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
deps.error(`[passthrough] connection closed (code: ${code}${reasonText ? `, reason: ${reasonText}` : ''})`);
|
|
376
|
+
finish(1);
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
/** Register `agent-relay passthrough <name>` on the supplied commander program. */
|
|
382
|
+
export function registerPassthroughCommands(program, overrides = {}) {
|
|
383
|
+
const deps = withDefaults(overrides);
|
|
384
|
+
program
|
|
385
|
+
.command('passthrough')
|
|
386
|
+
.description('Watch a running agent in passthrough session: broker auto-injects inbound relay messages while you type alongside (last-writer-wins)')
|
|
387
|
+
.argument('<name>', 'Agent name to attach to')
|
|
388
|
+
.option('--broker-url <url>', 'Broker base URL (overrides RELAY_BROKER_URL and connection.json)')
|
|
389
|
+
.option('--api-key <key>', 'Broker API key (overrides RELAY_BROKER_API_KEY and connection.json)')
|
|
390
|
+
.option('--state-dir <dir>', 'Directory containing connection.json (default: .agent-relay/)')
|
|
391
|
+
.action(async (name, options) => {
|
|
392
|
+
const code = await runPassthroughSession(name, options, deps);
|
|
393
|
+
if (code !== 0) {
|
|
394
|
+
deps.exit(code);
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
//# sourceMappingURL=passthrough.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passthrough.js","sourceRoot":"","sources":["../../../../src/cli/commands/passthrough.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agent-relay rm <name>` — release a spawned agent via the broker's
|
|
3
|
+
* `DELETE /api/spawned/{name}` route.
|
|
4
|
+
*
|
|
5
|
+
* Trivial wrapper. Prints a one-line confirmation on success and a
|
|
6
|
+
* one-line explanatory error on failure. Connection discovery uses the
|
|
7
|
+
* shared `resolveBrokerConnection` helper so the same `--broker-url` /
|
|
8
|
+
* `RELAY_BROKER_URL` / `connection.json` chain works as for `view` /
|
|
9
|
+
* `drive` / `passthrough`.
|
|
10
|
+
*
|
|
11
|
+
* The longer-form `release` command in `agent-management.ts` layers
|
|
12
|
+
* broker autostart on top of the same SDK client; `rm` is the lighter
|
|
13
|
+
* "I already have a broker" entry point.
|
|
14
|
+
*/
|
|
15
|
+
import { Command } from 'commander';
|
|
16
|
+
import { type BrokerConnection } from '../lib/broker-connection.js';
|
|
17
|
+
type ExitFn = (code: number) => never;
|
|
18
|
+
export interface RmDependencies {
|
|
19
|
+
readConnectionFile: (stateDir: string) => unknown;
|
|
20
|
+
getDefaultStateDir: () => string;
|
|
21
|
+
env: NodeJS.ProcessEnv;
|
|
22
|
+
fetch: typeof globalThis.fetch;
|
|
23
|
+
log: (...args: unknown[]) => void;
|
|
24
|
+
error: (...args: unknown[]) => void;
|
|
25
|
+
exit: ExitFn;
|
|
26
|
+
}
|
|
27
|
+
/** Outcome of `releaseAgent`. Useful for the `--ephemeral` teardown in `run`. */
|
|
28
|
+
export interface ReleaseResult {
|
|
29
|
+
ok: boolean;
|
|
30
|
+
status: number;
|
|
31
|
+
message?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Release through the SDK client against the resolved broker. Returns a
|
|
35
|
+
* structured outcome the caller can decide how to surface — `rm` prints
|
|
36
|
+
* a one-liner, the `--ephemeral` teardown in `run` swallows failures
|
|
37
|
+
* because the client is already on its way out.
|
|
38
|
+
*/
|
|
39
|
+
export declare function releaseAgent(connection: BrokerConnection, agentName: string, fetchFn: typeof globalThis.fetch): Promise<ReleaseResult>;
|
|
40
|
+
/**
|
|
41
|
+
* Run the `rm <name>` verb. Resolves with the exit code the CLI should
|
|
42
|
+
* propagate. Pure — no signal handlers, no event loop hooks.
|
|
43
|
+
*/
|
|
44
|
+
export declare function runRm(agentName: string, options: {
|
|
45
|
+
brokerUrl?: string;
|
|
46
|
+
apiKey?: string;
|
|
47
|
+
stateDir?: string;
|
|
48
|
+
}, deps: RmDependencies): Promise<number>;
|
|
49
|
+
/** Register `agent-relay rm <name>` on the supplied commander program. */
|
|
50
|
+
export declare function registerRmCommands(program: Command, overrides?: Partial<RmDependencies>): void;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=rm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rm.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/rm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,6BAA6B,CAAC;AAIrC,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;AAEtC,MAAM,WAAW,cAAc;IAC7B,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAClD,kBAAkB,EAAE,MAAM,MAAM,CAAC;IACjC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAC/B,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd;AAeD,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,gBAAgB,EAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,UAAU,CAAC,KAAK,GAC/B,OAAO,CAAC,aAAa,CAAC,CAQxB;AAED;;;GAGG;AACH,wBAAsB,KAAK,CACzB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EACnE,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM,GAAG,IAAI,CAgBlG"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agent-relay rm <name>` — release a spawned agent via the broker's
|
|
3
|
+
* `DELETE /api/spawned/{name}` route.
|
|
4
|
+
*
|
|
5
|
+
* Trivial wrapper. Prints a one-line confirmation on success and a
|
|
6
|
+
* one-line explanatory error on failure. Connection discovery uses the
|
|
7
|
+
* shared `resolveBrokerConnection` helper so the same `--broker-url` /
|
|
8
|
+
* `RELAY_BROKER_URL` / `connection.json` chain works as for `view` /
|
|
9
|
+
* `drive` / `passthrough`.
|
|
10
|
+
*
|
|
11
|
+
* The longer-form `release` command in `agent-management.ts` layers
|
|
12
|
+
* broker autostart on top of the same SDK client; `rm` is the lighter
|
|
13
|
+
* "I already have a broker" entry point.
|
|
14
|
+
*/
|
|
15
|
+
import { defaultStateDir, readConnectionFileFromDisk, resolveBrokerConnection, } from '../lib/broker-connection.js';
|
|
16
|
+
import { defaultExit } from '../lib/exit.js';
|
|
17
|
+
import { createBrokerClient, mapBrokerSdkFailure } from '../lib/sdk-client.js';
|
|
18
|
+
function withDefaults(overrides = {}) {
|
|
19
|
+
return {
|
|
20
|
+
readConnectionFile: readConnectionFileFromDisk,
|
|
21
|
+
getDefaultStateDir: defaultStateDir,
|
|
22
|
+
env: process.env,
|
|
23
|
+
fetch: (input, init) => fetch(input, init),
|
|
24
|
+
log: (...args) => console.log(...args),
|
|
25
|
+
error: (...args) => console.error(...args),
|
|
26
|
+
exit: defaultExit,
|
|
27
|
+
...overrides,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Release through the SDK client against the resolved broker. Returns a
|
|
32
|
+
* structured outcome the caller can decide how to surface — `rm` prints
|
|
33
|
+
* a one-liner, the `--ephemeral` teardown in `run` swallows failures
|
|
34
|
+
* because the client is already on its way out.
|
|
35
|
+
*/
|
|
36
|
+
export async function releaseAgent(connection, agentName, fetchFn) {
|
|
37
|
+
try {
|
|
38
|
+
await createBrokerClient(connection, fetchFn).release(agentName);
|
|
39
|
+
return { ok: true, status: 200 };
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
const failure = mapBrokerSdkFailure(err);
|
|
43
|
+
return { ok: false, status: failure.status, message: failure.message };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Run the `rm <name>` verb. Resolves with the exit code the CLI should
|
|
48
|
+
* propagate. Pure — no signal handlers, no event loop hooks.
|
|
49
|
+
*/
|
|
50
|
+
export async function runRm(agentName, options, deps) {
|
|
51
|
+
// Normalize once so lookups, error messages, and the success log all
|
|
52
|
+
// see the same trimmed name. Without this a stray space turns into a
|
|
53
|
+
// 404 (broker registers names verbatim) and the error message echoes
|
|
54
|
+
// the raw input, which makes debugging quoting issues painful.
|
|
55
|
+
const name = agentName.trim();
|
|
56
|
+
if (!name) {
|
|
57
|
+
deps.error('Error: agent name is required');
|
|
58
|
+
return 1;
|
|
59
|
+
}
|
|
60
|
+
const connection = resolveBrokerConnection(options, deps);
|
|
61
|
+
if (!connection) {
|
|
62
|
+
deps.error('Error: could not locate broker connection. Pass --broker-url, set RELAY_BROKER_URL, ' +
|
|
63
|
+
'or run from a directory containing .agent-relay/connection.json.');
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
const result = await releaseAgent(connection, name, deps.fetch);
|
|
67
|
+
if (!result.ok) {
|
|
68
|
+
if (result.status === 404) {
|
|
69
|
+
deps.error(`Error: no agent named '${name}'`);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
deps.error(`Error: could not release '${name}': ${result.message ?? 'unknown error'}`);
|
|
73
|
+
}
|
|
74
|
+
return 1;
|
|
75
|
+
}
|
|
76
|
+
deps.log(`Released agent: ${name}`);
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
79
|
+
/** Register `agent-relay rm <name>` on the supplied commander program. */
|
|
80
|
+
export function registerRmCommands(program, overrides = {}) {
|
|
81
|
+
const deps = withDefaults(overrides);
|
|
82
|
+
program
|
|
83
|
+
.command('rm')
|
|
84
|
+
.description('Release a running agent via the broker (no terminal required)')
|
|
85
|
+
.argument('<name>', 'Agent name to release')
|
|
86
|
+
.option('--broker-url <url>', 'Broker base URL (overrides RELAY_BROKER_URL and connection.json)')
|
|
87
|
+
.option('--api-key <key>', 'Broker API key (overrides RELAY_BROKER_API_KEY and connection.json)')
|
|
88
|
+
.option('--state-dir <dir>', 'Directory containing connection.json (default: .agent-relay/)')
|
|
89
|
+
.action(async (name, options) => {
|
|
90
|
+
const code = await runRm(name, options, deps);
|
|
91
|
+
if (code !== 0) {
|
|
92
|
+
deps.exit(code);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=rm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rm.js","sourceRoot":"","sources":["../../../../src/cli/commands/rm.ts"],"names":[],"mappings":"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"}
|