@rosthq/cli 0.7.64 → 0.7.66

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.
@@ -0,0 +1,23 @@
1
+ export type HostResourceTelemetry = {
2
+ load_avg_1m: number | null;
3
+ memory_available_mb: number | null;
4
+ swap_used_mb: number | null;
5
+ swap_total_mb: number | null;
6
+ };
7
+ export declare function parseLinuxMeminfoSwap(meminfo: string): {
8
+ swap_used_mb: number;
9
+ swap_total_mb: number;
10
+ } | null;
11
+ export declare function parseDarwinSwapusage(output: string): {
12
+ swap_used_mb: number;
13
+ swap_total_mb: number;
14
+ } | null;
15
+ export type HostResourceDeps = {
16
+ platform: () => string;
17
+ loadAvg: () => number[];
18
+ freeMemBytes: () => number;
19
+ readLinuxMeminfo: () => string;
20
+ readDarwinSwapusage: () => string;
21
+ };
22
+ export declare function detectHostResource(deps?: HostResourceDeps): HostResourceTelemetry;
23
+ //# sourceMappingURL=host-resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-resource.d.ts","sourceRoot":"","sources":["../src/host-resource.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,qBAAqB,GAAG;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC;AAGF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAS7G;AAGD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAmB3G;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,MAAM,CAAC;IAC/B,mBAAmB,EAAE,MAAM,MAAM,CAAC;CACnC,CAAC;AAUF,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,gBAA8B,GAAG,qBAAqB,CAiC9F"}
package/dist/index.js CHANGED
@@ -38250,6 +38250,39 @@ var CATALOG_ENTRIES = [
38250
38250
  credential_required: false,
38251
38251
  default_access_policy: "always_allow"
38252
38252
  },
38253
+ {
38254
+ id: "script.run",
38255
+ title: "Run a script (sandbox)",
38256
+ provider: "rost",
38257
+ description: "Call this to run a short program (shell/node/python) in an isolated, network-disabled microVM for pure computation \u2014 parsing, transforming, calculating, or validating data the agent already holds. The sandbox has NO credentials and NO network access; it cannot read files, call APIs, or reach the internet. Use it for compute, never to fetch or send data. Every run is metered and audited; availability is a per-account entitlement and each call is confirmed by default (arbitrary code execution).",
38258
+ // Compute-only: the microVM produces a structured, size-capped result and has
38259
+ // no durable or external effect, so the narrowest useful tier is `read`.
38260
+ default_scope_tier: "read",
38261
+ scope_tiers: ["read"],
38262
+ // v1 injects ZERO credentials (secret grants are DER-1585) — never a vault ref.
38263
+ credential_required: false,
38264
+ // Conservative by default (invariant #10): arbitrary code execution routes to the
38265
+ // human on every call until a tenant deliberately loosens it. The separate
38266
+ // `agent.script_run` account entitlement gates availability on top of this.
38267
+ default_access_policy: "always_ask"
38268
+ },
38269
+ {
38270
+ id: "secret.broker",
38271
+ title: "Call an authenticated API (brokered)",
38272
+ provider: "rost",
38273
+ description: "Call this to make ONE authenticated request to a pre-approved third-party API on the agent's behalf. You supply only the grant key, method, path, and query/body \u2014 never a credential. A server-side broker injects the secret, calls the single allowlisted host/path/method the grant permits, and returns a size-capped, secret-scrubbed result (response bodies that echo credential-shaped material are redacted wholesale). The secret never enters your context or the sandbox. Read requests run directly; any write (POST/PUT/PATCH/DELETE) is HELD for human approval before it is sent. Every attempt is audited.",
38274
+ // A write goes out over the network with a real credential — the broadest tier.
38275
+ // Reads on the same grant self-select the read behaviour at call time; the
38276
+ // catalog tier is the ceiling (a write is held-with-approval).
38277
+ default_scope_tier: "write_with_approval",
38278
+ scope_tiers: ["read", "write_with_approval"],
38279
+ // The broker resolves a vault ref per grant and injects it server-side.
38280
+ credential_required: true,
38281
+ // Conservative by default (invariant #10): brokered egress is confirmed by
38282
+ // default; writes are additionally held for /approvals. A per-seat grant
38283
+ // (script_run_secret_grants) gates availability on top of this — no grant, no call.
38284
+ default_access_policy: "always_ask"
38285
+ },
38253
38286
  {
38254
38287
  id: "ap.invoices.read",
38255
38288
  title: "Read AP invoices",
@@ -38984,8 +39017,29 @@ var agentSetupNextActionSchema = external_exports.enum([
38984
39017
  "sign_manifest",
38985
39018
  "run_dry_run",
38986
39019
  "go_live",
38987
- "complete"
39020
+ "complete",
39021
+ // DER-1628: live-agent remediation actions. A live agent is NOT automatically
39022
+ // "complete" — a missing/never-approved active Charter or an ARCHIVED
39023
+ // configured parent is a real post-go-live defect that must route the operator
39024
+ // to the exact repair instead of falsely reading complete. These only ever
39025
+ // appear for a live/promotable agent (the setup wizard's forward actions above
39026
+ // cover the draft flow), and DER-1652 deep-links each to its repair surface.
39027
+ "fix_charter",
39028
+ "fix_reporting_line"
39029
+ ]);
39030
+ var agentSetupBlockerCodeSchema = external_exports.enum([
39031
+ "missing_active_charter",
39032
+ "archived_parent",
39033
+ "missing_parent",
39034
+ "missing_steward",
39035
+ "missing_occupancy",
39036
+ "missing_goal_or_measurable",
39037
+ "skill_dependency_blocked"
38988
39038
  ]);
39039
+ var agentSetupBlockerSchema = external_exports.object({
39040
+ code: agentSetupBlockerCodeSchema,
39041
+ message: external_exports.string().min(1).max(500)
39042
+ }).strict();
38989
39043
  var agentSetupSkillRecommendationSchema = skillSummarySchema.extend({
38990
39044
  match_score: external_exports.number().int().min(0).max(100),
38991
39045
  recommendation_reason: external_exports.string().min(1).max(240)
@@ -39051,7 +39105,10 @@ var agentSetupStateSchema = external_exports.object({
39051
39105
  // reload. Optional so a pre-DER-842 recorded result still validates.
39052
39106
  transcript: dryRunTranscriptSchema.optional()
39053
39107
  }).strict().nullable(),
39054
- blockers: external_exports.array(external_exports.string()),
39108
+ // DER-1628: typed, stable completeness blockers (was `string[]`). `complete`
39109
+ // is impossible while this array is non-empty — every surface reads the same
39110
+ // canonical result rather than doing its own completeness math.
39111
+ blockers: external_exports.array(agentSetupBlockerSchema),
39055
39112
  next_action: agentSetupNextActionSchema
39056
39113
  }).strict();
39057
39114
  var agentSetupToolUpdateSchema = external_exports.object({
@@ -39480,6 +39537,22 @@ var storedModelGatewayPolicySchema = external_exports.object({
39480
39537
  allow_non_zdr_models: external_exports.boolean()
39481
39538
  }).strict();
39482
39539
 
39540
+ // ../../packages/protocol/src/cloud-brain-options.ts
39541
+ var cloudBrainOptionSchema = external_exports.object({
39542
+ // Null is reserved for the synthetic Anthropic "Automatic" default (today's
39543
+ // unchanged tiering behavior — no behavior change). A real option's slug is
39544
+ // the registry's dotted `provider:model` slug (e.g. "openai:gpt-5.6").
39545
+ slug: external_exports.string().nullable(),
39546
+ provider: external_exports.string(),
39547
+ label: external_exports.string().min(1),
39548
+ managed: external_exports.boolean(),
39549
+ zdr_available: external_exports.boolean(),
39550
+ selectable: external_exports.boolean(),
39551
+ disabled_reason: external_exports.string().min(1).nullable(),
39552
+ retention_disclosure: external_exports.string().min(1).nullable(),
39553
+ live_note: external_exports.string().min(1).nullable()
39554
+ }).strict();
39555
+
39483
39556
  // ../../packages/protocol/src/aicos.ts
39484
39557
  var uuidSchema5 = external_exports.string().uuid();
39485
39558
  var jsonObjectSchema = external_exports.record(external_exports.string(), external_exports.unknown());
@@ -39697,7 +39770,18 @@ var aicosBrainSettingsSchema = external_exports.object({
39697
39770
  cloud_brain: aicosCloudBrainPreferenceSchema,
39698
39771
  runner_brain: aicosRunnerBrainPreferenceSchema,
39699
39772
  effective_brain: aicosAnswerBrainSchema,
39700
- label: external_exports.string().min(1).max(80)
39773
+ label: external_exports.string().min(1).max(80),
39774
+ // DER-1591 (ADR-0019 W2.3b): the persisted managed-model slug for cloud
39775
+ // AICOS (null = the Anthropic "Automatic" default — today's unchanged
39776
+ // behavior), the full picker option list (ZDR-gated availability +
39777
+ // disclosure + the permanent non-Anthropic honesty note baked into each
39778
+ // option by `buildCloudBrainOptions`), and whether this tenant has unlocked
39779
+ // non-ZDR managed models. This settings/persistence layer does not yet
39780
+ // change which model actually serves a cloud turn (DER-1582, next in the
39781
+ // serial lane, wires it live).
39782
+ cloud_model_slug: external_exports.string().nullable(),
39783
+ cloud_options: external_exports.array(cloudBrainOptionSchema),
39784
+ non_zdr_unlocked: external_exports.boolean()
39701
39785
  }).strict();
39702
39786
  var aicosBrainSettingsGetInputSchema = external_exports.object({}).strict();
39703
39787
  var aicosBrainSettingsGetOutputSchema = external_exports.object({
@@ -39706,9 +39790,10 @@ var aicosBrainSettingsGetOutputSchema = external_exports.object({
39706
39790
  var aicosBrainSettingsUpdateInputSchema = external_exports.object({
39707
39791
  lane: aicosLaneSchema.optional(),
39708
39792
  cloud_brain: aicosCloudBrainPreferenceSchema.optional(),
39709
- runner_brain: aicosRunnerBrainPreferenceSchema.optional()
39793
+ runner_brain: aicosRunnerBrainPreferenceSchema.optional(),
39794
+ cloud_model_slug: external_exports.string().nullable().optional()
39710
39795
  }).strict().refine(
39711
- (value) => value.lane !== void 0 || value.cloud_brain !== void 0 || value.runner_brain !== void 0,
39796
+ (value) => value.lane !== void 0 || value.cloud_brain !== void 0 || value.runner_brain !== void 0 || value.cloud_model_slug !== void 0,
39712
39797
  "At least one AICOS lane or brain setting must be provided."
39713
39798
  );
39714
39799
  var aicosSessionSchema = external_exports.object({
@@ -45165,7 +45250,7 @@ The Compass is drafted, then activated by a human through supersession.
45165
45250
  order: 15,
45166
45251
  title: "AICOS chat guide",
45167
45252
  summary: "How the AI Chief of Staff chat works in the authenticated app shell and what it can safely do today.",
45168
- version: "2026-07-10.2",
45253
+ version: "2026-07-11.1",
45169
45254
  public: true,
45170
45255
  audiences: ["human", "in_app_agent"],
45171
45256
  stages: ["company_setup", "operating_rhythm"],
@@ -45178,6 +45263,7 @@ The Compass is drafted, then activated by a human through supersession.
45178
45263
  "runner.list",
45179
45264
  "aicos.brain_settings.get",
45180
45265
  "aicos.brain_settings.update",
45266
+ "tenant.model_gateway_policy.update",
45181
45267
  "agent.create_custom",
45182
45268
  "agent.configure_tools",
45183
45269
  "agent.run_dry_run",
@@ -45233,7 +45319,7 @@ Each turn carries server-normalized page context: route template, current path,
45233
45319
 
45234
45320
  The current chat harness shows the effective lane and model. Cloud is the default and remains the enforced lane during onboarding, even if a post-onboarding lane has been selected. After onboarding, an owner or admin can select cloud, runner, or MCP only when the server says that lane is ready. Lane changes update the governed AICOS agent seat and write an append-only audit event; the browser never decides tenant authority or runner/MCP readiness.
45235
45321
 
45236
- AICOS also has an explicit brain selection. Cloud can use the included managed allowance or a tenant Anthropic key (BYOK). Runner brain preference still records Claude or Codex, but interactive AICOS runner turns are currently gated to Claude while the Codex path remains unverified. MCP is labeled as the MCP client. Read this selection with \`aicos.brain_settings.get\`; owners can update it with \`aicos.brain_settings.update\` (CLI flags: \`--lane\`, \`--cloud-brain managed|byok\`, \`--runner-brain claude-cli|codex-cli\`). BYOK requires an active tenant Anthropic key. Choosing \`codex-cli\` for AICOS runner mode is currently rejected with a precondition error until the governed interactive runner path is verified. Runner and MCP answers are labeled in the transcript and do not consume the managed cloud allowance. If the selected runner reports that its active local model account has exhausted its allowance, Settings surfaces **Allowance exhausted** before the user sends another AICOS turn so they can switch lanes, switch runner accounts, or keep working manually instead of waiting on a doomed runner round-trip.
45322
+ AICOS also has an explicit brain selection. Cloud can use the included managed allowance or a tenant Anthropic key (BYOK). When cloud is on the managed allowance, an owner can also pick a specific managed model from the AI Gateway's priced, ZDR-rated catalog (today: Anthropic's own "Automatic" default, plus managed OpenAI and xAI entries) instead of leaving the choice on Anthropic's default routing. A managed model without a zero-data-retention tier shows as locked with the reason until a tenant owner explicitly unlocks non-ZDR managed models (\`tenant.model_gateway_policy.update\`, owner-only and dangerous-gated); once unlocked, its per-model data-retention disclosure is shown before it becomes selectable. Selecting one of these managed models updates AICOS settings immediately, but it does not yet change which model actually answers a cloud AICOS turn \u2014 every non-Anthropic option says so plainly, and cloud turns keep running on the existing Anthropic routing until a later runtime cutover wires the persisted selection through. Runner brain preference still records Claude or Codex, but interactive AICOS runner turns are currently gated to Claude while the Codex path remains unverified. MCP is labeled as the MCP client. Read this selection with \`aicos.brain_settings.get\`; owners can update it with \`aicos.brain_settings.update\` (CLI flags: \`--lane\`, \`--cloud-brain managed|byok\`, \`--runner-brain claude-cli|codex-cli\`). BYOK requires an active tenant Anthropic key and does not support a specific managed-model selection. Choosing \`codex-cli\` for AICOS runner mode is currently rejected with a precondition error until the governed interactive runner path is verified. Runner and MCP answers are labeled in the transcript and do not consume the managed cloud allowance. If the selected runner reports that its active local model account has exhausted its allowance, Settings surfaces **Allowance exhausted** before the user sends another AICOS turn so they can switch lanes, switch runner accounts, or keep working manually instead of waiting on a doomed runner round-trip.
45237
45323
 
45238
45324
  Runner mode uses the same AICOS sessions and transcript. Interactive chat turns are tracked separately from scheduled work orders: each user message has one user-owned turn execution with a short deadline, so two users' chat messages cannot collapse into the same scheduled-work slot. Scheduled and Forge runner work still use work orders. Runner claim packets carry ids and execution metadata, not the user's free-text request. After claim, the local runner calls the governed AICOS context-load tool, which re-checks seat scope and returns the bounded transcript, session summary, route context, tenant clock, grounding text, and source counts authorized for that turn. For execute-ready runners, the claim also carries a server-built Seat work contract that names the governed runtime profile, the AICOS context-loader tool, and the Seat's permission manifest; action attempts still route through command guards, tool-call audit, and pending confirmations. The runner treats loaded tenant clock, context, and contract as authoritative instead of substituting its own runtime clock, local files, or self-invented authority. A runner must be paired, execute-ready, and backed by the live AICOS agent before it can be selected.
45239
45325
 
@@ -45714,7 +45800,7 @@ For CLI and MCP setup, read agent-skill-setup-guide before adding or assigning S
45714
45800
  order: 42,
45715
45801
  title: "Design a custom agent",
45716
45802
  summary: "How to build a custom agent from operational questions through the Charter Builder, tools, dry run, and go-live without writing prompts.",
45717
- version: "2026-07-10.1",
45803
+ version: "2026-07-12.1",
45718
45804
  public: true,
45719
45805
  audiences: ["human", "cli", "mcp", "in_app_agent"],
45720
45806
  stages: ["staffing", "charter_design"],
@@ -45779,6 +45865,14 @@ The same path is command-backed:
45779
45865
  7. \`agent.configure_tools\` / \`rost_configure_agent_tools\` records connect/decline decisions and credential-ingress requests (vault refs only).
45780
45866
  8. \`agent.run_dry_run\` / \`rost_run_agent_dry_run\` rehearses the task after the manifest is signed.
45781
45867
 
45868
+ ## Setup completeness and blockers
45869
+
45870
+ \`agent_setup.get\` derives completeness canonically, so every surface \u2014 the web builder, the CLI, and the \`agent.show_markdown\` readout \u2014 reads one result instead of doing its own math. It returns a \`blockers\` array plus a \`next_action\`. Each blocker is a typed \`{ code, message }\`: consumers key off the stable \`code\` (to group blockers or deep-link to the exact repair) and show \`message\` verbatim. A setup is \`complete\` only when \`blockers\` is empty; while any blocker is present, \`next_action\` points at the highest-priority repair rather than \`complete\`.
45871
+
45872
+ The blocker codes are a stable vocabulary \u2014 new reasons get a new code rather than a rename. Emitted today: \`missing_active_charter\`, \`archived_parent\`, \`missing_parent\`, \`missing_steward\`, and \`skill_dependency_blocked\` (\`missing_occupancy\` and \`missing_goal_or_measurable\` are reserved for later checks).
45873
+
45874
+ Completeness is not just a draft gate: a **live** agent is not automatically \`complete\`. If a live seat has no active, approved Charter, its configured parent is archived, or its steward chain no longer resolves to a human, \`agent_setup.get\` surfaces the matching blocker and routes \`next_action\` to the fix \u2014 \`fix_charter\` for \`missing_active_charter\`, \`fix_reporting_line\` for \`archived_parent\`, then \`set_steward\` for \`missing_steward\`, in that priority order. A live agent with no configured parent at all is the legitimate top-level case and stays \`complete\`; only an archived configured parent blocks it.
45875
+
45782
45876
  ## Dry run and go-live
45783
45877
 
45784
45878
  The dry run is a real sandbox rehearsal, not a stamp. It executes a mock-provider run derived from the Charter \u2014 the agent works against sandbox data only and is expected to escalate where the Charter's must-escalate clause requires it. The same rehearsal works on all three lanes: cloud, external MCP, and local Runner. External MCP dry runs require an active seat-scoped MCP token; Runner dry runs require a paired Runner. Missing substrate returns a typed precondition error, not a generic failure. The recorded run keeps the agent's actual lane, so the evidence you review matches the lane you selected. The result is earned: a run that escalates the must-escalate boundary passes; a run that acts on that boundary instead of escalating fails. A failed dry run keeps the draft and shows the reason so you can edit and rerun. The rehearsal returns a transcript \u2014 the steps the agent took and the escalation it raised \u2014 shown step by step in the builder and printed by the CLI, so you can see the governance model working before anything goes live. The transcript is also lane-honest: each granted tool is marked executable, held for the steward, or granted but unimplemented in this lane, with a plain-count verdict such as "2 of 6 granted tools don't execute in the cloud lane yet" \u2014 so a grant that would silently no-op in the cloud runtime is visible before go-live instead of passing green. Runner and MCP-session agents run those tools through their own local skills, so their grants are not flagged as unimplemented. When the dry run passes, a human promotes the agent live. The dry run rehearses the specific model tier you chose, so once it passes the model is locked \u2014 changing the model requires re-running the dry run on the new model before go-live.
@@ -50002,7 +50096,7 @@ var COMMAND_MANIFEST = [
50002
50096
  { "id": "agent.status", "namespace": "agent", "action": "status", "title": "Get agent status", "description": "Return the agent occupancy, lane, schedule, live/offline state, steward chain, dry-run result, and Runner availability for a seat.", "requiredScope": "seat", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Check an agent's lane, live state, steward chain, dry-run result, and Runner availability before relying on it." },
50003
50097
  { "id": "agent.update_schedule", "namespace": "agent", "action": "update_schedule", "title": "Update agent schedule", "description": "Set or clear the scheduled execution cron for a draft or live agent on a seat.", "requiredScope": "tenant", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }, { "name": "schedule_cron", "flag": "schedule-cron", "type": "string", "required": true }], "hasComplexInput": false, "help": "Set or clear an agent's scheduled execution; a live scheduled agent must keep a steward chain resolving to a human." },
50004
50098
  { "id": "aicos.brain_settings.get", "namespace": "aicos", "action": "brain_settings.get", "title": "Get AICOS brain settings", "description": "Read the AICOS run lane and brain selection. Returns labels and enum settings only; no secrets or vault refs.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [], "hasComplexInput": false, "help": "Read the AICOS lane and brain selection labels without returning provider keys, vault refs, or runner secrets." },
50005
- { "id": "aicos.brain_settings.update", "namespace": "aicos", "action": "brain_settings.update", "title": "Update AICOS brain settings", "description": "Update the AICOS lane and cloud/runner brain preferences. Owner-only and audited.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "lane", "flag": "lane", "type": "enum", "required": false, "enumValues": ["cloud", "runner", "mcp"] }, { "name": "cloud_brain", "flag": "cloud-brain", "type": "enum", "required": false, "enumValues": ["managed", "byok"] }, { "name": "runner_brain", "flag": "runner-brain", "type": "enum", "required": false, "enumValues": ["claude-cli", "codex-cli"] }], "hasComplexInput": false, "help": "Owner-only update for AICOS cloud managed/BYOK and runner Claude/Codex preferences; BYOK requires an active tenant Anthropic key." },
50099
+ { "id": "aicos.brain_settings.update", "namespace": "aicos", "action": "brain_settings.update", "title": "Update AICOS brain settings", "description": "Update the AICOS lane and cloud/runner brain preferences. Owner-only and audited.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "lane", "flag": "lane", "type": "enum", "required": false, "enumValues": ["cloud", "runner", "mcp"] }, { "name": "cloud_brain", "flag": "cloud-brain", "type": "enum", "required": false, "enumValues": ["managed", "byok"] }, { "name": "runner_brain", "flag": "runner-brain", "type": "enum", "required": false, "enumValues": ["claude-cli", "codex-cli"] }, { "name": "cloud_model_slug", "flag": "cloud-model-slug", "type": "string", "required": false }], "hasComplexInput": false, "help": "Owner-only update for AICOS cloud managed/BYOK and runner Claude/Codex preferences; BYOK requires an active tenant Anthropic key." },
50006
50100
  { "id": "cascade.import", "namespace": "cascade", "action": "import", "title": "Import Rocks from a ninety Rocks export", "description": "Bulk-import a ninety Rocks export into the Cascade as cycle goals under a company objective in the active cycle. Owners are seat names resolved to seats. Requires an active cycle and a target company objective (auto-selected when exactly one exists, else pass parent_objective_id). Idempotent \u2014 re-importing the same export is a no-op, and an existing cycle goal with the same objective + seat + title is skipped.", "requiredScope": "tenant_admin", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "dry_run", "flag": "dry-run", "type": "boolean", "required": false }, { "name": "parent_objective_id", "flag": "parent-objective-id", "type": "string", "required": false }], "hasComplexInput": true, "help": "Import a ninety Rocks export into the Cascade as cycle goals under a company objective in the active cycle; owners resolve to seats." },
50007
50101
  { "id": "charter.apply_seat_type_recommendation", "namespace": "charter", "action": "apply_seat_type_recommendation", "title": "Apply Charter seat-type recommendation", "description": "Apply the seat-type recommendation from a draft Charter.", "requiredScope": "seat", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "charter_version_id", "flag": "charter-version-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Apply seat-type recommendations only after the Charter clarifies work shape, risk, and Steward accountability." },
50008
50102
  { "id": "charter.approve", "namespace": "charter", "action": "approve", "title": "Approve charter", "description": "Approve a draft Charter as a human owner.", "requiredScope": "seat", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": false }, { "name": "charter_version_id", "flag": "charter-version-id", "type": "string", "required": false }, { "name": "apply_seat_type", "flag": "apply-seat-type", "type": "boolean", "required": false }], "hasComplexInput": true, "help": "Charter approval is a human decision that activates the seat's operating contract." },
@@ -54554,6 +54648,80 @@ async function removeWorkspace(ws) {
54554
54648
  await removeWorktree(ws.baseRepo, ws.worktreeDir);
54555
54649
  }
54556
54650
 
54651
+ // src/host-resource.ts
54652
+ import { execFileSync } from "node:child_process";
54653
+ import { readFileSync as readFileSync4 } from "node:fs";
54654
+ import { freemem, loadavg, platform as osPlatform } from "node:os";
54655
+ var MB = 1024 * 1024;
54656
+ function parseLinuxMeminfoSwap(meminfo) {
54657
+ const total = /^SwapTotal:\s+(\d+)\s*kB/m.exec(meminfo);
54658
+ const free = /^SwapFree:\s+(\d+)\s*kB/m.exec(meminfo);
54659
+ if (!total || !free) return null;
54660
+ const totalKb = Number(total[1]);
54661
+ const freeKb = Number(free[1]);
54662
+ if (!Number.isFinite(totalKb) || !Number.isFinite(freeKb)) return null;
54663
+ const usedKb = Math.max(0, totalKb - freeKb);
54664
+ return { swap_used_mb: Math.round(usedKb / 1024), swap_total_mb: Math.round(totalKb / 1024) };
54665
+ }
54666
+ function parseDarwinSwapusage(output) {
54667
+ const total = /total\s*=\s*([\d.]+)\s*([KMGT])/i.exec(output);
54668
+ const used = /used\s*=\s*([\d.]+)\s*([KMGT])/i.exec(output);
54669
+ if (!total || !used) return null;
54670
+ const toMb = (value, unit) => {
54671
+ const n = Number(value);
54672
+ const u = unit.toUpperCase();
54673
+ const mult = u === "G" ? 1024 : u === "T" ? 1024 * 1024 : u === "K" ? 1 / 1024 : 1;
54674
+ return n * mult;
54675
+ };
54676
+ const usedValue = used[1];
54677
+ const usedUnit = used[2];
54678
+ const totalValue = total[1];
54679
+ const totalUnit = total[2];
54680
+ if (usedValue === void 0 || usedUnit === void 0 || totalValue === void 0 || totalUnit === void 0) return null;
54681
+ const usedMb = toMb(usedValue, usedUnit);
54682
+ const totalMb = toMb(totalValue, totalUnit);
54683
+ if (!Number.isFinite(usedMb) || !Number.isFinite(totalMb)) return null;
54684
+ return { swap_used_mb: Math.round(usedMb), swap_total_mb: Math.round(totalMb) };
54685
+ }
54686
+ var defaultDeps = {
54687
+ platform: () => osPlatform(),
54688
+ loadAvg: () => loadavg(),
54689
+ freeMemBytes: () => freemem(),
54690
+ readLinuxMeminfo: () => readFileSync4("/proc/meminfo", "utf8"),
54691
+ readDarwinSwapusage: () => execFileSync("sysctl", ["-n", "vm.swapusage"], { encoding: "utf8", timeout: 2e3 })
54692
+ };
54693
+ function detectHostResource(deps = defaultDeps) {
54694
+ let load_avg_1m = null;
54695
+ try {
54696
+ const l = deps.loadAvg();
54697
+ const first = Array.isArray(l) ? l[0] : void 0;
54698
+ load_avg_1m = typeof first === "number" && Number.isFinite(first) ? first : null;
54699
+ } catch {
54700
+ load_avg_1m = null;
54701
+ }
54702
+ let memory_available_mb = null;
54703
+ try {
54704
+ const bytes = deps.freeMemBytes();
54705
+ memory_available_mb = Number.isFinite(bytes) && bytes >= 0 ? Math.round(bytes / MB) : null;
54706
+ } catch {
54707
+ memory_available_mb = null;
54708
+ }
54709
+ let swap = null;
54710
+ try {
54711
+ const p = deps.platform();
54712
+ if (p === "linux") swap = parseLinuxMeminfoSwap(deps.readLinuxMeminfo());
54713
+ else if (p === "darwin") swap = parseDarwinSwapusage(deps.readDarwinSwapusage());
54714
+ } catch {
54715
+ swap = null;
54716
+ }
54717
+ return {
54718
+ load_avg_1m,
54719
+ memory_available_mb,
54720
+ swap_used_mb: swap?.swap_used_mb ?? null,
54721
+ swap_total_mb: swap?.swap_total_mb ?? null
54722
+ };
54723
+ }
54724
+
54557
54725
  // src/runner-serve.ts
54558
54726
  var execFile5 = promisify5(execFileCallback5);
54559
54727
  var RUNNER_WORK_ORDER_TOOLS = [
@@ -54739,6 +54907,7 @@ function capabilitiesForAnalytics(capabilities) {
54739
54907
  }
54740
54908
  function detectTelemetry(capabilities, env, activeSessions, cliVersion) {
54741
54909
  const usageState = env.RUNNER_MODEL_ACCOUNT_STATE ?? env.ROST_RUNNER_MODEL_ACCOUNT_STATE ?? "unknown";
54910
+ const host = detectHostResource();
54742
54911
  return {
54743
54912
  os: platform(),
54744
54913
  cpu_count: cpus().length,
@@ -54752,7 +54921,11 @@ function detectTelemetry(capabilities, env, activeSessions, cliVersion) {
54752
54921
  usage_limit_observation: {
54753
54922
  state: usageState,
54754
54923
  source: "runner_env_or_unknown"
54755
- }
54924
+ },
54925
+ load_avg_1m: host.load_avg_1m,
54926
+ memory_available_mb: host.memory_available_mb,
54927
+ swap_used_mb: host.swap_used_mb,
54928
+ swap_total_mb: host.swap_total_mb
54756
54929
  };
54757
54930
  }
54758
54931
  function parseServeArgs(args, appUrl2, env, homeDir) {