@agent-relay/sdk 6.3.6 → 7.0.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/README.md +5 -0
- package/bin/agent-relay-broker-darwin-arm64 +0 -0
- package/bin/agent-relay-broker-darwin-x64 +0 -0
- package/bin/agent-relay-broker-linux-arm64 +0 -0
- package/bin/agent-relay-broker-linux-x64 +0 -0
- package/bin/agent-relay-broker-win32-x64.exe +0 -0
- package/dist/broker-logs.d.ts +80 -0
- package/dist/broker-logs.d.ts.map +1 -0
- package/dist/broker-logs.js +189 -0
- package/dist/broker-logs.js.map +1 -0
- package/dist/client.d.ts +30 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +80 -19
- package/dist/client.js.map +1 -1
- package/dist/event-bus.d.ts +16 -4
- package/dist/event-bus.d.ts.map +1 -1
- package/dist/event-bus.js +8 -0
- package/dist/event-bus.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/relay.d.ts +8 -1
- package/dist/relay.d.ts.map +1 -1
- package/dist/relay.js +0 -18
- package/dist/relay.js.map +1 -1
- package/dist/workers.d.ts +1 -1
- package/dist/workers.d.ts.map +1 -1
- package/dist/workers.js.map +1 -1
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -89,6 +89,11 @@ const client = await AgentRelayClient.spawn({
|
|
|
89
89
|
channels: ['general'],
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
+
const unsubscribeBrokerExit = client.onBrokerExit((info) => {
|
|
93
|
+
console.error('broker exited', info.code, info.signal, info.recentStderr);
|
|
94
|
+
unsubscribeBrokerExit();
|
|
95
|
+
});
|
|
96
|
+
|
|
92
97
|
// Or connect to an already-running broker (reads connection.json)
|
|
93
98
|
// const client = AgentRelayClient.connect({ cwd: '/my/project' });
|
|
94
99
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for the broker's tracing log directory.
|
|
3
|
+
*
|
|
4
|
+
* The Rust broker writes its diagnostic logs to a platform-standard directory
|
|
5
|
+
* with daily rotation (see `crates/broker/src/runtime/util.rs::broker_log_dir`).
|
|
6
|
+
* This module mirrors that path so the TypeScript CLI can list, tail, prune,
|
|
7
|
+
* and clear those files without spawning the broker.
|
|
8
|
+
*/
|
|
9
|
+
export interface BrokerLogFile {
|
|
10
|
+
/** Absolute path to the log file. */
|
|
11
|
+
path: string;
|
|
12
|
+
/** Just the file name, e.g. `myproject.log.2026-05-21`. */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Broker identifier inferred from the filename (the prefix before `.log`). */
|
|
15
|
+
brokerId: string;
|
|
16
|
+
/**
|
|
17
|
+
* The rotation date suffix in `YYYY-MM-DD` form, or `null` for the
|
|
18
|
+
* pre-rotation file laid down before `tracing-appender` rolled over.
|
|
19
|
+
*/
|
|
20
|
+
date: string | null;
|
|
21
|
+
/** File size in bytes. */
|
|
22
|
+
size: number;
|
|
23
|
+
/** Last-modified time. */
|
|
24
|
+
mtime: Date;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolve the platform-standard broker log directory. Matches the Rust
|
|
28
|
+
* implementation in `runtime/util.rs::broker_log_dir`.
|
|
29
|
+
*
|
|
30
|
+
* - macOS: `~/Library/Logs/agent-relay`
|
|
31
|
+
* - Linux / other Unix: `$XDG_STATE_HOME/agent-relay/logs` (default
|
|
32
|
+
* `~/.local/state/agent-relay/logs`)
|
|
33
|
+
* - Windows: `%LOCALAPPDATA%\agent-relay\Logs`
|
|
34
|
+
*/
|
|
35
|
+
export declare function getBrokerLogDir(): string;
|
|
36
|
+
/** List all broker log files (current + rotated) in [`getBrokerLogDir`]. */
|
|
37
|
+
export declare function listBrokerLogs(dir?: string): Promise<BrokerLogFile[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Read the last `lines` lines of a broker's log. Picks the most recent file
|
|
40
|
+
* matching `brokerId`. Returns `null` when no log file exists for that id.
|
|
41
|
+
*/
|
|
42
|
+
export declare function tailBrokerLog(brokerId: string, options?: {
|
|
43
|
+
lines?: number;
|
|
44
|
+
dir?: string;
|
|
45
|
+
}): Promise<{
|
|
46
|
+
path: string;
|
|
47
|
+
content: string;
|
|
48
|
+
} | null>;
|
|
49
|
+
export interface PruneBrokerLogsOptions {
|
|
50
|
+
/** Override the log directory. Defaults to [`getBrokerLogDir`]. */
|
|
51
|
+
dir?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Keep rotated files newer than this many days. `0` removes everything
|
|
54
|
+
* except the current (un-suffixed) file. Default: 7.
|
|
55
|
+
*/
|
|
56
|
+
keepDays?: number;
|
|
57
|
+
/** When true, list candidates but don't delete. */
|
|
58
|
+
dryRun?: boolean;
|
|
59
|
+
/** Restrict to a single broker id. */
|
|
60
|
+
brokerId?: string;
|
|
61
|
+
}
|
|
62
|
+
export interface PruneBrokerLogsResult {
|
|
63
|
+
removed: BrokerLogFile[];
|
|
64
|
+
kept: BrokerLogFile[];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Delete rotated log files older than `keepDays` days. The current
|
|
68
|
+
* un-suffixed file is always kept because `tracing-appender` is writing to it.
|
|
69
|
+
*/
|
|
70
|
+
export declare function pruneBrokerLogs(options?: PruneBrokerLogsOptions): Promise<PruneBrokerLogsResult>;
|
|
71
|
+
export interface ClearBrokerLogsOptions {
|
|
72
|
+
dir?: string;
|
|
73
|
+
/** Restrict to a single broker id. When omitted, removes all log files. */
|
|
74
|
+
brokerId?: string;
|
|
75
|
+
/** When true, list candidates but don't delete. */
|
|
76
|
+
dryRun?: boolean;
|
|
77
|
+
}
|
|
78
|
+
/** Delete every log file (including the current one) matching the filter. */
|
|
79
|
+
export declare function clearBrokerLogs(options?: ClearBrokerLogsOptions): Promise<BrokerLogFile[]>;
|
|
80
|
+
//# sourceMappingURL=broker-logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker-logs.d.ts","sourceRoot":"","sources":["../src/broker-logs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,KAAK,EAAE,IAAI,CAAC;CACb;AAID;;;;;;;;GAQG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAiBxC;AAED,4EAA4E;AAC5E,wBAAsB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAkC3E;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAMnD;AAED,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,IAAI,EAAE,aAAa,EAAE,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAgC1G;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,6EAA6E;AAC7E,wBAAsB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAcpG"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for the broker's tracing log directory.
|
|
3
|
+
*
|
|
4
|
+
* The Rust broker writes its diagnostic logs to a platform-standard directory
|
|
5
|
+
* with daily rotation (see `crates/broker/src/runtime/util.rs::broker_log_dir`).
|
|
6
|
+
* This module mirrors that path so the TypeScript CLI can list, tail, prune,
|
|
7
|
+
* and clear those files without spawning the broker.
|
|
8
|
+
*/
|
|
9
|
+
import { homedir, platform } from 'node:os';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { readdir, stat, unlink, open } from 'node:fs/promises';
|
|
12
|
+
const LOG_NAME_PATTERN = /^(?<brokerId>.+)\.log(?:\.(?<date>\d{4}-\d{2}-\d{2}))?$/;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the platform-standard broker log directory. Matches the Rust
|
|
15
|
+
* implementation in `runtime/util.rs::broker_log_dir`.
|
|
16
|
+
*
|
|
17
|
+
* - macOS: `~/Library/Logs/agent-relay`
|
|
18
|
+
* - Linux / other Unix: `$XDG_STATE_HOME/agent-relay/logs` (default
|
|
19
|
+
* `~/.local/state/agent-relay/logs`)
|
|
20
|
+
* - Windows: `%LOCALAPPDATA%\agent-relay\Logs`
|
|
21
|
+
*/
|
|
22
|
+
export function getBrokerLogDir() {
|
|
23
|
+
const home = homedir();
|
|
24
|
+
switch (platform()) {
|
|
25
|
+
case 'darwin':
|
|
26
|
+
return join(home, 'Library', 'Logs', 'agent-relay');
|
|
27
|
+
case 'win32': {
|
|
28
|
+
const localAppData = process.env.LOCALAPPDATA ?? join(home, 'AppData', 'Local');
|
|
29
|
+
return join(localAppData, 'agent-relay', 'Logs');
|
|
30
|
+
}
|
|
31
|
+
default: {
|
|
32
|
+
const stateHome = process.env.XDG_STATE_HOME && process.env.XDG_STATE_HOME.length > 0
|
|
33
|
+
? process.env.XDG_STATE_HOME
|
|
34
|
+
: join(home, '.local', 'state');
|
|
35
|
+
return join(stateHome, 'agent-relay', 'logs');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** List all broker log files (current + rotated) in [`getBrokerLogDir`]. */
|
|
40
|
+
export async function listBrokerLogs(dir) {
|
|
41
|
+
const logDir = dir ?? getBrokerLogDir();
|
|
42
|
+
let entries;
|
|
43
|
+
try {
|
|
44
|
+
entries = await readdir(logDir);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
if (err.code === 'ENOENT')
|
|
48
|
+
return [];
|
|
49
|
+
throw err;
|
|
50
|
+
}
|
|
51
|
+
const files = [];
|
|
52
|
+
for (const name of entries) {
|
|
53
|
+
const match = LOG_NAME_PATTERN.exec(name);
|
|
54
|
+
if (!match || !match.groups)
|
|
55
|
+
continue;
|
|
56
|
+
const fullPath = join(logDir, name);
|
|
57
|
+
let info;
|
|
58
|
+
try {
|
|
59
|
+
info = await stat(fullPath);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (!info.isFile())
|
|
65
|
+
continue;
|
|
66
|
+
files.push({
|
|
67
|
+
path: fullPath,
|
|
68
|
+
name,
|
|
69
|
+
brokerId: match.groups.brokerId,
|
|
70
|
+
date: match.groups.date ?? null,
|
|
71
|
+
size: info.size,
|
|
72
|
+
mtime: info.mtime,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
files.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
76
|
+
return files;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Read the last `lines` lines of a broker's log. Picks the most recent file
|
|
80
|
+
* matching `brokerId`. Returns `null` when no log file exists for that id.
|
|
81
|
+
*/
|
|
82
|
+
export async function tailBrokerLog(brokerId, options = {}) {
|
|
83
|
+
const lines = options.lines ?? 200;
|
|
84
|
+
const files = (await listBrokerLogs(options.dir)).filter((f) => f.brokerId === brokerId);
|
|
85
|
+
if (files.length === 0)
|
|
86
|
+
return null;
|
|
87
|
+
const target = files[0]; // newest first
|
|
88
|
+
return { path: target.path, content: await tailFile(target.path, lines) };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Delete rotated log files older than `keepDays` days. The current
|
|
92
|
+
* un-suffixed file is always kept because `tracing-appender` is writing to it.
|
|
93
|
+
*/
|
|
94
|
+
export async function pruneBrokerLogs(options = {}) {
|
|
95
|
+
const keepDays = options.keepDays ?? 7;
|
|
96
|
+
const cutoff = Date.now() - keepDays * 24 * 60 * 60 * 1000;
|
|
97
|
+
const files = await listBrokerLogs(options.dir);
|
|
98
|
+
const removed = [];
|
|
99
|
+
const kept = [];
|
|
100
|
+
for (const file of files) {
|
|
101
|
+
if (options.brokerId && file.brokerId !== options.brokerId) {
|
|
102
|
+
kept.push(file);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
// Never delete the current (un-suffixed) file — it's being written to.
|
|
106
|
+
if (file.date === null) {
|
|
107
|
+
kept.push(file);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (file.mtime.getTime() >= cutoff) {
|
|
111
|
+
kept.push(file);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (!options.dryRun) {
|
|
115
|
+
try {
|
|
116
|
+
await unlink(file.path);
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
if (err.code !== 'ENOENT')
|
|
120
|
+
throw err;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
removed.push(file);
|
|
124
|
+
}
|
|
125
|
+
return { removed, kept };
|
|
126
|
+
}
|
|
127
|
+
/** Delete every log file (including the current one) matching the filter. */
|
|
128
|
+
export async function clearBrokerLogs(options = {}) {
|
|
129
|
+
const files = await listBrokerLogs(options.dir);
|
|
130
|
+
const target = options.brokerId ? files.filter((f) => f.brokerId === options.brokerId) : files;
|
|
131
|
+
if (options.dryRun)
|
|
132
|
+
return target;
|
|
133
|
+
for (const file of target) {
|
|
134
|
+
try {
|
|
135
|
+
await unlink(file.path);
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
if (err.code !== 'ENOENT')
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return target;
|
|
143
|
+
}
|
|
144
|
+
async function tailFile(filePath, lines) {
|
|
145
|
+
const CHUNK = 8192;
|
|
146
|
+
let fh;
|
|
147
|
+
try {
|
|
148
|
+
fh = await open(filePath, 'r');
|
|
149
|
+
const { size } = await fh.stat();
|
|
150
|
+
if (size === 0)
|
|
151
|
+
return '';
|
|
152
|
+
if (size <= CHUNK) {
|
|
153
|
+
const buf = Buffer.alloc(size);
|
|
154
|
+
await fh.read(buf, 0, size, 0);
|
|
155
|
+
return tailLines(buf.toString('utf-8'), lines);
|
|
156
|
+
}
|
|
157
|
+
const chunks = [];
|
|
158
|
+
let position = size;
|
|
159
|
+
let newlines = 0;
|
|
160
|
+
while (position > 0 && newlines <= lines) {
|
|
161
|
+
const readSize = Math.min(CHUNK, position);
|
|
162
|
+
position -= readSize;
|
|
163
|
+
const buf = Buffer.alloc(readSize);
|
|
164
|
+
await fh.read(buf, 0, readSize, position);
|
|
165
|
+
chunks.unshift(buf);
|
|
166
|
+
newlines += countNewlines(buf);
|
|
167
|
+
}
|
|
168
|
+
const combined = Buffer.concat(chunks).toString('utf-8');
|
|
169
|
+
return tailLines(combined, lines);
|
|
170
|
+
}
|
|
171
|
+
finally {
|
|
172
|
+
if (fh)
|
|
173
|
+
await fh.close();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function tailLines(text, count) {
|
|
177
|
+
const split = text.split('\n');
|
|
178
|
+
if (split.length > 0 && split[split.length - 1] === '')
|
|
179
|
+
split.pop();
|
|
180
|
+
return split.slice(-count).join('\n');
|
|
181
|
+
}
|
|
182
|
+
function countNewlines(buf) {
|
|
183
|
+
let n = 0;
|
|
184
|
+
for (const byte of buf)
|
|
185
|
+
if (byte === 0x0a)
|
|
186
|
+
n++;
|
|
187
|
+
return n;
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=broker-logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker-logs.js","sourceRoot":"","sources":["../src/broker-logs.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { type PtyInputStream, type PtyInputStreamOptions } from './transport.js'
|
|
|
14
14
|
import type { AgentRuntime, BrokerEvent, BrokerStats, BrokerStatus, CrashInsightsResponse, PendingRelayMessage, PtySnapshot, InboundDeliveryMode, SnapshotFormat } from './protocol.js';
|
|
15
15
|
import type { SpawnHeadlessInput, SpawnPtyInput, SpawnProviderInput, SendMessageInput, ListAgent } from './types.js';
|
|
16
16
|
import { EventBus } from './event-bus.js';
|
|
17
|
-
import type { AgentRelayEvents } from './lifecycle-hooks.js';
|
|
17
|
+
import type { AgentRelayEvents, BeforeAgentSpawnHandler } from './lifecycle-hooks.js';
|
|
18
18
|
export interface AgentRelayClientOptions {
|
|
19
19
|
baseUrl: string;
|
|
20
20
|
apiKey?: string;
|
|
@@ -31,6 +31,16 @@ export interface AgentRelayClientOptions {
|
|
|
31
31
|
*/
|
|
32
32
|
eventBus?: EventBus<AgentRelayEvents>;
|
|
33
33
|
}
|
|
34
|
+
export interface BrokerExitInfo {
|
|
35
|
+
/** Exit code, or null when the process was killed by signal. */
|
|
36
|
+
code: number | null;
|
|
37
|
+
/** Terminating signal, or null when the process exited normally. */
|
|
38
|
+
signal: NodeJS.Signals | null;
|
|
39
|
+
/** PID of the managed broker process that exited. */
|
|
40
|
+
pid: number | undefined;
|
|
41
|
+
/** Recent stderr lines captured from the managed broker process. */
|
|
42
|
+
recentStderr: string[];
|
|
43
|
+
}
|
|
34
44
|
export interface AgentRelayBrokerInitArgs {
|
|
35
45
|
/** Optional HTTP API port for dashboard proxy (0 = disabled). */
|
|
36
46
|
apiPort?: number;
|
|
@@ -81,12 +91,15 @@ export interface WorkerStreamSubscriptionOptions {
|
|
|
81
91
|
/** Sequence offset to pass to the broker event stream when connecting. */
|
|
82
92
|
sinceSeq?: number;
|
|
83
93
|
}
|
|
94
|
+
type BrokerExitListener = (info: BrokerExitInfo) => void;
|
|
84
95
|
export declare class AgentRelayClient {
|
|
85
96
|
private readonly transport;
|
|
86
97
|
/** Set after spawn() — the managed child process. */
|
|
87
98
|
private child;
|
|
88
99
|
/** Lease renewal timer (only for spawned brokers). */
|
|
89
100
|
private leaseTimer;
|
|
101
|
+
private brokerExitInfo;
|
|
102
|
+
private brokerExitListeners;
|
|
90
103
|
workspaceKey?: string;
|
|
91
104
|
/** Resolved broker URL — captured so call-site lifecycle contexts can surface it. */
|
|
92
105
|
readonly baseUrl: string;
|
|
@@ -98,9 +111,16 @@ export declare class AgentRelayClient {
|
|
|
98
111
|
* function. Equivalent to `client.eventBus.addListener(...)` but mirrors
|
|
99
112
|
* the `AgentRelay` facade API so direct-client callers don't need to
|
|
100
113
|
* reach through `.eventBus`.
|
|
114
|
+
*
|
|
115
|
+
* `beforeAgentSpawn` is the one event whose handler may return a
|
|
116
|
+
* `SpawnPatch` to mutate the spawn input — the dedicated overload
|
|
117
|
+
* keeps that contract type-safe without forcing other events to accept
|
|
118
|
+
* non-void returns.
|
|
101
119
|
*/
|
|
120
|
+
addListener(event: 'beforeAgentSpawn', handler: BeforeAgentSpawnHandler): () => void;
|
|
102
121
|
addListener<K extends keyof AgentRelayEvents>(event: K, handler: (...args: AgentRelayEvents[K]) => void | Promise<void>): () => void;
|
|
103
122
|
/** Remove a previously-registered listener. */
|
|
123
|
+
removeListener(event: 'beforeAgentSpawn', handler: BeforeAgentSpawnHandler): void;
|
|
104
124
|
removeListener<K extends keyof AgentRelayEvents>(event: K, handler: (...args: AgentRelayEvents[K]) => void | Promise<void>): void;
|
|
105
125
|
/**
|
|
106
126
|
* Fold `beforeAgentSpawn` patches into the input. Listeners run in
|
|
@@ -143,6 +163,13 @@ export declare class AgentRelayClient {
|
|
|
143
163
|
connectEvents(sinceSeq?: number): void;
|
|
144
164
|
disconnectEvents(): void;
|
|
145
165
|
onEvent(listener: (event: BrokerEvent) => void): () => void;
|
|
166
|
+
/**
|
|
167
|
+
* Subscribe to managed broker child-process exit.
|
|
168
|
+
*
|
|
169
|
+
* Clients created with `new AgentRelayClient(...)` or `connect()` do not own a
|
|
170
|
+
* broker child process, so this is a no-op for them.
|
|
171
|
+
*/
|
|
172
|
+
onBrokerExit(listener: BrokerExitListener): () => void;
|
|
146
173
|
queryEvents(filter?: {
|
|
147
174
|
kind?: string;
|
|
148
175
|
name?: string;
|
|
@@ -239,6 +266,8 @@ export declare class AgentRelayClient {
|
|
|
239
266
|
getConfig(): Promise<{
|
|
240
267
|
workspaceKey?: string;
|
|
241
268
|
}>;
|
|
269
|
+
private notifyBrokerExit;
|
|
270
|
+
private installManagedBrokerExitHandler;
|
|
242
271
|
}
|
|
243
272
|
declare function drainBrokerStdioAfterStartup(child: ChildProcess): void;
|
|
244
273
|
/** @internal Test-only hooks; not part of the public SDK API. */
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAI9D,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,YAAY,EACZ,qBAAqB,EAErB,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,cAAc,EACf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAEV,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,SAAS,EACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAGV,gBAAgB,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -104,6 +104,8 @@ export class AgentRelayClient {
|
|
|
104
104
|
child = null;
|
|
105
105
|
/** Lease renewal timer (only for spawned brokers). */
|
|
106
106
|
leaseTimer = null;
|
|
107
|
+
brokerExitInfo = null;
|
|
108
|
+
brokerExitListeners = new Set();
|
|
107
109
|
workspaceKey;
|
|
108
110
|
/** Resolved broker URL — captured so call-site lifecycle contexts can surface it. */
|
|
109
111
|
baseUrl;
|
|
@@ -119,16 +121,9 @@ export class AgentRelayClient {
|
|
|
119
121
|
requestTimeoutMs: options.requestTimeoutMs,
|
|
120
122
|
});
|
|
121
123
|
}
|
|
122
|
-
/**
|
|
123
|
-
* Register a listener on the client's event bus. Returns an unsubscribe
|
|
124
|
-
* function. Equivalent to `client.eventBus.addListener(...)` but mirrors
|
|
125
|
-
* the `AgentRelay` facade API so direct-client callers don't need to
|
|
126
|
-
* reach through `.eventBus`.
|
|
127
|
-
*/
|
|
128
124
|
addListener(event, handler) {
|
|
129
125
|
return this.eventBus.addListener(event, handler);
|
|
130
126
|
}
|
|
131
|
-
/** Remove a previously-registered listener. */
|
|
132
127
|
removeListener(event, handler) {
|
|
133
128
|
this.eventBus.removeListener(event, handler);
|
|
134
129
|
}
|
|
@@ -252,6 +247,7 @@ export class AgentRelayClient {
|
|
|
252
247
|
...(options?.eventBus ? { eventBus: options.eventBus } : {}),
|
|
253
248
|
});
|
|
254
249
|
client.child = child;
|
|
250
|
+
client.installManagedBrokerExitHandler(child, stderrLines);
|
|
255
251
|
// The broker prints "API listening on …" the moment its TCP listener is
|
|
256
252
|
// bound, but it still needs to complete a Relaycast handshake before
|
|
257
253
|
// `getSession()` will return. Two failure modes to handle:
|
|
@@ -288,18 +284,13 @@ export class AgentRelayClient {
|
|
|
288
284
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
289
285
|
}
|
|
290
286
|
}
|
|
291
|
-
client.
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
client.
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
if (client.leaseTimer) {
|
|
299
|
-
clearInterval(client.leaseTimer);
|
|
300
|
-
client.leaseTimer = null;
|
|
301
|
-
}
|
|
302
|
-
});
|
|
287
|
+
if (!client.brokerExitInfo) {
|
|
288
|
+
client.connectEvents();
|
|
289
|
+
// Renew the owner lease so the broker doesn't auto-shutdown
|
|
290
|
+
client.leaseTimer = setInterval(() => {
|
|
291
|
+
client.renewLease().catch(() => { });
|
|
292
|
+
}, 60_000);
|
|
293
|
+
}
|
|
303
294
|
return client;
|
|
304
295
|
}
|
|
305
296
|
/** PID of the managed broker process, if spawned locally. */
|
|
@@ -325,6 +316,34 @@ export class AgentRelayClient {
|
|
|
325
316
|
onEvent(listener) {
|
|
326
317
|
return this.transport.onEvent(listener);
|
|
327
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Subscribe to managed broker child-process exit.
|
|
321
|
+
*
|
|
322
|
+
* Clients created with `new AgentRelayClient(...)` or `connect()` do not own a
|
|
323
|
+
* broker child process, so this is a no-op for them.
|
|
324
|
+
*/
|
|
325
|
+
onBrokerExit(listener) {
|
|
326
|
+
if (!this.child && !this.brokerExitInfo) {
|
|
327
|
+
return () => { };
|
|
328
|
+
}
|
|
329
|
+
this.brokerExitListeners.add(listener);
|
|
330
|
+
if (this.brokerExitInfo) {
|
|
331
|
+
const info = cloneBrokerExitInfo(this.brokerExitInfo);
|
|
332
|
+
queueMicrotask(() => {
|
|
333
|
+
if (this.brokerExitListeners.has(listener)) {
|
|
334
|
+
try {
|
|
335
|
+
listener(info);
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
// Listener failures should not interfere with SDK cleanup.
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
return () => {
|
|
344
|
+
this.brokerExitListeners.delete(listener);
|
|
345
|
+
};
|
|
346
|
+
}
|
|
328
347
|
queryEvents(filter) {
|
|
329
348
|
return this.transport.queryEvents(filter);
|
|
330
349
|
}
|
|
@@ -650,6 +669,42 @@ export class AgentRelayClient {
|
|
|
650
669
|
async getConfig() {
|
|
651
670
|
return this.transport.request('/api/config');
|
|
652
671
|
}
|
|
672
|
+
notifyBrokerExit(info) {
|
|
673
|
+
if (this.brokerExitInfo)
|
|
674
|
+
return;
|
|
675
|
+
this.brokerExitInfo = cloneBrokerExitInfo(info);
|
|
676
|
+
for (const listener of this.brokerExitListeners) {
|
|
677
|
+
try {
|
|
678
|
+
listener(cloneBrokerExitInfo(info));
|
|
679
|
+
}
|
|
680
|
+
catch {
|
|
681
|
+
// Listener failures should not interfere with SDK cleanup.
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
installManagedBrokerExitHandler(child, stderrLines) {
|
|
686
|
+
const handleExit = (code, signal) => {
|
|
687
|
+
this.notifyBrokerExit({
|
|
688
|
+
code,
|
|
689
|
+
signal,
|
|
690
|
+
pid: child.pid,
|
|
691
|
+
recentStderr: [...stderrLines],
|
|
692
|
+
});
|
|
693
|
+
this.disconnectEvents();
|
|
694
|
+
if (this.leaseTimer) {
|
|
695
|
+
clearInterval(this.leaseTimer);
|
|
696
|
+
this.leaseTimer = null;
|
|
697
|
+
}
|
|
698
|
+
if (this.child === child) {
|
|
699
|
+
this.child = null;
|
|
700
|
+
}
|
|
701
|
+
};
|
|
702
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
703
|
+
handleExit(child.exitCode, child.signalCode);
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
child.once('exit', handleExit);
|
|
707
|
+
}
|
|
653
708
|
}
|
|
654
709
|
// ── Helpers ──────────────────────────────────────────────────────────────
|
|
655
710
|
/**
|
|
@@ -727,6 +782,12 @@ function pushBufferedLine(lines, line) {
|
|
|
727
782
|
lines.splice(0, lines.length - 40);
|
|
728
783
|
}
|
|
729
784
|
}
|
|
785
|
+
function cloneBrokerExitInfo(info) {
|
|
786
|
+
return {
|
|
787
|
+
...info,
|
|
788
|
+
recentStderr: [...info.recentStderr],
|
|
789
|
+
};
|
|
790
|
+
}
|
|
730
791
|
function formatBrokerStartupError(message, child, debug) {
|
|
731
792
|
const details = [
|
|
732
793
|
`pid=${child.pid ?? 'unknown'}`,
|