@sechroom/cli 2026.7.21 → 2026.7.22

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.
Files changed (2) hide show
  1. package/dist/index.js +24 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2213,7 +2213,7 @@ function registerExecutor(program2) {
2213
2213
  );
2214
2214
  });
2215
2215
  executor.command("refresh <id>").description("Refresh one advertisement lease once").option("--ttl <seconds>", "Advertisement TTL (30-600)", parseInteger, 120).action(async (id, opts, cmd) => {
2216
- const data = await refresh(
2216
+ const data = await refreshExecutorInstance(
2217
2217
  resolveConfig(cmd.optsWithGlobals()),
2218
2218
  id,
2219
2219
  opts.ttl
@@ -2224,13 +2224,13 @@ function registerExecutor(program2) {
2224
2224
  if (opts.interval >= opts.ttl)
2225
2225
  fail("heartbeat interval must be shorter than the TTL");
2226
2226
  const cfg = resolveConfig(cmd.optsWithGlobals());
2227
- await refresh(cfg, id, opts.ttl);
2227
+ await refreshExecutorInstance(cfg, id, opts.ttl);
2228
2228
  process.stderr.write(
2229
2229
  style.green("executor heartbeat active") + style.dim(` \u2014 ${id}
2230
2230
  `)
2231
2231
  );
2232
2232
  await holdHeartbeat(async () => {
2233
- await refresh(cfg, id, opts.ttl);
2233
+ await refreshExecutorInstance(cfg, id, opts.ttl);
2234
2234
  }, opts.interval * 1e3);
2235
2235
  });
2236
2236
  executor.command("offers <id>").description("List live dispatch offers addressed to this exact instance").action(async (id, _opts, cmd) => {
@@ -2275,7 +2275,7 @@ function parseTransport(value) {
2275
2275
  return fail("transport must be push or pull");
2276
2276
  }
2277
2277
  }
2278
- async function refresh(cfg, id, ttlSeconds) {
2278
+ async function refreshExecutorInstance(cfg, id, ttlSeconds) {
2279
2279
  return api(
2280
2280
  cfg,
2281
2281
  `/me/executor-instances/${encodeURIComponent(id)}/refresh`,
@@ -2404,6 +2404,10 @@ function registerChannel(program2) {
2404
2404
  );
2405
2405
  await drain();
2406
2406
  const stopReconciliation = startOfferReconciliation(drain);
2407
+ const stopHeartbeat = startExecutorHeartbeat(
2408
+ () => refreshExecutorInstance(cfg, instance.id, located.state.ttlSeconds),
2409
+ located.state.refreshAfterSeconds * 1e3
2410
+ );
2407
2411
  if (json) {
2408
2412
  emit(
2409
2413
  {
@@ -2427,6 +2431,7 @@ function registerChannel(program2) {
2427
2431
  await holdOpen(conn);
2428
2432
  } finally {
2429
2433
  stopReconciliation();
2434
+ stopHeartbeat();
2430
2435
  }
2431
2436
  });
2432
2437
  withFilterOpts(
@@ -2469,6 +2474,10 @@ function registerChannel(program2) {
2469
2474
  );
2470
2475
  await drain();
2471
2476
  const stopReconciliation = startOfferReconciliation(drain);
2477
+ const stopHeartbeat = startExecutorHeartbeat(
2478
+ () => refreshExecutorInstance(cfg, instance.id, located.state.ttlSeconds),
2479
+ located.state.refreshAfterSeconds * 1e3
2480
+ );
2472
2481
  process.stderr.write(
2473
2482
  style.dim(
2474
2483
  `sechroom channel (mcp) \u2014 tenant ${cfg.tenant}, executor ${located.state.instanceKey}
@@ -2479,6 +2488,7 @@ function registerChannel(program2) {
2479
2488
  await holdOpen(conn);
2480
2489
  } finally {
2481
2490
  stopReconciliation();
2491
+ stopHeartbeat();
2482
2492
  }
2483
2493
  });
2484
2494
  channel.command("install").description(
@@ -2584,6 +2594,16 @@ function startOfferReconciliation(drain, intervalMilliseconds = 5e3, dependencie
2584
2594
  }, intervalMilliseconds);
2585
2595
  return () => cancel(timer);
2586
2596
  }
2597
+ function startExecutorHeartbeat(refresh, intervalMilliseconds, dependencies = {}) {
2598
+ const schedule = dependencies.setInterval ?? setInterval;
2599
+ const cancel = dependencies.clearInterval ?? clearInterval;
2600
+ const onError = dependencies.onError ?? ((error) => process.stderr.write(err(`channel heartbeat failed: ${String(error)}
2601
+ `)));
2602
+ const timer = schedule(() => {
2603
+ void refresh().catch(onError);
2604
+ }, intervalMilliseconds);
2605
+ return () => cancel(timer);
2606
+ }
2587
2607
  async function drainClaims(cfg, executorInstanceId, deliver, dependencies = {}) {
2588
2608
  const request = dependencies.request ?? api;
2589
2609
  const sleep = dependencies.sleep ?? ((milliseconds) => new Promise((resolve3) => setTimeout(resolve3, milliseconds)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sechroom/cli",
3
- "version": "2026.7.21",
3
+ "version": "2026.7.22",
4
4
  "description": "Sechroom CLI — a thin, generated client over the Sechroom HTTP API. An agent/human surface alongside MCP.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",