@comput/pi-intercom 0.3.0 → 0.4.2
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 +137 -25
- package/dist/activity.d.ts +12 -0
- package/dist/activity.js +73 -0
- package/dist/activity.js.map +1 -0
- package/dist/config.d.ts +39 -0
- package/dist/config.js +182 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +186 -0
- package/dist/index.js.map +1 -0
- package/dist/launcher.d.ts +17 -0
- package/dist/launcher.js +77 -0
- package/dist/launcher.js.map +1 -0
- package/dist/monitor-launcher.d.ts +17 -0
- package/dist/monitor-launcher.js +136 -0
- package/dist/monitor-launcher.js.map +1 -0
- package/dist/monitor-view.d.ts +6 -0
- package/dist/monitor-view.js +134 -0
- package/dist/monitor-view.js.map +1 -0
- package/dist/monitor.d.ts +22 -0
- package/dist/monitor.js +171 -0
- package/dist/monitor.js.map +1 -0
- package/dist/observability.d.ts +79 -0
- package/dist/observability.js +208 -0
- package/dist/observability.js.map +1 -0
- package/dist/reports.d.ts +12 -0
- package/dist/reports.js +160 -0
- package/dist/reports.js.map +1 -0
- package/dist/runtime.d.ts +59 -0
- package/dist/runtime.js +458 -0
- package/dist/runtime.js.map +1 -0
- package/dist/snapshot.d.ts +15 -0
- package/dist/snapshot.js +128 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/transport.d.ts +24 -0
- package/dist/transport.js +122 -0
- package/dist/transport.js.map +1 -0
- package/dist/worker-status.d.ts +26 -0
- package/dist/worker-status.js +76 -0
- package/dist/worker-status.js.map +1 -0
- package/package.json +13 -7
- package/references/observability.md +66 -60
- package/references/roadmap.md +68 -0
- package/src/activity.ts +66 -0
- package/src/config.ts +1 -1
- package/src/index.ts +51 -23
- package/src/monitor-launcher.ts +110 -0
- package/src/monitor-view.ts +123 -0
- package/src/monitor.ts +143 -0
- package/src/observability.ts +6 -1
- package/src/reports.ts +122 -0
- package/src/runtime.ts +45 -7
- package/src/{dashboard.ts → snapshot.ts} +9 -60
- package/src/transport.ts +11 -2
- package/src/worker-status.ts +66 -0
- package/dashboard/app.js +0 -182
- package/dashboard/index.html +0 -41
- package/dashboard/style.css +0 -82
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { LocalObserver, LOG_LIMITS, observationError } from './observability.js';
|
|
4
|
+
import { ConfigStore, coordinator, directory, fail, named, requireCoordinator } from './config.js';
|
|
5
|
+
import { listen, send, reportPayload } from './transport.js';
|
|
6
|
+
import { saveWorkerReport } from './reports.js';
|
|
7
|
+
import { readObservationSnapshot } from './snapshot.js';
|
|
8
|
+
import { workerStatusPage } from './worker-status.js';
|
|
9
|
+
export const UNSUPPORTED_CANCELLATION = 'Unsupported Pi host: stop_worker and close_worker are disabled. Pi 0.84.4 extension abort does not cancel retry backoff/continuations; graceful shutdown cannot guarantee no queued work restarts. No cancellation or shutdown was performed. See references/implementation-blocker.md. A verified supported host API is required (no version-only override).';
|
|
10
|
+
export class Intercom {
|
|
11
|
+
host;
|
|
12
|
+
options;
|
|
13
|
+
store;
|
|
14
|
+
endpoint;
|
|
15
|
+
active = false;
|
|
16
|
+
generation = 0;
|
|
17
|
+
initialId = '';
|
|
18
|
+
responsibility;
|
|
19
|
+
observer;
|
|
20
|
+
closing;
|
|
21
|
+
reportWrites = Promise.resolve();
|
|
22
|
+
pendingReports = 0;
|
|
23
|
+
captureObserver() {
|
|
24
|
+
const observer = this.observer;
|
|
25
|
+
return (event, metadata = {}) => {
|
|
26
|
+
try {
|
|
27
|
+
observer?.record(event, metadata);
|
|
28
|
+
}
|
|
29
|
+
catch { /* Logging cannot affect communication. */ }
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
recordObservation(event, metadata = {}) { this.captureObserver()(event, metadata); }
|
|
33
|
+
constructor(host, options) {
|
|
34
|
+
this.host = host;
|
|
35
|
+
this.options = options;
|
|
36
|
+
}
|
|
37
|
+
id() {
|
|
38
|
+
const id = this.host.sessionId();
|
|
39
|
+
if (!this.active || id !== this.initialId)
|
|
40
|
+
fail('session is inactive or replaced');
|
|
41
|
+
return id;
|
|
42
|
+
}
|
|
43
|
+
validity() {
|
|
44
|
+
const generation = this.generation;
|
|
45
|
+
this.id();
|
|
46
|
+
return () => {
|
|
47
|
+
this.id();
|
|
48
|
+
if (generation !== this.generation)
|
|
49
|
+
fail('runtime lifecycle replaced');
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
async start() {
|
|
53
|
+
if (this.closing)
|
|
54
|
+
await this.closing;
|
|
55
|
+
if (this.active)
|
|
56
|
+
fail('runtime already active');
|
|
57
|
+
this.initialId = this.host.sessionId();
|
|
58
|
+
this.active = true;
|
|
59
|
+
const generation = ++this.generation, assertValid = this.validity();
|
|
60
|
+
let record = this.captureObserver();
|
|
61
|
+
try {
|
|
62
|
+
const discovered = await ConfigStore.discover(this.host.cwd);
|
|
63
|
+
assertValid();
|
|
64
|
+
this.store = this.options.store?.(discovered?.root ?? this.host.cwd) ?? discovered ?? new ConfigStore(this.host.cwd);
|
|
65
|
+
try {
|
|
66
|
+
this.observer = this.options.observe ? this.options.observe(this.store.root, this.initialId) : new LocalObserver(this.store.root, this.initialId);
|
|
67
|
+
}
|
|
68
|
+
catch { /* Logging is optional on failure. */ }
|
|
69
|
+
record = this.captureObserver();
|
|
70
|
+
record('runtime.starting');
|
|
71
|
+
const previous = discovered ? await this.store.read() : undefined;
|
|
72
|
+
assertValid();
|
|
73
|
+
const own = previous?.agents.find(a => a.sessionId === this.id());
|
|
74
|
+
const endpoint = await (this.options.listen ?? listen)(own?.port, m => { assertValid(); return this.receive(m); });
|
|
75
|
+
try {
|
|
76
|
+
assertValid();
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
await endpoint.close();
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
this.endpoint = endpoint;
|
|
83
|
+
if (!previous) {
|
|
84
|
+
const initialized = await this.store.initialize(this.id(), this.endpoint.port, assertValid);
|
|
85
|
+
if (initialized)
|
|
86
|
+
record('config.changed', { operation: 'initialize', outcome: 'written' });
|
|
87
|
+
}
|
|
88
|
+
const config = await this.store.read();
|
|
89
|
+
assertValid();
|
|
90
|
+
const me = config.agents.find(a => a.sessionId === this.id());
|
|
91
|
+
if (me?.coordinator) {
|
|
92
|
+
try {
|
|
93
|
+
this.observer?.maintain?.();
|
|
94
|
+
}
|
|
95
|
+
catch { /* No cleanup failure affects readiness. */ }
|
|
96
|
+
await this.store.update(this.id(), c => { requireCoordinator(c, this.id()).port = this.endpoint.port; }, assertValid);
|
|
97
|
+
assertValid();
|
|
98
|
+
record('config.changed', { operation: 'port_update', outcome: 'written', port: this.endpoint.port });
|
|
99
|
+
try {
|
|
100
|
+
await this.reload();
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
assertValid();
|
|
104
|
+
this.host.notify(`Name/responsibility synchronization failed: ${String(e)}`);
|
|
105
|
+
}
|
|
106
|
+
assertValid();
|
|
107
|
+
this.host.notify(`Intercom Coordinator ready at 127.0.0.1:${this.endpoint.port}; waiting for user input.`);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
if (me) {
|
|
111
|
+
try {
|
|
112
|
+
await this.reload();
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
assertValid();
|
|
116
|
+
this.host.notify(`Name/responsibility synchronization failed: ${String(e)}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
assertValid();
|
|
120
|
+
try {
|
|
121
|
+
if (me)
|
|
122
|
+
await this.report();
|
|
123
|
+
else {
|
|
124
|
+
const projectDirectory = await directory(this.store.root, this.host.cwd);
|
|
125
|
+
assertValid();
|
|
126
|
+
await this.transmit(coordinator(config).name, 'registration', { port: this.endpoint.port, projectDirectory });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (e) {
|
|
130
|
+
assertValid();
|
|
131
|
+
this.host.notify(`Coordinator unreachable/registration failed; worker remains reachable: ${String(e)}. No retry. Anonymous registration repeat is an unresolved contract; use explicit Pi /reload to restart this extension, not report_status.`);
|
|
132
|
+
}
|
|
133
|
+
assertValid();
|
|
134
|
+
this.host.notify(`Intercom worker ready at 127.0.0.1:${this.endpoint.port}; waiting for explicit work.`);
|
|
135
|
+
}
|
|
136
|
+
record('runtime.ready', { port: this.endpoint.port, role: me?.coordinator ? 'coordinator' : me ? 'worker' : 'anonymous', busy: this.host.busy(), outcome: 'ready' });
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
if (generation === this.generation) {
|
|
140
|
+
record('runtime.failed', { errorCode: observationError(e), outcome: 'failed' });
|
|
141
|
+
await this.close();
|
|
142
|
+
}
|
|
143
|
+
throw e;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async close() {
|
|
147
|
+
if (this.closing)
|
|
148
|
+
return this.closing;
|
|
149
|
+
this.recordObservation('runtime.closed');
|
|
150
|
+
const observer = this.observer;
|
|
151
|
+
this.observer = undefined;
|
|
152
|
+
this.active = false;
|
|
153
|
+
this.generation++;
|
|
154
|
+
const endpoint = this.endpoint;
|
|
155
|
+
this.endpoint = undefined;
|
|
156
|
+
this.responsibility = undefined;
|
|
157
|
+
const closing = (async () => {
|
|
158
|
+
try {
|
|
159
|
+
if (endpoint)
|
|
160
|
+
await endpoint.close();
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
if (observer) {
|
|
164
|
+
let timer;
|
|
165
|
+
try {
|
|
166
|
+
// Only shutdown waits, and only for this bounded deadline. Already-issued I/O cannot be cancelled.
|
|
167
|
+
await Promise.race([
|
|
168
|
+
Promise.resolve().then(() => observer.close()).catch(() => { }),
|
|
169
|
+
new Promise(resolve => { timer = setTimeout(resolve, LOG_LIMITS.closeTimeoutMs); }),
|
|
170
|
+
]);
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
if (timer)
|
|
174
|
+
clearTimeout(timer);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
})();
|
|
179
|
+
this.closing = closing;
|
|
180
|
+
try {
|
|
181
|
+
await closing;
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
if (this.closing === closing)
|
|
185
|
+
this.closing = undefined;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
async state() {
|
|
189
|
+
const assertValid = this.validity();
|
|
190
|
+
const id = this.id(), config = await this.store.read();
|
|
191
|
+
assertValid();
|
|
192
|
+
return { id, config, me: config.agents.find(a => a.sessionId === id) };
|
|
193
|
+
}
|
|
194
|
+
/** Accept old configs, but retire the removed browser dashboard's discovery metadata. */
|
|
195
|
+
async retireDashboardMetadata() {
|
|
196
|
+
const record = this.captureObserver(), assertValid = this.validity();
|
|
197
|
+
const { id, config } = await this.state();
|
|
198
|
+
assertValid();
|
|
199
|
+
if (requireCoordinator(config, id).dashboardPort === undefined)
|
|
200
|
+
return;
|
|
201
|
+
await this.store.update(id, c => { delete requireCoordinator(c, id).dashboardPort; }, assertValid);
|
|
202
|
+
record('config.changed', { outcome: 'written' });
|
|
203
|
+
}
|
|
204
|
+
async reload() {
|
|
205
|
+
const record = this.captureObserver();
|
|
206
|
+
const assertValid = this.validity();
|
|
207
|
+
const { me } = await this.state();
|
|
208
|
+
assertValid();
|
|
209
|
+
if (!me)
|
|
210
|
+
fail('worker not configured; configure_worker must run before reload_worker');
|
|
211
|
+
this.responsibility = { ...me };
|
|
212
|
+
await this.host.setName(me.name);
|
|
213
|
+
assertValid();
|
|
214
|
+
record('config.reloaded', { role: me.coordinator ? 'coordinator' : 'worker' });
|
|
215
|
+
this.host.notify(`Intercom responsibility loaded for ${me.name}; no work turn started.`);
|
|
216
|
+
}
|
|
217
|
+
async transmit(to, kind, payload = {}) {
|
|
218
|
+
const record = this.captureObserver();
|
|
219
|
+
const assertValid = this.validity();
|
|
220
|
+
const { id, config } = await this.state();
|
|
221
|
+
assertValid();
|
|
222
|
+
const target = named(config, to), correlationId = randomUUID();
|
|
223
|
+
const metadata = { peerSessionId: target.sessionId, peerName: target.name, correlationId, kind };
|
|
224
|
+
record('transport.send', { ...metadata, outcome: 'attempted' });
|
|
225
|
+
try {
|
|
226
|
+
await (this.options.send ?? send)(target.port, { version: 1, from: id, to: target.sessionId, kind, payload, correlationId });
|
|
227
|
+
record('transport.receipt', { ...metadata, outcome: 'http_receipt' });
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
record('transport.failed', { ...metadata, outcome: 'failed', errorCode: observationError(error) });
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
async report() {
|
|
235
|
+
const assertValid = this.validity();
|
|
236
|
+
const { config, me } = await this.state();
|
|
237
|
+
assertValid();
|
|
238
|
+
if (me?.coordinator)
|
|
239
|
+
fail('report_status is worker-only');
|
|
240
|
+
if (!this.endpoint)
|
|
241
|
+
fail('endpoint unavailable');
|
|
242
|
+
await this.transmit(coordinator(config).name, 'status', { port: this.endpoint.port, busy: this.host.busy() });
|
|
243
|
+
}
|
|
244
|
+
async receive(message) {
|
|
245
|
+
const record = this.captureObserver();
|
|
246
|
+
const metadata = { peerSessionId: message.from, correlationId: message.correlationId, kind: message.kind };
|
|
247
|
+
record('transport.received', metadata);
|
|
248
|
+
try {
|
|
249
|
+
await this.handleReceive(message);
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
record('transport.rejected', { ...metadata, outcome: 'handler_failed', errorCode: observationError(error) });
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async handleReceive(message) {
|
|
257
|
+
const record = this.captureObserver();
|
|
258
|
+
const assertValid = this.validity();
|
|
259
|
+
const { id, config, me } = await this.state();
|
|
260
|
+
assertValid();
|
|
261
|
+
if (message.to !== id)
|
|
262
|
+
fail('recipient session ID mismatch (stale endpoint)');
|
|
263
|
+
const sender = config.agents.find(a => a.sessionId === message.from);
|
|
264
|
+
const busy = this.host.busy();
|
|
265
|
+
const metadata = { peerSessionId: message.from, peerName: sender?.name, correlationId: message.correlationId, kind: message.kind, busy };
|
|
266
|
+
const notify = (purpose, content) => {
|
|
267
|
+
assertValid();
|
|
268
|
+
record('host.submission', { ...metadata, outcome: 'attempted' });
|
|
269
|
+
try {
|
|
270
|
+
this.host.deliver(`[Intercom ${purpose} from ${sender?.name ?? 'unconfigured worker'} (${message.from})]\n${content}`, busy);
|
|
271
|
+
// A synchronous return is not Pi queue acceptance or model completion.
|
|
272
|
+
record('host.submission', { ...metadata, outcome: 'returned' });
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
record('host.submission', { ...metadata, outcome: 'failed', errorCode: observationError(error) });
|
|
276
|
+
throw error;
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
if (message.kind === 'registration' || message.kind === 'status') {
|
|
280
|
+
requireCoordinator(config, id);
|
|
281
|
+
if (sender?.coordinator)
|
|
282
|
+
fail('coordinator cannot report as worker');
|
|
283
|
+
if (message.kind === 'registration') {
|
|
284
|
+
const projectDirectory = await directory(this.store.root, message.payload.projectDirectory);
|
|
285
|
+
// No pending map, placeholder or configuration mutation.
|
|
286
|
+
record('registration.received', { ...metadata, port: message.payload.port });
|
|
287
|
+
notify('registration', JSON.stringify({ sessionId: message.from, port: message.payload.port, projectDirectory }) + '\nThis is connection information, not a work assignment. Configure explicitly, then reload separately.');
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
if (sender)
|
|
291
|
+
await this.store.update(id, c => {
|
|
292
|
+
const entry = c.agents.find(a => a.sessionId === message.from && !a.coordinator);
|
|
293
|
+
if (entry)
|
|
294
|
+
entry.port = message.payload.port;
|
|
295
|
+
}, assertValid);
|
|
296
|
+
record('status.received', { ...metadata, busy: message.payload.busy, port: message.payload.port });
|
|
297
|
+
if (sender)
|
|
298
|
+
record('config.changed', { operation: 'port_update', peerSessionId: message.from, port: message.payload.port, outcome: 'written' });
|
|
299
|
+
notify('status', JSON.stringify({ sessionId: message.from, port: message.payload.port, busy: message.payload.busy, configured: !!sender }));
|
|
300
|
+
}
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
if (message.kind === 'report') {
|
|
304
|
+
requireCoordinator(config, id);
|
|
305
|
+
if (!sender || sender.coordinator)
|
|
306
|
+
fail('work reports require a configured worker sender');
|
|
307
|
+
const payload = reportPayload(message.payload);
|
|
308
|
+
if (this.pendingReports >= 64)
|
|
309
|
+
fail('report queue full; no report stored');
|
|
310
|
+
this.pendingReports++;
|
|
311
|
+
const pending = this.reportWrites.then(async () => {
|
|
312
|
+
assertValid();
|
|
313
|
+
const fresh = await this.state();
|
|
314
|
+
requireCoordinator(fresh.config, id);
|
|
315
|
+
if (!fresh.config.agents.some(agent => agent.sessionId === message.from && !agent.coordinator))
|
|
316
|
+
fail('reporting worker is no longer configured');
|
|
317
|
+
await saveWorkerReport(this.store.root, { version: 1, sessionId: message.from, ...payload, updatedAt: new Date().toISOString() }, assertValid);
|
|
318
|
+
assertValid();
|
|
319
|
+
try {
|
|
320
|
+
notify('worker report', `Report: ${payload.status}\n${payload.summary}\nThis is a worker-authored public report, not approval or verified completion. Evaluate it before deciding any next step. Clearing retires the report only; it does not resume or complete work.`);
|
|
321
|
+
}
|
|
322
|
+
catch {
|
|
323
|
+
fail('Report stored, but coordinator notification failed or became uncertain; do not blindly resend');
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
this.reportWrites = pending.catch(() => { }).finally(() => { this.pendingReports--; });
|
|
327
|
+
await pending;
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
if (message.kind === 'message') {
|
|
331
|
+
if (!sender || !me)
|
|
332
|
+
fail('agent messaging requires configured sender and recipient; anonymous permissions TODO');
|
|
333
|
+
if (!this.responsibility)
|
|
334
|
+
fail('worker must load responsibility before receiving work');
|
|
335
|
+
notify('agent message', message.payload.message);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
if (!sender?.coordinator)
|
|
339
|
+
fail('control requires current coordinator sender session ID');
|
|
340
|
+
if (me?.coordinator)
|
|
341
|
+
fail('worker control cannot target coordinator');
|
|
342
|
+
if (message.kind === 'stop' || message.kind === 'close')
|
|
343
|
+
fail(UNSUPPORTED_CANCELLATION);
|
|
344
|
+
if (message.kind === 'reload') {
|
|
345
|
+
await this.reload();
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (message.kind === 'request_status') {
|
|
349
|
+
// Independent one-way report, never a synchronous status in the HTTP response.
|
|
350
|
+
setImmediate(() => {
|
|
351
|
+
try {
|
|
352
|
+
assertValid();
|
|
353
|
+
}
|
|
354
|
+
catch {
|
|
355
|
+
return;
|
|
356
|
+
} // Closed/replaced requests cannot report for a new lifecycle.
|
|
357
|
+
void this.report().catch(e => {
|
|
358
|
+
try {
|
|
359
|
+
assertValid();
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
this.host.notify(`Status report failed: ${String(e)}`);
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
fail('unsupported control');
|
|
370
|
+
}
|
|
371
|
+
async tool(operation, args) {
|
|
372
|
+
const record = this.captureObserver();
|
|
373
|
+
const assertValid = this.validity();
|
|
374
|
+
const { id, config, me } = await this.state();
|
|
375
|
+
assertValid();
|
|
376
|
+
if (operation === 'worker_status') {
|
|
377
|
+
if (!me)
|
|
378
|
+
fail('worker_status requires a configured session');
|
|
379
|
+
const snapshot = await readObservationSnapshot(this.store.root);
|
|
380
|
+
assertValid();
|
|
381
|
+
return workerStatusPage(snapshot, { name: args.name, offset: args.offset, limit: args.limit });
|
|
382
|
+
}
|
|
383
|
+
if (operation === 'list') {
|
|
384
|
+
if (!me)
|
|
385
|
+
fail('anonymous intercom_list permissions unresolved (TODO); no coordinator privileges');
|
|
386
|
+
return { ...config, agents: config.agents.map(({ dashboardPort: _retired, ...agent }) => agent) };
|
|
387
|
+
}
|
|
388
|
+
if (operation === 'report_status') {
|
|
389
|
+
await this.report();
|
|
390
|
+
return { accepted: true };
|
|
391
|
+
}
|
|
392
|
+
if (operation === 'report_work') {
|
|
393
|
+
if (!me || me.coordinator || !this.responsibility)
|
|
394
|
+
fail('report_work requires a configured, responsibility-loaded worker');
|
|
395
|
+
const payload = reportPayload(args);
|
|
396
|
+
await this.transmit(coordinator(config).name, 'report', payload);
|
|
397
|
+
return { accepted: true, coordinatorEvaluation: 'not awaited' };
|
|
398
|
+
}
|
|
399
|
+
if (operation === 'send') {
|
|
400
|
+
if (!me || !this.responsibility)
|
|
401
|
+
fail('anonymous/unloaded worker cannot send agent messages (permissions TODO)');
|
|
402
|
+
await this.transmit(args.to, 'message', { message: args.message });
|
|
403
|
+
return { accepted: true, completion: 'not awaited' };
|
|
404
|
+
}
|
|
405
|
+
requireCoordinator(config, id);
|
|
406
|
+
if (operation === 'stop_worker' || operation === 'close_worker')
|
|
407
|
+
fail(UNSUPPORTED_CANCELLATION);
|
|
408
|
+
if (operation === 'configure_worker') {
|
|
409
|
+
await this.store.configure(id, args, assertValid);
|
|
410
|
+
record('config.changed', { operation: 'configure_worker', peerSessionId: args.sessionId, peerName: args.name, outcome: 'written' });
|
|
411
|
+
return { written: true, reloaded: false };
|
|
412
|
+
}
|
|
413
|
+
if (operation === 'set_multiplexer') {
|
|
414
|
+
await this.store.update(id, c => { c.multiplexer = args.multiplexer; }, assertValid);
|
|
415
|
+
record('config.changed', { operation: 'set_multiplexer', outcome: 'written' });
|
|
416
|
+
return { written: true };
|
|
417
|
+
}
|
|
418
|
+
if (operation === 'create_worker') {
|
|
419
|
+
const relative = await directory(this.store.root, args.projectDirectory ?? '.');
|
|
420
|
+
assertValid();
|
|
421
|
+
return this.launchObserved({ multiplexer: config.multiplexer, cwd: path.resolve(this.store.root, relative) });
|
|
422
|
+
}
|
|
423
|
+
const target = named(config, args.to);
|
|
424
|
+
if (target.coordinator)
|
|
425
|
+
fail('operation requires a worker target');
|
|
426
|
+
if (operation === 'reload_worker' || operation === 'request_status') {
|
|
427
|
+
await this.transmit(target.name, operation === 'reload_worker' ? 'reload' : 'request_status');
|
|
428
|
+
return { accepted: true, completion: 'not awaited' };
|
|
429
|
+
}
|
|
430
|
+
if (operation === 'resume_worker') {
|
|
431
|
+
const relative = await directory(this.store.root, target.projectDirectory);
|
|
432
|
+
assertValid();
|
|
433
|
+
return this.launchObserved({ multiplexer: config.multiplexer, cwd: path.resolve(this.store.root, relative), sessionId: target.sessionId });
|
|
434
|
+
}
|
|
435
|
+
if (operation === 'remove_worker') {
|
|
436
|
+
// No live process claim: the caller must explicitly ensure closure first.
|
|
437
|
+
await this.store.update(id, c => { c.agents = c.agents.filter(a => a.sessionId !== target.sessionId); }, assertValid);
|
|
438
|
+
record('config.changed', { operation: 'remove_worker', peerSessionId: target.sessionId, peerName: target.name, outcome: 'removed' });
|
|
439
|
+
return { removed: true, processStopped: false, sessionDeleted: false };
|
|
440
|
+
}
|
|
441
|
+
fail(`unknown operation ${operation}`);
|
|
442
|
+
}
|
|
443
|
+
async launchObserved(request) {
|
|
444
|
+
const record = this.captureObserver();
|
|
445
|
+
const metadata = { operation: request.sessionId ? 'resume_worker' : 'create_worker', peerSessionId: request.sessionId };
|
|
446
|
+
record('launch.result', { ...metadata, outcome: 'attempted' });
|
|
447
|
+
try {
|
|
448
|
+
const result = await this.options.launch(request);
|
|
449
|
+
record('launch.result', { ...metadata, outcome: 'returned' });
|
|
450
|
+
return result;
|
|
451
|
+
}
|
|
452
|
+
catch (error) {
|
|
453
|
+
record('launch.result', { ...metadata, outcome: 'failed', errorCode: observationError(error) });
|
|
454
|
+
throw error;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Config } from './config.js';
|
|
2
|
+
import { type WorkerReport } from './reports.js';
|
|
3
|
+
import { type Observation } from './observability.js';
|
|
4
|
+
export interface ObservationSnapshot {
|
|
5
|
+
version: 1;
|
|
6
|
+
generatedAt: string;
|
|
7
|
+
staleAfterMs: number;
|
|
8
|
+
config: Pick<Config, 'multiplexer' | 'agents'> | null;
|
|
9
|
+
events: Observation[];
|
|
10
|
+
reports?: WorkerReport[];
|
|
11
|
+
truncated: boolean;
|
|
12
|
+
errors: string[];
|
|
13
|
+
}
|
|
14
|
+
/** Bounded, sanitized local evidence, independent of any UI or HTTP server. */
|
|
15
|
+
export declare function readObservationSnapshot(root: string): Promise<ObservationSnapshot>;
|
package/dist/snapshot.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { constants } from 'node:fs';
|
|
2
|
+
import { lstat, open, opendir, realpath } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { validateConfig } from './config.js';
|
|
5
|
+
import { readWorkerReports } from './reports.js';
|
|
6
|
+
import { LOG_DIRECTORY, LOG_FILE_PATTERN, sanitizeObservation } from './observability.js';
|
|
7
|
+
const CONFIG_BYTES = 1024 * 1024, TAIL_BYTES = 128 * 1024, TOTAL_BYTES = 2 * 1024 * 1024;
|
|
8
|
+
const MAX_FILES = 32, MAX_ENTRIES = 512, MAX_EVENTS = 500, MAX_AGENTS = 256;
|
|
9
|
+
// Only fixed, extension-owned paths are read. Reject symlink/junction components
|
|
10
|
+
// rather than allowing a local log/config link to expose an unrelated file.
|
|
11
|
+
async function confined(root, relative) {
|
|
12
|
+
const base = await realpath(root);
|
|
13
|
+
let current = base;
|
|
14
|
+
for (const segment of relative.split(/[\\/]/)) {
|
|
15
|
+
if (!segment || segment === '.' || segment === '..')
|
|
16
|
+
throw new Error('invalid path');
|
|
17
|
+
current = path.join(current, segment);
|
|
18
|
+
if ((await lstat(current)).isSymbolicLink())
|
|
19
|
+
throw new Error('linked path');
|
|
20
|
+
if (path.relative(current, await realpath(current)) !== '')
|
|
21
|
+
throw new Error('redirected path');
|
|
22
|
+
}
|
|
23
|
+
return current;
|
|
24
|
+
}
|
|
25
|
+
async function boundedRead(file, limit, tail = false) {
|
|
26
|
+
if (!(await lstat(file)).isFile())
|
|
27
|
+
throw new Error('not a file');
|
|
28
|
+
const handle = await open(file, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0));
|
|
29
|
+
try {
|
|
30
|
+
const stat = await handle.stat();
|
|
31
|
+
if (!stat.isFile())
|
|
32
|
+
throw new Error('not a file');
|
|
33
|
+
if (!tail && stat.size > limit)
|
|
34
|
+
throw new Error('file too large');
|
|
35
|
+
const size = Math.min(stat.size, limit), start = tail ? Math.max(0, stat.size - size) : 0;
|
|
36
|
+
const buffer = Buffer.alloc(size);
|
|
37
|
+
const { bytesRead } = await handle.read(buffer, 0, size, start);
|
|
38
|
+
let text = buffer.subarray(0, bytesRead).toString('utf8');
|
|
39
|
+
// Drop potentially partial UTF-8/JSON at both tail boundaries. Writers append
|
|
40
|
+
// complete newline-terminated records; incomplete records are not evidence.
|
|
41
|
+
if (tail) {
|
|
42
|
+
if (start > 0)
|
|
43
|
+
text = text.slice(text.indexOf('\n') + 1);
|
|
44
|
+
text = text.slice(0, text.lastIndexOf('\n') + 1);
|
|
45
|
+
}
|
|
46
|
+
return { text, truncated: stat.size > limit, bytes: bytesRead };
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
await handle.close();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Bounded, sanitized local evidence, independent of any UI or HTTP server. */
|
|
53
|
+
export async function readObservationSnapshot(root) {
|
|
54
|
+
const result = { version: 1, generatedAt: new Date().toISOString(), staleAfterMs: 60000, config: null, events: [], truncated: false, errors: [] };
|
|
55
|
+
try {
|
|
56
|
+
const file = await confined(root, '.pi-intercom/config.json');
|
|
57
|
+
const config = validateConfig(JSON.parse((await boundedRead(file, CONFIG_BYTES)).text));
|
|
58
|
+
result.truncated ||= config.agents.length > MAX_AGENTS;
|
|
59
|
+
result.config = { multiplexer: config.multiplexer, agents: config.agents.slice(0, MAX_AGENTS).map(a => ({
|
|
60
|
+
sessionId: a.sessionId, name: a.name, coordinator: a.coordinator, description: a.description,
|
|
61
|
+
projectDirectory: a.projectDirectory, port: a.port,
|
|
62
|
+
})) };
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
result.errors.push('config_unavailable');
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const directory = await confined(root, LOG_DIRECTORY);
|
|
69
|
+
const files = [];
|
|
70
|
+
const entries = await opendir(directory);
|
|
71
|
+
let scanned = 0;
|
|
72
|
+
for await (const entry of entries) {
|
|
73
|
+
if (++scanned > MAX_ENTRIES) {
|
|
74
|
+
result.truncated = true;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
if (!entry.isFile() || !LOG_FILE_PATTERN.test(entry.name))
|
|
78
|
+
continue;
|
|
79
|
+
try {
|
|
80
|
+
const file = await confined(root, `${LOG_DIRECTORY}/${entry.name}`);
|
|
81
|
+
files.push({ name: entry.name, modified: (await lstat(file)).mtimeMs });
|
|
82
|
+
}
|
|
83
|
+
catch { /* Rotations can remove a file while scanning. */ }
|
|
84
|
+
}
|
|
85
|
+
files.sort((a, b) => b.modified - a.modified || a.name.localeCompare(b.name));
|
|
86
|
+
result.truncated ||= files.length > MAX_FILES;
|
|
87
|
+
let budget = TOTAL_BYTES;
|
|
88
|
+
for (const file of files.slice(0, MAX_FILES)) {
|
|
89
|
+
if (budget <= 0) {
|
|
90
|
+
result.truncated = true;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const resolved = await confined(root, `${LOG_DIRECTORY}/${file.name}`);
|
|
95
|
+
const read = await boundedRead(resolved, Math.min(TAIL_BYTES, budget), true);
|
|
96
|
+
budget -= read.bytes;
|
|
97
|
+
result.truncated ||= read.truncated;
|
|
98
|
+
for (const line of read.text.split('\n')) {
|
|
99
|
+
if (!line)
|
|
100
|
+
continue;
|
|
101
|
+
try {
|
|
102
|
+
const event = sanitizeObservation(JSON.parse(line));
|
|
103
|
+
if (event)
|
|
104
|
+
result.events.push(event);
|
|
105
|
+
}
|
|
106
|
+
catch { /* Ignore malformed/partial/foreign records, never expose raw data. */ }
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
if (!result.errors.includes('log_read_failed'))
|
|
111
|
+
result.errors.push('log_read_failed');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
result.events.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
115
|
+
if (result.events.length > MAX_EVENTS) {
|
|
116
|
+
result.events = result.events.slice(-MAX_EVENTS);
|
|
117
|
+
result.truncated = true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
result.errors.push('logs_unavailable');
|
|
122
|
+
}
|
|
123
|
+
result.reports = result.config
|
|
124
|
+
? await readWorkerReports(root, result.config.agents.filter(agent => !agent.coordinator).map(agent => agent.sessionId))
|
|
125
|
+
: [];
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"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"}
|