@songsid/agend 2.1.0-beta.5 → 2.1.0-beta.7
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/cli.js +35 -4
- package/dist/cli.js.map +1 -1
- package/dist/fleet-context.d.ts +1 -0
- package/dist/fleet-manager.d.ts +5 -0
- package/dist/fleet-manager.js +30 -0
- package/dist/fleet-manager.js.map +1 -1
- package/dist/outbound-handlers.d.ts +3 -0
- package/dist/outbound-handlers.js +25 -0
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/topic-commands.d.ts +5 -1
- package/dist/topic-commands.js +53 -10
- package/dist/topic-commands.js.map +1 -1
- package/dist/web-api.d.ts +1 -0
- package/dist/web-api.js +21 -14
- package/dist/web-api.js.map +1 -1
- package/package.json +1 -1
package/dist/fleet-manager.js
CHANGED
|
@@ -93,6 +93,8 @@ export class FleetManager {
|
|
|
93
93
|
// Topic icon + auto-archive state
|
|
94
94
|
topicIcons = {};
|
|
95
95
|
lastActivity = new Map();
|
|
96
|
+
/** Latest pane-derived execution snapshot reported by each daemon. */
|
|
97
|
+
instanceStateCache = new Map();
|
|
96
98
|
lastInboundUser = new Map(); // instanceName → last username
|
|
97
99
|
// Active "🛑 Cancel" buttons, tracked per button (keyed by messageId) rather
|
|
98
100
|
// than one-per-instance. A button is retired (deleted, with bounded retry) on
|
|
@@ -160,6 +162,7 @@ export class FleetManager {
|
|
|
160
162
|
const instances = Object.keys(this.fleetConfig?.instances ?? {}).map(name => ({
|
|
161
163
|
name,
|
|
162
164
|
status: this.getInstanceStatus(name),
|
|
165
|
+
state: this.getInstanceExecutionState(name),
|
|
163
166
|
ipc: this.instanceIpcClients.has(name),
|
|
164
167
|
costCents: this.costGuard?.getDailyCostCents(name) ?? 0,
|
|
165
168
|
rateLimits: this.statuslineWatcher.getRateLimits(name) ?? null,
|
|
@@ -290,6 +293,25 @@ export class FleetManager {
|
|
|
290
293
|
return "crashed";
|
|
291
294
|
}
|
|
292
295
|
}
|
|
296
|
+
getInstanceExecutionState(name) {
|
|
297
|
+
if (this.lifecycle.isPaused(name))
|
|
298
|
+
return null;
|
|
299
|
+
return this.instanceStateCache.get(name)?.state ?? null;
|
|
300
|
+
}
|
|
301
|
+
cacheInstanceExecutionState(name, msg) {
|
|
302
|
+
const state = msg.state;
|
|
303
|
+
if (state !== "idle" && state !== "working" && state !== "stuck")
|
|
304
|
+
return;
|
|
305
|
+
const previous = this.instanceStateCache.get(name);
|
|
306
|
+
const now = Date.now();
|
|
307
|
+
const numberOr = (value, fallback) => typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
308
|
+
this.instanceStateCache.set(name, {
|
|
309
|
+
state,
|
|
310
|
+
unchangedForMs: numberOr(msg.unchangedForMs, previous?.unchangedForMs ?? 0),
|
|
311
|
+
observedAt: numberOr(msg.observedAt, now),
|
|
312
|
+
stateChangedAt: numberOr(msg.stateChangedAt, previous?.state === state ? previous.stateChangedAt : now),
|
|
313
|
+
});
|
|
314
|
+
}
|
|
293
315
|
/** Single delivery facade: wake an auto-paused CLI before sending to daemon IPC. */
|
|
294
316
|
async deliverToInstance(instanceName, payload) {
|
|
295
317
|
if (this.lifecycle.isPaused(instanceName)) {
|
|
@@ -367,6 +389,7 @@ export class FleetManager {
|
|
|
367
389
|
}
|
|
368
390
|
async stopInstance(name) {
|
|
369
391
|
this.failoverActive.delete(name);
|
|
392
|
+
this.instanceStateCache.delete(name);
|
|
370
393
|
return this.lifecycle.stop(name);
|
|
371
394
|
}
|
|
372
395
|
/** Restart a single instance, reloading fleet.yaml first to pick up config changes. */
|
|
@@ -1532,10 +1555,16 @@ export class FleetManager {
|
|
|
1532
1555
|
else if (msg.type === "fleet_set_description") {
|
|
1533
1556
|
this.handleSetDescription(name, msg);
|
|
1534
1557
|
}
|
|
1558
|
+
else if (msg.type === "instance_state" || msg.type === "instance_state_response") {
|
|
1559
|
+
this.cacheInstanceExecutionState(name, msg);
|
|
1560
|
+
}
|
|
1535
1561
|
}, this.logger, `ipc.message[${name}]`));
|
|
1536
1562
|
// Ask daemon for any sessions that registered before we connected
|
|
1537
1563
|
// (fixes race condition where mcp_ready was broadcast before fleet manager connected)
|
|
1538
1564
|
ipc.send({ type: "query_sessions" });
|
|
1565
|
+
// The initial state transition may have happened before FleetManager
|
|
1566
|
+
// connected, so seed the cache instead of waiting for another transition.
|
|
1567
|
+
ipc.send({ type: "query_instance_state", requestId: `fleet-state-${Date.now()}` });
|
|
1539
1568
|
this.logger.debug({ name }, "Connected to instance IPC");
|
|
1540
1569
|
if (!this.statuslineWatcher.has(name)) {
|
|
1541
1570
|
this.statuslineWatcher.watch(name);
|
|
@@ -4349,6 +4378,7 @@ When users create specialized instances, suggest these configurations:
|
|
|
4349
4378
|
lastActivity: this.lastActivityMs(inst.name) || null,
|
|
4350
4379
|
currentTask,
|
|
4351
4380
|
idle: this.getInstanceIdle(inst.name),
|
|
4381
|
+
state: this.getInstanceExecutionState(inst.name),
|
|
4352
4382
|
};
|
|
4353
4383
|
});
|
|
4354
4384
|
res.setHeader("Access-Control-Allow-Origin", "*");
|