@rosthq/cli 0.7.108 → 0.7.109

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 CHANGED
@@ -50841,7 +50841,7 @@ Every notification should include the seat, cause, evidence, and requested decis
50841
50841
  order: 75,
50842
50842
  title: "Local runner guide",
50843
50843
  summary: "How local agent sessions and runner surfaces should operate through {{brand}} without bypassing Charters or audit.",
50844
- version: "2026-07-18.1",
50844
+ version: "2026-07-20.1",
50845
50845
  public: true,
50846
50846
  audiences: ["human", "cli", "mcp", "in_app_agent"],
50847
50847
  stages: ["staffing", "operating_rhythm"],
@@ -50887,7 +50887,7 @@ Runner transport defaults to the canonical production host \`https://rost.elevat
50887
50887
 
50888
50888
  Choose the local runtime with \`--runtime auto|claude|codex\` (default \`auto\`). The same short-lived seat-scoped MCP token and server-side guard apply regardless of runtime; results are tagged \`claude-cli\` or \`codex-cli\`.
50889
50889
 
50890
- For always-on execution, \`runner serve --execute\` heartbeats on its normal interval and also checks for claimable work between heartbeats. The default interactive claim cadence is about one second; set \`RUNNER_INTERACTIVE_CLAIM_MS\` or \`--interactive-claim-ms\` to tune it for a host. Claude-backed turns reuse a per-seat Claude Code resume session when Claude reports a session id, so later turns can run with \`claude --resume <session-id>\` under the local subscription account. The runner stores only the opaque resume id in its owner-only state file; it does not use API-billed managed sessions to make subscription runner turns faster. A resident long-lived Claude/Codex process is still prototype-gated, so do not assume a fixed latency SLA from this guide alone.
50890
+ For always-on execution, \`runner serve --execute\` heartbeats on its normal interval and also checks for claimable work between heartbeats. The default interactive claim cadence is about one second; set \`RUNNER_INTERACTIVE_CLAIM_MS\` or \`--interactive-claim-ms\` to tune it for a host. Set how many turns the runner may run in parallel with \`--max-sessions <n>\` or \`RUNNER_MAX_SESSIONS\`; left unset, the runner estimates a value from host CPU and memory. The scheduler honors the declared value (clamped to a small ceiling) so a runner never claims more concurrent work than the capacity it reports. Claude-backed turns reuse a per-seat Claude Code resume session when Claude reports a session id, so later turns can run with \`claude --resume <session-id>\` under the local subscription account. The runner stores only the opaque resume id in its owner-only state file; it does not use API-billed managed sessions to make subscription runner turns faster. A resident long-lived Claude/Codex process is still prototype-gated, so do not assume a fixed latency SLA from this guide alone.
50891
50891
 
50892
50892
  The runner bearer secret is stored locally and is never displayed. Each claimed turn receives a short-lived seat-scoped MCP token from {{brand}}, and server-side guards still decide what tools the Seat may use.
50893
50893
 
@@ -57659,7 +57659,7 @@ ${usage()}
57659
57659
  let activeSessions = 0;
57660
57660
  const activeTurnExecutionIds = /* @__PURE__ */ new Set();
57661
57661
  do {
57662
- const detectedCapabilities = await detectCapabilities(cliVersion, env, homeDir);
57662
+ const detectedCapabilities = await detectCapabilities(cliVersion, env, homeDir, config2.maxSessionsOverride);
57663
57663
  const capabilities = capabilitiesForConfiguredRuntime(detectedCapabilities, config2.runtime);
57664
57664
  const localRuntime = config2.execute ? effectiveExecutionRuntime(config2.runtime, capabilities) : null;
57665
57665
  try {
@@ -57839,6 +57839,7 @@ function parseServeArgs(args, appUrl2, env, homeDir) {
57839
57839
  let once = false;
57840
57840
  let runtime = parseRuntime(env.RUNNER_RUNTIME ?? "auto");
57841
57841
  let userCode = env.RUNNER_USER_CODE;
57842
+ let maxSessionsOverride = parseMaxSessionsEnv(env.RUNNER_MAX_SESSIONS);
57842
57843
  for (let index = 0; index < args.length; index += 1) {
57843
57844
  const token = args[index];
57844
57845
  if (token === "--name") {
@@ -57859,6 +57860,13 @@ function parseServeArgs(args, appUrl2, env, homeDir) {
57859
57860
  } else if (token === "--runtime") {
57860
57861
  runtime = parseRuntime(requiredValue(args, index));
57861
57862
  index += 1;
57863
+ } else if (token === "--max-sessions") {
57864
+ const raw = Number(requiredValue(args, index));
57865
+ if (!Number.isSafeInteger(raw) || raw < 1) {
57866
+ throw new Error("--max-sessions must be an integer >= 1.");
57867
+ }
57868
+ maxSessionsOverride = raw;
57869
+ index += 1;
57862
57870
  } else if (token === "--execute") {
57863
57871
  execute2 = true;
57864
57872
  } else if (token === "--once") {
@@ -57899,9 +57907,17 @@ function parseServeArgs(args, appUrl2, env, homeDir) {
57899
57907
  sandboxAllowNetwork: network.allowNetwork,
57900
57908
  homeDir,
57901
57909
  ...network.unrecognized !== null ? { sandboxNetworkWarning: `RUNNER_SANDBOX_NETWORK='${network.unrecognized}' not recognized (use allow|deny); defaulting to allow egress.` } : {},
57902
- ...userCode ? { userCode } : {}
57910
+ ...userCode ? { userCode } : {},
57911
+ ...maxSessionsOverride !== void 0 ? { maxSessionsOverride: Math.min(maxSessionsOverride, RUNNER_MAX_SESSIONS_CAP) } : {}
57903
57912
  };
57904
57913
  }
57914
+ function parseMaxSessionsEnv(value) {
57915
+ if (value === void 0) {
57916
+ return void 0;
57917
+ }
57918
+ const parsed = Number(value);
57919
+ return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : void 0;
57920
+ }
57905
57921
  function parseRuntime(value) {
57906
57922
  if (value === "auto" || value === "claude" || value === "codex") {
57907
57923
  return value;
@@ -58040,7 +58056,14 @@ async function startPairing(client, config2) {
58040
58056
  }
58041
58057
  return userCode;
58042
58058
  }
58043
- async function detectCapabilities(cliVersion, env, homeDir) {
58059
+ var RUNNER_MAX_SESSIONS_CAP = 8;
58060
+ function estimateMaxSessions(cpuCount, memoryMb) {
58061
+ const byCpu = Number.isFinite(cpuCount) && cpuCount > 0 ? Math.floor(cpuCount) : 1;
58062
+ const byMem = Number.isFinite(memoryMb) && memoryMb > 0 ? Math.floor(memoryMb / 2048) : 1;
58063
+ const estimate = Math.min(byCpu, byMem);
58064
+ return Math.min(Math.max(estimate, 1), RUNNER_MAX_SESSIONS_CAP);
58065
+ }
58066
+ async function detectCapabilities(cliVersion, env, homeDir, maxSessionsOverride) {
58044
58067
  const [claude, codex, git, gh, forgeDiskFreeMb] = await Promise.all([
58045
58068
  probeClaude(),
58046
58069
  probe("codex"),
@@ -58049,6 +58072,7 @@ async function detectCapabilities(cliVersion, env, homeDir) {
58049
58072
  probeForgeDiskFreeMb(homeDir)
58050
58073
  ]);
58051
58074
  const accountAlias = resolveAccountAlias(env);
58075
+ const sessionEstimate = estimateMaxSessions(cpus().length, Math.round(totalmem() / (1024 * 1024)));
58052
58076
  return {
58053
58077
  claude: { ...claude, account_alias: accountAlias, rate_limited_until: null },
58054
58078
  codex: { ...codex, account_alias: accountAlias, rate_limited_until: null },
@@ -58061,7 +58085,10 @@ async function detectCapabilities(cliVersion, env, homeDir) {
58061
58085
  ...cliVersion ? { forge_build: cliVersion, seat_work: cliVersion, forge_merge: cliVersion } : {},
58062
58086
  git,
58063
58087
  gh,
58064
- scheduler: { max_parallel_sessions_estimate: null },
58088
+ scheduler: {
58089
+ max_active_sessions: maxSessionsOverride ?? sessionEstimate,
58090
+ max_parallel_sessions_estimate: sessionEstimate
58091
+ },
58065
58092
  host: { forge_disk_free_mb: forgeDiskFreeMb }
58066
58093
  };
58067
58094
  }
@@ -59408,7 +59435,7 @@ async function clearClaudeSessionId(stateFile, state, workOrder) {
59408
59435
  await saveState(stateFile, state);
59409
59436
  }
59410
59437
  function usage() {
59411
- return "Usage: rost runner serve [--name <text>] [--state-file <path>] [--heartbeat-ms <n>] [--interactive-claim-ms <n>] [--user-code <code>] [--runtime auto|claude|codex] [--once] [--execute]";
59438
+ return "Usage: rost runner serve [--name <text>] [--state-file <path>] [--heartbeat-ms <n>] [--interactive-claim-ms <n>] [--user-code <code>] [--runtime auto|claude|codex] [--max-sessions <n>] [--once] [--execute]";
59412
59439
  }
59413
59440
 
59414
59441
  // src/index.ts