agent-relay 6.0.22 → 6.2.1
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,565 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agent-relay drive <name>` — interactive read-write take-over client.
|
|
3
|
+
*
|
|
4
|
+
* Attaches to a running agent, flips it into `manual_flush` inbound delivery mode so the
|
|
5
|
+
* broker parks new relay messages in a per-worker queue, and forwards your
|
|
6
|
+
* keystrokes to the worker's PTY. You can drain the queue on demand with
|
|
7
|
+
* `Ctrl+G` and detach with `Ctrl+B D` (or `Ctrl+C` as a safety alias).
|
|
8
|
+
* Detaching restores the worker's previous inbound delivery mode and leaves the
|
|
9
|
+
* agent running under the broker — `drive` never kills the worker.
|
|
10
|
+
*
|
|
11
|
+
* Sequence of operations on attach:
|
|
12
|
+
*
|
|
13
|
+
* 1. Discover broker connection (CLI flag → env → connection.json).
|
|
14
|
+
* 2. `GET /api/spawned/{name}/delivery-mode` → remember the previous mode.
|
|
15
|
+
* 3. `PUT /api/spawned/{name}/delivery-mode` → switch to `manual_flush`.
|
|
16
|
+
* 4. `captureAndRenderSnapshot` → repaint the agent's current screen.
|
|
17
|
+
* 5. `GET /api/spawned/{name}/pending` → seed the status-line counter.
|
|
18
|
+
* 6. Open `/ws`, subscribe to events for this worker.
|
|
19
|
+
* 7. Switch local stdin to raw mode; forward bytes to `POST /api/input/{name}`.
|
|
20
|
+
*
|
|
21
|
+
* On detach (clean or abnormal), best-effort `PUT .../delivery-mode` restores the
|
|
22
|
+
* previous mode so the queue doesn't fill up indefinitely.
|
|
23
|
+
*/
|
|
24
|
+
import { Buffer } from 'node:buffer';
|
|
25
|
+
import WebSocket from 'ws';
|
|
26
|
+
import { captureAndRenderSnapshot, } from '../lib/attach.js';
|
|
27
|
+
import { defaultStateDir, readConnectionFileFromDisk, resolveBrokerConnection, toWsUrl, } from '../lib/broker-connection.js';
|
|
28
|
+
import { defaultExit, runSignalHandler } from '../lib/exit.js';
|
|
29
|
+
import { createBrokerClient, mapBrokerSdkFailure } from '../lib/sdk-client.js';
|
|
30
|
+
function withDefaults(overrides = {}) {
|
|
31
|
+
return {
|
|
32
|
+
readConnectionFile: readConnectionFileFromDisk,
|
|
33
|
+
getDefaultStateDir: defaultStateDir,
|
|
34
|
+
env: process.env,
|
|
35
|
+
createWebSocket: (url, headers) => new WebSocket(url, { headers }),
|
|
36
|
+
writeChunk: (chunk) => {
|
|
37
|
+
process.stdout.write(chunk);
|
|
38
|
+
},
|
|
39
|
+
onSignal: (signal, handler) => {
|
|
40
|
+
process.on(signal, () => runSignalHandler(handler));
|
|
41
|
+
},
|
|
42
|
+
log: (...args) => console.error(...args),
|
|
43
|
+
error: (...args) => console.error(...args),
|
|
44
|
+
exit: defaultExit,
|
|
45
|
+
fetch: (input, init) => fetch(input, init),
|
|
46
|
+
captureAndRenderSnapshot,
|
|
47
|
+
stdin: process.stdin,
|
|
48
|
+
terminal: {
|
|
49
|
+
getSize: () => {
|
|
50
|
+
// process.stdout.isTTY is `true | undefined`; reading
|
|
51
|
+
// rows/columns on a non-TTY returns `undefined`.
|
|
52
|
+
const stdout = process.stdout;
|
|
53
|
+
if (!stdout.isTTY)
|
|
54
|
+
return null;
|
|
55
|
+
const rows = stdout.rows;
|
|
56
|
+
const cols = stdout.columns;
|
|
57
|
+
if (typeof rows !== 'number' || typeof cols !== 'number')
|
|
58
|
+
return null;
|
|
59
|
+
return { rows, cols };
|
|
60
|
+
},
|
|
61
|
+
onResize: (handler) => {
|
|
62
|
+
// Node automatically translates SIGWINCH into a `'resize'`
|
|
63
|
+
// event on `process.stdout` when stdout is a TTY.
|
|
64
|
+
process.stdout.on('resize', handler);
|
|
65
|
+
return () => process.stdout.off('resize', handler);
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
...overrides,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** ----- HTTP helpers ----- */
|
|
72
|
+
/** `GET /api/spawned/{name}/delivery-mode` → `'manual_flush' | 'auto_inject'` or `null` on failure. */
|
|
73
|
+
export async function getInboundDeliveryMode(connection, name, fetchFn) {
|
|
74
|
+
try {
|
|
75
|
+
return await createBrokerClient(connection, fetchFn).getInboundDeliveryMode(name);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export async function setInboundDeliveryMode(connection, name, mode, fetchFn) {
|
|
82
|
+
try {
|
|
83
|
+
const body = await createBrokerClient(connection, fetchFn).setInboundDeliveryMode(name, mode);
|
|
84
|
+
const flushed = body.flushed;
|
|
85
|
+
return { ok: true, status: 200, flushed };
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
const failure = mapBrokerSdkFailure(err);
|
|
89
|
+
return { ok: false, status: failure.status, message: failure.message };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/** `GET /api/spawned/{name}/pending` → count, or `0` on failure (best-effort). */
|
|
93
|
+
export async function getPendingCount(connection, name, fetchFn) {
|
|
94
|
+
try {
|
|
95
|
+
return (await createBrokerClient(connection, fetchFn).getPending(name)).length;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** `POST /api/spawned/{name}/flush` → server returns `{ flushed: N }`. */
|
|
102
|
+
export async function flushPending(connection, name, fetchFn) {
|
|
103
|
+
try {
|
|
104
|
+
const body = await createBrokerClient(connection, fetchFn).flushPending(name);
|
|
105
|
+
return { ok: true, flushed: body.flushed };
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
const failure = mapBrokerSdkFailure(err);
|
|
109
|
+
return { ok: false, message: failure.message };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/** `POST /api/input/{name}` body `{ data: "<bytes>" }`. */
|
|
113
|
+
export async function sendInput(connection, name, data, fetchFn) {
|
|
114
|
+
try {
|
|
115
|
+
await createBrokerClient(connection, fetchFn).sendInput(name, data);
|
|
116
|
+
return { ok: true };
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
const failure = mapBrokerSdkFailure(err);
|
|
120
|
+
return { ok: false, message: failure.message };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* `POST /api/resize/{name}` body `{ rows, cols }`. Forwards the
|
|
125
|
+
* driver's local terminal dimensions so the agent's PTY (and any TUI
|
|
126
|
+
* running in it) sees the size the human is actually looking at.
|
|
127
|
+
* Called once on attach and again on every local-terminal resize.
|
|
128
|
+
*/
|
|
129
|
+
export async function resizeWorker(connection, name, rows, cols, fetchFn) {
|
|
130
|
+
try {
|
|
131
|
+
await createBrokerClient(connection, fetchFn).resizePty(name, rows, cols);
|
|
132
|
+
return { ok: true };
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
const failure = mapBrokerSdkFailure(err);
|
|
136
|
+
return { ok: false, message: failure.message };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/** ----- WS message classification ----- */
|
|
140
|
+
function isStringObject(value) {
|
|
141
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Inspect a single WebSocket frame and classify it relative to the agent
|
|
145
|
+
* we're driving. Non-matching / malformed frames return `{ kind: 'other' }`
|
|
146
|
+
* so the caller can ignore them cheaply.
|
|
147
|
+
*
|
|
148
|
+
* Exported for unit testing the filter in isolation.
|
|
149
|
+
*/
|
|
150
|
+
export function classifyWsEvent(rawMessage, name) {
|
|
151
|
+
let parsed;
|
|
152
|
+
try {
|
|
153
|
+
parsed = JSON.parse(rawMessage);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
return { kind: 'other' };
|
|
157
|
+
}
|
|
158
|
+
if (!isStringObject(parsed))
|
|
159
|
+
return { kind: 'other' };
|
|
160
|
+
// All three events we care about are scoped by the worker `name` field.
|
|
161
|
+
if (parsed.name !== name)
|
|
162
|
+
return { kind: 'other' };
|
|
163
|
+
if (parsed.kind === 'worker_stream') {
|
|
164
|
+
const chunk = parsed.chunk;
|
|
165
|
+
if (typeof chunk !== 'string')
|
|
166
|
+
return { kind: 'other' };
|
|
167
|
+
return { kind: 'worker_stream', chunk };
|
|
168
|
+
}
|
|
169
|
+
if (parsed.kind === 'delivery_queued') {
|
|
170
|
+
return { kind: 'delivery_queued' };
|
|
171
|
+
}
|
|
172
|
+
if (parsed.kind === 'agent_pending_drained') {
|
|
173
|
+
const count = typeof parsed.count === 'number' ? parsed.count : undefined;
|
|
174
|
+
return { kind: 'agent_pending_drained', count };
|
|
175
|
+
}
|
|
176
|
+
return { kind: 'other' };
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Stateful parser that recognises the `Ctrl+B <key>` two-byte prefix
|
|
180
|
+
* sequence, plus the single-byte safety keybinds (`Ctrl+G` flush,
|
|
181
|
+
* `Ctrl+C` detach).
|
|
182
|
+
*
|
|
183
|
+
* The parser is intentionally tiny — no readline, no keypress — because
|
|
184
|
+
* the keybinds are all ASCII control characters, and pulling in a
|
|
185
|
+
* keypress parser would just add a dependency for no real benefit.
|
|
186
|
+
*
|
|
187
|
+
* Semantics:
|
|
188
|
+
* - `Ctrl+G` (0x07) → emit `flush`, never forwarded.
|
|
189
|
+
* - `Ctrl+C` (0x03) → emit `detach`, never forwarded.
|
|
190
|
+
* - `Ctrl+B` (0x02) → swallow, arm the prefix state.
|
|
191
|
+
* Next byte (within the same chunk OR a subsequent chunk):
|
|
192
|
+
* - 'd' / 'D' / 0x04 (Ctrl+D) → emit `detach`.
|
|
193
|
+
* - '?' → emit `toggle_help`.
|
|
194
|
+
* - anything else → forward the original `Ctrl+B` byte
|
|
195
|
+
* followed by the new byte, so the
|
|
196
|
+
* agent isn't deprived if the user
|
|
197
|
+
* hit Ctrl+B by accident.
|
|
198
|
+
*
|
|
199
|
+
* Multiple keybinds in one chunk are handled in order; bytes between
|
|
200
|
+
* them are forwarded normally.
|
|
201
|
+
*/
|
|
202
|
+
export class KeybindParser {
|
|
203
|
+
pendingPrefix = false;
|
|
204
|
+
/** Process one chunk; returns bytes to forward + actions to take. */
|
|
205
|
+
feed(chunk) {
|
|
206
|
+
const forward = [];
|
|
207
|
+
const actions = [];
|
|
208
|
+
for (const byte of chunk) {
|
|
209
|
+
if (this.pendingPrefix) {
|
|
210
|
+
this.pendingPrefix = false;
|
|
211
|
+
if (byte === 0x44 /* 'D' */ || byte === 0x64 /* 'd' */ || byte === 0x04 /* Ctrl+D */) {
|
|
212
|
+
actions.push('detach');
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if (byte === 0x3f /* '?' */) {
|
|
216
|
+
actions.push('toggle_help');
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
// Not a recognised prefix command — forward Ctrl+B + the byte
|
|
220
|
+
// so the agent isn't deprived (some TUI apps use Ctrl+B for
|
|
221
|
+
// their own bindings).
|
|
222
|
+
forward.push(0x02);
|
|
223
|
+
forward.push(byte);
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (byte === 0x07 /* Ctrl+G */) {
|
|
227
|
+
actions.push('flush');
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
if (byte === 0x03 /* Ctrl+C */) {
|
|
231
|
+
actions.push('detach');
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (byte === 0x02 /* Ctrl+B */) {
|
|
235
|
+
this.pendingPrefix = true;
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
forward.push(byte);
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
forward: Buffer.from(forward),
|
|
242
|
+
actions,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/** Reset the parser (e.g. before tearing down). */
|
|
246
|
+
reset() {
|
|
247
|
+
this.pendingPrefix = false;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/** ----- Status line rendering ----- */
|
|
251
|
+
/**
|
|
252
|
+
* Render the bottom-of-terminal status line for `drive`. Uses ANSI
|
|
253
|
+
* save-cursor / restore-cursor so the agent's output isn't disturbed.
|
|
254
|
+
*
|
|
255
|
+
* Exported for unit testing — `runDriveSession` calls it on every
|
|
256
|
+
* pending-count change.
|
|
257
|
+
*/
|
|
258
|
+
export function renderStatusLine(opts) {
|
|
259
|
+
const row = Math.max(opts.rows ?? 24, 1);
|
|
260
|
+
const help = opts.showHelp
|
|
261
|
+
? ' | Ctrl+G flush | Ctrl+B D detach | Ctrl+B ? hide help'
|
|
262
|
+
: ' | Ctrl+G flush | Ctrl+B D detach';
|
|
263
|
+
const text = `[drive ${opts.name} | delivery=${opts.mode} | pending=${opts.pending}${help}]`;
|
|
264
|
+
// ESC 7 = save cursor; ESC[<row>;1H = move to bottom row; ESC[2K = clear line;
|
|
265
|
+
// ESC[7m = reverse video; ESC[0m = reset; ESC 8 = restore cursor.
|
|
266
|
+
return `\x1b7\x1b[${row};1H\x1b[2K\x1b[7m${text}\x1b[0m\x1b8`;
|
|
267
|
+
}
|
|
268
|
+
/** ----- Main session runner ----- */
|
|
269
|
+
/**
|
|
270
|
+
* Open a `drive` session. Resolves with the exit code the CLI should
|
|
271
|
+
* propagate. Cleans up its own stdin raw-mode and best-effort restores
|
|
272
|
+
* the worker's previous inbound delivery mode on any exit path.
|
|
273
|
+
*/
|
|
274
|
+
export async function runDriveSession(agentName, options, deps) {
|
|
275
|
+
// Normalize once so every downstream broker call, WS-event match,
|
|
276
|
+
// status-line label, and error message uses the same trimmed value.
|
|
277
|
+
// Without this a stray space in the raw input turns into a silent
|
|
278
|
+
// 404 (the broker stores names verbatim).
|
|
279
|
+
const name = agentName.trim();
|
|
280
|
+
if (!name) {
|
|
281
|
+
deps.error('Error: agent name is required');
|
|
282
|
+
return 1;
|
|
283
|
+
}
|
|
284
|
+
const connection = resolveBrokerConnection(options, deps);
|
|
285
|
+
if (!connection) {
|
|
286
|
+
deps.error('Error: could not locate broker connection. Pass --broker-url, set RELAY_BROKER_URL, ' +
|
|
287
|
+
'or run from a directory containing .agent-relay/connection.json.');
|
|
288
|
+
return 1;
|
|
289
|
+
}
|
|
290
|
+
// Remember the worker's prior mode so we can restore it on detach.
|
|
291
|
+
// `null` means we couldn't read it (broker hiccup or worker missing);
|
|
292
|
+
// we default the restore target to `auto_inject` in that case so the
|
|
293
|
+
// queue doesn't keep growing.
|
|
294
|
+
const previousMode = await getInboundDeliveryMode(connection, name, deps.fetch);
|
|
295
|
+
// Flip the worker into manual_flush mode. If this fails outright, abort
|
|
296
|
+
// before doing anything else — we don't want to redraw the screen
|
|
297
|
+
// and then silently keep auto-injecting into the agent.
|
|
298
|
+
const flip = await setInboundDeliveryMode(connection, name, 'manual_flush', deps.fetch);
|
|
299
|
+
if (!flip.ok) {
|
|
300
|
+
if (flip.status === 404) {
|
|
301
|
+
deps.error(`Error: no agent named '${name}'`);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
deps.error(`Error: could not switch '${name}' to manual_flush mode: ${flip.message ?? 'unknown error'}`);
|
|
305
|
+
}
|
|
306
|
+
return 1;
|
|
307
|
+
}
|
|
308
|
+
// Render the agent's current visible screen before the live stream
|
|
309
|
+
// begins. Same error semantics as `view`: hard errors abort, transient
|
|
310
|
+
// errors warn and proceed.
|
|
311
|
+
const snapshot = await deps.captureAndRenderSnapshot({ url: connection.url, apiKey: connection.apiKey }, name, { fetch: deps.fetch, writeChunk: deps.writeChunk });
|
|
312
|
+
switch (snapshot.status) {
|
|
313
|
+
case 'ok':
|
|
314
|
+
break;
|
|
315
|
+
case 'not_found':
|
|
316
|
+
// Best-effort restore — we did flip the mode above.
|
|
317
|
+
await setInboundDeliveryMode(connection, name, previousMode ?? 'auto_inject', deps.fetch);
|
|
318
|
+
deps.error(`Error: ${snapshot.message ?? `no agent named '${name}'`}`);
|
|
319
|
+
return 1;
|
|
320
|
+
case 'no_pty':
|
|
321
|
+
await setInboundDeliveryMode(connection, name, previousMode ?? 'auto_inject', deps.fetch);
|
|
322
|
+
deps.error(`Error: ${snapshot.message ?? `agent '${name}' has no PTY to drive`}`);
|
|
323
|
+
return 1;
|
|
324
|
+
case 'unavailable':
|
|
325
|
+
case 'transport_error':
|
|
326
|
+
deps.log(`[drive] could not capture initial screen (${snapshot.message ?? snapshot.status}); streaming live output only`);
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
// Seed the pending counter so the status line is correct from the
|
|
330
|
+
// first paint.
|
|
331
|
+
let pending = await getPendingCount(connection, name, deps.fetch);
|
|
332
|
+
let showHelp = false;
|
|
333
|
+
// Status-line row tracks the LOCAL terminal's bottom row, not the
|
|
334
|
+
// agent's PTY rows from the snapshot — those can differ before we
|
|
335
|
+
// forward our size to the broker, and the status line needs to land
|
|
336
|
+
// where the human is looking. Falls back to the snapshot rows, then
|
|
337
|
+
// the renderer's own 24-row default.
|
|
338
|
+
const initialLocalSize = deps.terminal.getSize();
|
|
339
|
+
let terminalRows = initialLocalSize?.rows ??
|
|
340
|
+
(typeof snapshot.rows === 'number' && snapshot.rows > 0 ? snapshot.rows : undefined);
|
|
341
|
+
const paintStatus = () => {
|
|
342
|
+
deps.writeChunk(renderStatusLine({
|
|
343
|
+
name,
|
|
344
|
+
mode: 'manual_flush',
|
|
345
|
+
pending,
|
|
346
|
+
showHelp,
|
|
347
|
+
rows: terminalRows,
|
|
348
|
+
}));
|
|
349
|
+
};
|
|
350
|
+
paintStatus();
|
|
351
|
+
// Sync the agent's PTY to the driver's local terminal size. tmux /
|
|
352
|
+
// screen / ssh all do this — without it, a TUI in the agent renders
|
|
353
|
+
// into whatever 24×80 box the PTY was spawned with, ignoring the
|
|
354
|
+
// human's actual viewport. Best-effort: a failure here is annoying
|
|
355
|
+
// but not fatal (the human can still type, output just renders into
|
|
356
|
+
// the old size). Skipped entirely when stdout isn't a TTY.
|
|
357
|
+
if (initialLocalSize) {
|
|
358
|
+
const initialResize = await resizeWorker(connection, name, initialLocalSize.rows, initialLocalSize.cols, deps.fetch);
|
|
359
|
+
if (!initialResize.ok) {
|
|
360
|
+
deps.log(`[drive] could not sync agent PTY size to local terminal (${initialResize.message ?? 'unknown'}); continuing`);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
const wsUrl = toWsUrl(connection.url);
|
|
364
|
+
const headers = {};
|
|
365
|
+
if (connection.apiKey) {
|
|
366
|
+
headers['X-API-Key'] = connection.apiKey;
|
|
367
|
+
}
|
|
368
|
+
return new Promise((resolve) => {
|
|
369
|
+
let settled = false;
|
|
370
|
+
let rawModeWasSet = false;
|
|
371
|
+
let unsubscribeResize = null;
|
|
372
|
+
const parser = new KeybindParser();
|
|
373
|
+
// Local-terminal resize handler. Forwards to the broker and
|
|
374
|
+
// repaints the status line at the new bottom-row index. Registered
|
|
375
|
+
// on `socket.on('open')` (same point we take over stdin) so a
|
|
376
|
+
// failed connection doesn't leave a dangling listener; unregistered
|
|
377
|
+
// in `teardownStdin` so detach is clean.
|
|
378
|
+
const resizeHandler = () => {
|
|
379
|
+
const size = deps.terminal.getSize();
|
|
380
|
+
if (!size)
|
|
381
|
+
return;
|
|
382
|
+
terminalRows = size.rows;
|
|
383
|
+
void resizeWorker(connection, name, size.rows, size.cols, deps.fetch).then((res) => {
|
|
384
|
+
if (!res.ok) {
|
|
385
|
+
deps.log(`[drive] resize forward failed: ${res.message ?? 'unknown error'}`);
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
// Repaint regardless of fetch outcome — the local terminal has
|
|
389
|
+
// already moved, so the status line position needs to move with
|
|
390
|
+
// it whether or not the broker accepted the resize.
|
|
391
|
+
paintStatus();
|
|
392
|
+
};
|
|
393
|
+
// ---- stdin handling ----
|
|
394
|
+
const stdinDataHandler = (chunk) => {
|
|
395
|
+
const outcome = parser.feed(chunk);
|
|
396
|
+
if (outcome.forward.length > 0) {
|
|
397
|
+
// Fire-and-forget; surface errors via log but don't block the
|
|
398
|
+
// event loop on every keystroke.
|
|
399
|
+
// UTF-8, not latin1 — the broker deserializes /api/input's
|
|
400
|
+
// `data` as a Rust `String` and forwards the bytes verbatim.
|
|
401
|
+
// 'binary' would map bytes ≥ 0x80 to Latin-1 code points,
|
|
402
|
+
// which then get UTF-8 re-encoded on the wire, doubling
|
|
403
|
+
// multi-byte characters (e.g. `é` → `é` on the agent's side).
|
|
404
|
+
void sendInput(connection, name, outcome.forward.toString('utf-8'), deps.fetch).then((res) => {
|
|
405
|
+
if (!res.ok) {
|
|
406
|
+
deps.log(`[drive] input send failed: ${res.message ?? 'unknown error'}`);
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
for (const action of outcome.actions) {
|
|
411
|
+
switch (action) {
|
|
412
|
+
case 'flush':
|
|
413
|
+
void flushPending(connection, name, deps.fetch).then((res) => {
|
|
414
|
+
if (!res.ok) {
|
|
415
|
+
deps.log(`[drive] flush failed: ${res.message ?? 'unknown error'}`);
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
break;
|
|
419
|
+
case 'detach':
|
|
420
|
+
finish(0);
|
|
421
|
+
return;
|
|
422
|
+
case 'toggle_help':
|
|
423
|
+
showHelp = !showHelp;
|
|
424
|
+
paintStatus();
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
const teardownStdin = () => {
|
|
430
|
+
try {
|
|
431
|
+
if (deps.stdin.off) {
|
|
432
|
+
deps.stdin.off('data', stdinDataHandler);
|
|
433
|
+
}
|
|
434
|
+
else if (deps.stdin.removeListener) {
|
|
435
|
+
deps.stdin.removeListener('data', stdinDataHandler);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
catch {
|
|
439
|
+
// best effort
|
|
440
|
+
}
|
|
441
|
+
try {
|
|
442
|
+
if (rawModeWasSet && typeof deps.stdin.setRawMode === 'function') {
|
|
443
|
+
deps.stdin.setRawMode(false);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
catch {
|
|
447
|
+
// best effort
|
|
448
|
+
}
|
|
449
|
+
try {
|
|
450
|
+
deps.stdin.pause();
|
|
451
|
+
}
|
|
452
|
+
catch {
|
|
453
|
+
// best effort
|
|
454
|
+
}
|
|
455
|
+
try {
|
|
456
|
+
if (unsubscribeResize) {
|
|
457
|
+
unsubscribeResize();
|
|
458
|
+
unsubscribeResize = null;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
// best effort
|
|
463
|
+
}
|
|
464
|
+
rawModeWasSet = false;
|
|
465
|
+
};
|
|
466
|
+
const finish = (code) => {
|
|
467
|
+
if (settled)
|
|
468
|
+
return;
|
|
469
|
+
settled = true;
|
|
470
|
+
teardownStdin();
|
|
471
|
+
try {
|
|
472
|
+
socket.close(1000, 'drive client exiting');
|
|
473
|
+
}
|
|
474
|
+
catch {
|
|
475
|
+
// best effort
|
|
476
|
+
}
|
|
477
|
+
// Best-effort: restore the worker's previous mode so we don't
|
|
478
|
+
// leave it stuck in manual_flush and silently piling up queued messages.
|
|
479
|
+
void setInboundDeliveryMode(connection, name, previousMode ?? 'auto_inject', deps.fetch).finally(() => {
|
|
480
|
+
resolve(code);
|
|
481
|
+
});
|
|
482
|
+
};
|
|
483
|
+
const socket = deps.createWebSocket(wsUrl, headers);
|
|
484
|
+
deps.onSignal('SIGINT', () => finish(0));
|
|
485
|
+
deps.onSignal('SIGTERM', () => finish(0));
|
|
486
|
+
socket.on('open', () => {
|
|
487
|
+
deps.log(`[drive] driving ${name} via ${connection.url} (Ctrl+B D to detach)`);
|
|
488
|
+
// Now that the WS is up, take over stdin. We do this on `open`
|
|
489
|
+
// rather than synchronously so a failed connection doesn't leave
|
|
490
|
+
// the user's terminal in raw mode with nothing to type into.
|
|
491
|
+
try {
|
|
492
|
+
if (typeof deps.stdin.setRawMode === 'function' && deps.stdin.isTTY !== false) {
|
|
493
|
+
deps.stdin.setRawMode(true);
|
|
494
|
+
rawModeWasSet = true;
|
|
495
|
+
}
|
|
496
|
+
deps.stdin.resume();
|
|
497
|
+
deps.stdin.on('data', stdinDataHandler);
|
|
498
|
+
// Subscribe to local-terminal resize events at the same point
|
|
499
|
+
// we take over stdin so the lifecycles match — both go away in
|
|
500
|
+
// `teardownStdin` on any exit path.
|
|
501
|
+
unsubscribeResize = deps.terminal.onResize(resizeHandler);
|
|
502
|
+
}
|
|
503
|
+
catch (err) {
|
|
504
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
505
|
+
deps.error(`[drive] could not enable raw input mode: ${message}`);
|
|
506
|
+
finish(1);
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
socket.on('message', (data) => {
|
|
510
|
+
const text = typeof data === 'string' ? data : Buffer.isBuffer(data) ? data.toString('utf-8') : String(data);
|
|
511
|
+
const event = classifyWsEvent(text, name);
|
|
512
|
+
switch (event.kind) {
|
|
513
|
+
case 'worker_stream':
|
|
514
|
+
deps.writeChunk(event.chunk);
|
|
515
|
+
// Repaint the status line so the worker's writes don't
|
|
516
|
+
// obscure it. Cheap — it's just an ANSI escape sequence.
|
|
517
|
+
paintStatus();
|
|
518
|
+
break;
|
|
519
|
+
case 'delivery_queued':
|
|
520
|
+
pending += 1;
|
|
521
|
+
paintStatus();
|
|
522
|
+
break;
|
|
523
|
+
case 'agent_pending_drained':
|
|
524
|
+
pending = 0;
|
|
525
|
+
paintStatus();
|
|
526
|
+
break;
|
|
527
|
+
case 'other':
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
socket.on('error', (err) => {
|
|
532
|
+
deps.error(`[drive] WebSocket error: ${err.message}`);
|
|
533
|
+
});
|
|
534
|
+
socket.on('close', (code, reason) => {
|
|
535
|
+
if (settled)
|
|
536
|
+
return;
|
|
537
|
+
const reasonText = reason && reason.length > 0 ? reason.toString('utf-8') : '';
|
|
538
|
+
if (code === 1000 || code === 1005) {
|
|
539
|
+
finish(0);
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
deps.error(`[drive] connection closed (code: ${code}${reasonText ? `, reason: ${reasonText}` : ''})`);
|
|
543
|
+
finish(1);
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
/** Register `agent-relay drive <name>` on the supplied commander program. */
|
|
549
|
+
export function registerDriveCommands(program, overrides = {}) {
|
|
550
|
+
const deps = withDefaults(overrides);
|
|
551
|
+
program
|
|
552
|
+
.command('drive')
|
|
553
|
+
.description('Take interactive control of a running agent: queue inbound relay messages, type into the worker, flush on demand, detach when done')
|
|
554
|
+
.argument('<name>', 'Agent name to drive')
|
|
555
|
+
.option('--broker-url <url>', 'Broker base URL (overrides RELAY_BROKER_URL and connection.json)')
|
|
556
|
+
.option('--api-key <key>', 'Broker API key (overrides RELAY_BROKER_API_KEY and connection.json)')
|
|
557
|
+
.option('--state-dir <dir>', 'Directory containing connection.json (default: .agent-relay/)')
|
|
558
|
+
.action(async (name, options) => {
|
|
559
|
+
const code = await runDriveSession(name, options, deps);
|
|
560
|
+
if (code !== 0) {
|
|
561
|
+
deps.exit(code);
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
//# sourceMappingURL=drive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive.js","sourceRoot":"","sources":["../../../../src/cli/commands/drive.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,14 +27,24 @@ interface RelaycastMention {
|
|
|
27
27
|
interface RelaycastLastMessage {
|
|
28
28
|
id: string;
|
|
29
29
|
text: string;
|
|
30
|
+
agentName?: string;
|
|
31
|
+
agent_name?: string;
|
|
30
32
|
createdAt?: string;
|
|
31
33
|
created_at?: string;
|
|
34
|
+
direction?: DmDirection;
|
|
35
|
+
unread?: boolean;
|
|
36
|
+
isUnread?: boolean;
|
|
37
|
+
is_unread?: boolean;
|
|
38
|
+
read?: boolean;
|
|
39
|
+
isRead?: boolean;
|
|
40
|
+
is_read?: boolean;
|
|
32
41
|
}
|
|
33
42
|
interface RelaycastUnreadDm {
|
|
34
43
|
from: string;
|
|
35
44
|
conversationId?: string;
|
|
36
45
|
unreadCount?: number;
|
|
37
46
|
lastMessage?: RelaycastLastMessage | null;
|
|
47
|
+
messages?: RelaycastLastMessage[];
|
|
38
48
|
conversation_id?: string;
|
|
39
49
|
unread_count?: number;
|
|
40
50
|
last_message?: RelaycastLastMessage | null;
|
|
@@ -65,6 +75,8 @@ interface DmConversationParticipant {
|
|
|
65
75
|
}
|
|
66
76
|
interface DmConversationSummary {
|
|
67
77
|
id: string;
|
|
78
|
+
type?: string;
|
|
79
|
+
dm_type?: string;
|
|
68
80
|
participants: DmConversationParticipant[];
|
|
69
81
|
lastMessage?: {
|
|
70
82
|
id: string;
|
|
@@ -94,7 +106,14 @@ interface DmMessageItem {
|
|
|
94
106
|
text: string;
|
|
95
107
|
createdAt?: string;
|
|
96
108
|
created_at?: string;
|
|
109
|
+
unread?: boolean;
|
|
110
|
+
isUnread?: boolean;
|
|
111
|
+
is_unread?: boolean;
|
|
112
|
+
read?: boolean;
|
|
113
|
+
isRead?: boolean;
|
|
114
|
+
is_read?: boolean;
|
|
97
115
|
}
|
|
116
|
+
type DmDirection = 'inbound' | 'outbound';
|
|
98
117
|
export interface MessagingRelaycastClient {
|
|
99
118
|
message(id: string): Promise<RelaycastMessage>;
|
|
100
119
|
messages(channel: string, options?: {
|
|
@@ -105,12 +124,17 @@ export interface MessagingRelaycastClient {
|
|
|
105
124
|
inbox(): Promise<RelaycastInbox>;
|
|
106
125
|
dm(to: string, text: string): Promise<void>;
|
|
107
126
|
post(channel: string, text: string): Promise<void>;
|
|
127
|
+
markRead?: (messageId: string) => Promise<unknown> | unknown;
|
|
128
|
+
markMessagesRead?: (conversationId: string, messageIds: string[]) => Promise<unknown> | unknown;
|
|
108
129
|
dms: {
|
|
109
130
|
conversations(): Promise<DmConversationSummary[]>;
|
|
110
131
|
messages(conversationId: string, opts?: {
|
|
111
132
|
limit?: number;
|
|
112
133
|
}): Promise<DmMessageItem[]>;
|
|
134
|
+
markRead?: (conversationId: string, messageIds: string[]) => Promise<unknown> | unknown;
|
|
135
|
+
markMessagesRead?: (conversationId: string, messageIds: string[]) => Promise<unknown> | unknown;
|
|
113
136
|
};
|
|
137
|
+
disconnect?: () => Promise<unknown> | unknown;
|
|
114
138
|
}
|
|
115
139
|
export interface MessagingBrokerClient {
|
|
116
140
|
sendMessage(input: {
|
|
@@ -132,6 +156,7 @@ export interface MessagingDependencies {
|
|
|
132
156
|
error: (...args: unknown[]) => void;
|
|
133
157
|
exit: ExitFn;
|
|
134
158
|
}
|
|
159
|
+
export declare function wrapRelaycastAgentClient(agentClient: any): MessagingRelaycastClient;
|
|
135
160
|
export declare function registerMessagingCommands(program: Command, overrides?: Partial<MessagingDependencies>): void;
|
|
136
161
|
export {};
|
|
137
162
|
//# sourceMappingURL=messaging.d.ts.map
|