@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 +34 -7
- package/dist/index.js.map +2 -2
- package/dist/runner-serve.d.ts +4 -0
- package/dist/runner-serve.d.ts.map +1 -1
- package/package.json +1 -1
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-
|
|
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
|
-
|
|
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: {
|
|
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
|