@sechroom/cli 2026.8.1 → 2026.8.3-rc.fc3795ae7
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.js +114 -52
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8975,7 +8975,7 @@ function herdrRequest(socketPath, method, params, timeoutMs = 1e4) {
|
|
|
8975
8975
|
});
|
|
8976
8976
|
}
|
|
8977
8977
|
function herdrStream(socketPath, subscriptions, onEvent, options = {}) {
|
|
8978
|
-
const { signal, onWarning, subscribeTimeoutMs = 1e4 } = options;
|
|
8978
|
+
const { signal, onWarning, onReady, subscribeTimeoutMs = 1e4 } = options;
|
|
8979
8979
|
return new Promise((resolvePromise, rejectPromise) => {
|
|
8980
8980
|
if (signal?.aborted) {
|
|
8981
8981
|
resolvePromise();
|
|
@@ -9017,6 +9017,7 @@ function herdrStream(socketPath, subscriptions, onEvent, options = {}) {
|
|
|
9017
9017
|
if (!acked) {
|
|
9018
9018
|
acked = true;
|
|
9019
9019
|
clearTimeout(ackTimer);
|
|
9020
|
+
onReady?.();
|
|
9020
9021
|
}
|
|
9021
9022
|
const classified = classifyStreamLine(line, id);
|
|
9022
9023
|
if (classified.kind === "ack") continue;
|
|
@@ -9191,9 +9192,12 @@ function indexAgents(agents) {
|
|
|
9191
9192
|
return new Map(agents.map((agent) => [agent.pane_id, agent]));
|
|
9192
9193
|
}
|
|
9193
9194
|
function buildWatchSubscriptions(agents) {
|
|
9194
|
-
return agents.
|
|
9195
|
-
|
|
9196
|
-
|
|
9195
|
+
return buildPaneSubscriptions(agents.map((agent) => agent.pane_id));
|
|
9196
|
+
}
|
|
9197
|
+
function buildPaneSubscriptions(paneIds) {
|
|
9198
|
+
return [...new Set(paneIds)].flatMap((pane_id) => [
|
|
9199
|
+
{ type: "pane.agent_status_changed", pane_id },
|
|
9200
|
+
{ type: "pane.exited", pane_id }
|
|
9197
9201
|
]);
|
|
9198
9202
|
}
|
|
9199
9203
|
function normalizeWatchEvent(raw) {
|
|
@@ -9385,6 +9389,7 @@ async function runWait(ports, targets, options) {
|
|
|
9385
9389
|
const remaining = new Set(targetIds);
|
|
9386
9390
|
let seed = /* @__PURE__ */ new Map();
|
|
9387
9391
|
let attempt = 0;
|
|
9392
|
+
const subscriptions = buildPaneSubscriptions(targetIds);
|
|
9388
9393
|
const settle = (agent, paneId, status) => {
|
|
9389
9394
|
if (!remaining.has(paneId)) return;
|
|
9390
9395
|
const record = {
|
|
@@ -9403,67 +9408,124 @@ async function runWait(ports, targets, options) {
|
|
|
9403
9408
|
try {
|
|
9404
9409
|
while (!controller.signal.aborted) {
|
|
9405
9410
|
try {
|
|
9406
|
-
const listed = await raceAbort(
|
|
9407
|
-
ports.request("agent.list", {})
|
|
9408
|
-
);
|
|
9409
|
-
if (listed === aborted) break;
|
|
9410
|
-
const current = listed.agents ?? [];
|
|
9411
|
-
const fresh = indexAgents(current);
|
|
9412
|
-
for (const paneId of [...remaining]) {
|
|
9413
|
-
const currentAgent = fresh.get(paneId);
|
|
9414
|
-
if (currentAgent === void 0) {
|
|
9415
|
-
settle(seed.get(paneId), paneId, "exited");
|
|
9416
|
-
continue;
|
|
9417
|
-
}
|
|
9418
|
-
const status = currentAgent.agent_status?.trim().toLowerCase();
|
|
9419
|
-
if (status !== void 0 && statuses.has(status)) {
|
|
9420
|
-
settle(currentAgent, paneId, currentAgent.agent_status ?? status);
|
|
9421
|
-
}
|
|
9422
|
-
}
|
|
9423
|
-
seed = fresh;
|
|
9424
|
-
if (completed || remaining.size === 0) return;
|
|
9425
|
-
const subscriptions = buildWatchSubscriptions(
|
|
9426
|
-
current.filter((agent) => remaining.has(agent.pane_id))
|
|
9427
|
-
);
|
|
9428
9411
|
let carriedTraffic = false;
|
|
9429
9412
|
let relistNeeded = false;
|
|
9413
|
+
let reconciled = false;
|
|
9414
|
+
const bufferedEvents = [];
|
|
9430
9415
|
const startedAt = now();
|
|
9431
9416
|
const cycle = new AbortController();
|
|
9432
9417
|
const stopCycle = () => cycle.abort();
|
|
9433
9418
|
controller.signal.addEventListener("abort", stopCycle, { once: true });
|
|
9419
|
+
let streamReady = false;
|
|
9420
|
+
let streamFailed = false;
|
|
9421
|
+
let streamFailure;
|
|
9422
|
+
let resolveReady;
|
|
9423
|
+
let rejectReady;
|
|
9424
|
+
const ready = new Promise((resolve9, reject) => {
|
|
9425
|
+
resolveReady = resolve9;
|
|
9426
|
+
rejectReady = reject;
|
|
9427
|
+
});
|
|
9428
|
+
const handleEvent = (event) => {
|
|
9429
|
+
if (!remaining.has(event.paneId)) return;
|
|
9430
|
+
const known = seed.get(event.paneId);
|
|
9431
|
+
if (event.type === "pane.exited") {
|
|
9432
|
+
settle(known, event.paneId, "exited");
|
|
9433
|
+
return;
|
|
9434
|
+
}
|
|
9435
|
+
const status = event.to?.trim().toLowerCase();
|
|
9436
|
+
if (known && event.to) known.agent_status = event.to;
|
|
9437
|
+
if (status !== void 0 && statuses.has(status)) {
|
|
9438
|
+
settle(known, event.paneId, event.to ?? status);
|
|
9439
|
+
}
|
|
9440
|
+
};
|
|
9441
|
+
let streamFinished;
|
|
9434
9442
|
try {
|
|
9435
|
-
const
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9443
|
+
const stream = ports.stream(
|
|
9444
|
+
subscriptions,
|
|
9445
|
+
(raw) => {
|
|
9446
|
+
carriedTraffic = true;
|
|
9447
|
+
if (!streamReady) {
|
|
9448
|
+
streamReady = true;
|
|
9449
|
+
resolveReady();
|
|
9450
|
+
}
|
|
9451
|
+
const event = normalizeWatchEvent(raw);
|
|
9452
|
+
if (event === null || needsRelistFallback(event)) {
|
|
9453
|
+
relistNeeded = true;
|
|
9454
|
+
cycle.abort();
|
|
9455
|
+
return;
|
|
9456
|
+
}
|
|
9457
|
+
if (!reconciled) {
|
|
9458
|
+
bufferedEvents.push(event);
|
|
9459
|
+
return;
|
|
9460
|
+
}
|
|
9461
|
+
handleEvent(event);
|
|
9462
|
+
},
|
|
9463
|
+
{
|
|
9464
|
+
signal: cycle.signal,
|
|
9465
|
+
onReady: () => {
|
|
9466
|
+
streamReady = true;
|
|
9467
|
+
resolveReady();
|
|
9457
9468
|
},
|
|
9458
|
-
{
|
|
9459
|
-
|
|
9460
|
-
|
|
9469
|
+
onWarning: (message) => warn2(`herdr wait: ${message}`)
|
|
9470
|
+
}
|
|
9471
|
+
);
|
|
9472
|
+
streamFinished = stream.then(
|
|
9473
|
+
() => {
|
|
9474
|
+
if (!streamReady) {
|
|
9475
|
+
rejectReady(
|
|
9476
|
+
new Error("Herdr subscription closed before it was ready")
|
|
9477
|
+
);
|
|
9461
9478
|
}
|
|
9462
|
-
|
|
9479
|
+
},
|
|
9480
|
+
(error) => {
|
|
9481
|
+
streamFailed = true;
|
|
9482
|
+
streamFailure = error;
|
|
9483
|
+
if (!streamReady) rejectReady(error);
|
|
9484
|
+
}
|
|
9463
9485
|
);
|
|
9486
|
+
} catch (error) {
|
|
9487
|
+
streamFailed = true;
|
|
9488
|
+
streamFailure = error;
|
|
9489
|
+
rejectReady(error);
|
|
9490
|
+
streamFinished = Promise.resolve();
|
|
9491
|
+
}
|
|
9492
|
+
try {
|
|
9493
|
+
const readyResult = await raceAbort(ready);
|
|
9494
|
+
if (readyResult === aborted) break;
|
|
9495
|
+
const listed = await raceAbort(
|
|
9496
|
+
ports.request("agent.list", {})
|
|
9497
|
+
);
|
|
9498
|
+
if (listed === aborted) break;
|
|
9499
|
+
const current = listed.agents ?? [];
|
|
9500
|
+
const fresh = indexAgents(current);
|
|
9501
|
+
for (const paneId of [...remaining]) {
|
|
9502
|
+
const currentAgent = fresh.get(paneId);
|
|
9503
|
+
if (currentAgent === void 0) {
|
|
9504
|
+
settle(seed.get(paneId), paneId, "exited");
|
|
9505
|
+
}
|
|
9506
|
+
}
|
|
9507
|
+
seed = fresh;
|
|
9508
|
+
reconciled = true;
|
|
9509
|
+
for (const paneId of [...remaining]) {
|
|
9510
|
+
const currentAgent = fresh.get(paneId);
|
|
9511
|
+
if (currentAgent === void 0) continue;
|
|
9512
|
+
for (const event of bufferedEvents) {
|
|
9513
|
+
if (event.paneId === paneId) handleEvent(event);
|
|
9514
|
+
}
|
|
9515
|
+
if (!remaining.has(paneId)) continue;
|
|
9516
|
+
const status = currentAgent.agent_status?.trim().toLowerCase();
|
|
9517
|
+
if (status !== void 0 && statuses.has(status)) {
|
|
9518
|
+
settle(currentAgent, paneId, currentAgent.agent_status ?? status);
|
|
9519
|
+
}
|
|
9520
|
+
}
|
|
9521
|
+
if (completed || remaining.size === 0) return;
|
|
9522
|
+
if (relistNeeded) continue;
|
|
9523
|
+
const streamed = await raceAbort(streamFinished);
|
|
9464
9524
|
if (streamed === aborted) break;
|
|
9525
|
+
if (streamFailed) throw streamFailure;
|
|
9465
9526
|
} finally {
|
|
9466
9527
|
controller.signal.removeEventListener("abort", stopCycle);
|
|
9528
|
+
cycle.abort();
|
|
9467
9529
|
}
|
|
9468
9530
|
if (completed) return;
|
|
9469
9531
|
if (relistNeeded) continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sechroom/cli",
|
|
3
|
-
"version": "2026.8.
|
|
3
|
+
"version": "2026.8.3-rc.fc3795ae7",
|
|
4
4
|
"description": "Command-line interface for Sechroom — sign in, wire your AI tools, and work with your sechroom from the terminal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|