@rosthq/cli 0.7.32 → 0.7.34

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,39 @@
1
+ export declare const MODEL_SPAWN_ENV_ALLOWLIST: readonly ["PATH", "HOME", "LANG", "LC_ALL", "TMPDIR", "SHELL", "NODE_OPTIONS"];
2
+ export declare function buildModelSpawnEnv(base: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
3
+ export type ForgeCredential = {
4
+ token: string;
5
+ expiresAt: string;
6
+ };
7
+ export type ForgeWorkspace = {
8
+ baseRepo: string;
9
+ worktreeDir: string;
10
+ branch: string;
11
+ readOnly: boolean;
12
+ baseSha: string;
13
+ };
14
+ export type ForgeWorkspaceProfile = "build" | "review";
15
+ export type PrepareForgeWorkspaceOptions = {
16
+ baseDir: string;
17
+ tenantId: string;
18
+ buildRequestId: string;
19
+ changeset: {
20
+ id: string;
21
+ ordinal: number;
22
+ total: number;
23
+ };
24
+ profile: ForgeWorkspaceProfile;
25
+ headSha?: string;
26
+ repo: {
27
+ owner: string;
28
+ name: string;
29
+ default_branch: string;
30
+ };
31
+ credential: ForgeCredential;
32
+ remoteUrl?: string;
33
+ };
34
+ export declare function prepareForgeWorkspace(options: PrepareForgeWorkspaceOptions): Promise<ForgeWorkspace>;
35
+ export declare function pushChangeset(ws: ForgeWorkspace, credential: ForgeCredential): Promise<{
36
+ commitSha: string;
37
+ } | null>;
38
+ export declare function removeWorkspace(ws: ForgeWorkspace): Promise<void>;
39
+ //# sourceMappingURL=forge-workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forge-workspace.d.ts","sourceRoot":"","sources":["../src/forge-workspace.ts"],"names":[],"mappings":"AAmDA,eAAO,MAAM,yBAAyB,gFAQ5B,CAAC;AAEX,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAW7E;AAID,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAG3B,QAAQ,EAAE,MAAM,CAAC;IAGjB,WAAW,EAAE,MAAM,CAAC;IAGpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAKlB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEvD,MAAM,MAAM,4BAA4B,GAAG;IAEzC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,OAAO,EAAE,qBAAqB,CAAC;IAE/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,UAAU,EAAE,eAAe,CAAC;IAI5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAuPF,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,cAAc,CAAC,CAiC1G;AA8CD,wBAAsB,aAAa,CACjC,EAAE,EAAE,cAAc,EAClB,UAAU,EAAE,eAAe,GAC1B,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA2BvC;AAiBD,wBAAsB,eAAe,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvE"}
@@ -1 +1 @@
1
- {"version":3,"file":"command-manifest.d.ts","sourceRoot":"","sources":["../../src/generated/command-manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,eAAO,MAAM,gBAAgB,EAAE,SAAS,oBAAoB,EAmO3D,CAAC"}
1
+ {"version":3,"file":"command-manifest.d.ts","sourceRoot":"","sources":["../../src/generated/command-manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,eAAO,MAAM,gBAAgB,EAAE,SAAS,oBAAoB,EAoO3D,CAAC"}
package/dist/index.js CHANGED
@@ -43130,6 +43130,30 @@ var softwareDeveloperTeamInstallOutputSchema = external_exports.object({
43130
43130
  token_budget: softwareDeveloperTeamTokenBudgetSummarySchema,
43131
43131
  github_policy: softwareDeveloperTeamGithubPolicySummarySchema.nullable()
43132
43132
  });
43133
+ var softwareFactoryTeardownTriggerSchema = external_exports.enum(["manual", "entitlement_lapse"]);
43134
+ var softwareDeveloperTeamUninstallInputSchema = external_exports.object({
43135
+ // DER-1241: this command is human-confirmed, so its input round-trips through
43136
+ // `pending_confirmations.input` (JSONB) and is re-parsed on approve replay. Use
43137
+ // `.nullable().optional()` (not a bare `.optional()`) so an omitted reason persists
43138
+ // as JSON `null` and re-parses cleanly, matching the sibling install schema.
43139
+ reason: external_exports.string().max(500).nullable().optional(),
43140
+ trigger: softwareFactoryTeardownTriggerSchema.default("manual")
43141
+ }).strict();
43142
+ var softwareDeveloperTeamDecommissionedAgentSchema = external_exports.object({
43143
+ role: softwareDeveloperTeamRoleSchema.nullable(),
43144
+ seat_id: uuid10,
43145
+ agent_id: uuid10
43146
+ });
43147
+ var softwareDeveloperTeamUninstallOutputSchema = external_exports.object({
43148
+ torn_down: external_exports.boolean(),
43149
+ trigger: softwareFactoryTeardownTriggerSchema,
43150
+ // The count of non-decommissioned team seats found under the ltree prefix (the human
43151
+ // forge_lead seat is included in the scope but is never decommissioned).
43152
+ seats_scoped: external_exports.number().int().nonnegative(),
43153
+ agents_decommissioned: external_exports.array(softwareDeveloperTeamDecommissionedAgentSchema),
43154
+ authority_grants_revoked: external_exports.number().int().nonnegative(),
43155
+ secret_grants_revoked: external_exports.number().int().nonnegative()
43156
+ });
43133
43157
  var forgeArtifactText = external_exports.string().trim().min(1).max(4e3);
43134
43158
  var forgeArtifactList = external_exports.array(forgeArtifactText).max(50).default([]);
43135
43159
  var forgeTaskKey = external_exports.string().trim().min(1).max(200);
@@ -45149,7 +45173,7 @@ External connectors are being rolled out provider by provider, conservatively (r
45149
45173
  order: 48,
45150
45174
  title: "CLI and MCP installation guide",
45151
45175
  summary: "Install the public CLI, register remote token-backed MCP clients, and find the full command and tool catalog.",
45152
- version: "2026-07-05.2",
45176
+ version: "2026-07-05.3",
45153
45177
  public: true,
45154
45178
  audiences: ["human", "cli", "mcp", "in_app_agent"],
45155
45179
  stages: ["company_setup", "staffing"],
@@ -45887,6 +45911,7 @@ Several rows here are seat-operating commands (\`task.create\`, the \`signal.*\`
45887
45911
  | \`rost_grant_forge_seat_authority\` | \`software_factory.authority.grant\` | Grant a seat a Forge authority profile on a project (seat \u2192 project \u2192 profile). Owner-only and human-gated; emits a durable authority-change event. | Tenant-admin | Call with \`{"software_project_id":"<project-id>","seat_id":"<seat-id>","authority_profile_id":"<profile-id>"}\`; non-interactive callers receive a confirmation handoff. |
45888
45912
  | \`rost_revoke_forge_seat_authority\` | \`software_factory.authority.revoke\` | Revoke a Forge authority grant (teardown). Owner-only and human-gated. | Tenant-admin | Call with \`{"grant_id":"<grant-id>"}\`; non-interactive callers receive a confirmation handoff. |
45889
45913
  | \`rost_install_forge_developer_team\` | \`software_factory.developer_team.install\` | Install AND activate the governed Forge Developer Team: Forge Lead (human) plus Planner, Builder, plan reviewer, security reviewer, QA/release, and Fold/Memory seats with draft Charters, first-party Forge Skills, and authority presets. Approving ALSO auto-staffs the 6 agent seats as live occupancies at a pull-request-only, observe-first posture (open pull requests, never merge/deploy without a human), steward-chained to the human lead, each with a signed manifest + passed sandbox dry-run; the 6 agent seats staff the runner lane and go live in a PARKED state \u2014 they become claimable once a runner pairs and cannot claim work before then; it sets a conservative default token budget (only if none) and, for a supplied project, a default pr_only GitHub automation policy (only if none \u2014 never widening a stricter one). Entitlement-gated and human-gated. | Tenant-admin | Call with \`{"steward_seat_id":"<human-steward-seat-id>"}\` \u2014 \`software_project_id\` is optional (when supplied it scopes authority grants to that project; the team installs tenant-wide either way). If the company autonomy ceiling is more permissive than the observe-first envelope, add \`{"acknowledge_autonomy_ceiling":true}\` to activate. Add \`{"lane_overrides":{"qa_release":"cloud"}}\` to pin a role to the cloud lane instead of the default runner lane. Non-interactive callers receive a confirmation handoff. |
45914
+ | \`rost_uninstall_forge_developer_team\` | \`software_factory.developer_team.uninstall\` | Tear down the governed Forge Developer Team (teardown \u2014 ADR-0018 \xA76): end the auto-staffed agent occupancies in a no-orphan-safe order, decommission the agents, and revoke the team's project authority and secret grants. The human Forge Lead seat is left intact; re-installing re-staffs the team. The entitlement-lapse variant runs the same teardown path without re-checking the Forge paywall. Owner-only and human-gated. | Tenant-admin | Call with \`{}\` (optionally \`{"reason":"offboarding"}\`); non-interactive callers receive a confirmation handoff. |
45890
45915
  | \`rost_list_forge_config\` | \`software_factory.config.list\` | List active Forge configuration entries. Plain values may be returned only when they passed the non-secret guard; secret refs appear as metadata and never include the ref value. | Tenant | Call with \`{}\` or \`{"software_project_id":"<project-id>","environment":"preview"}\`. |
45891
45916
  | \`rost_set_forge_config\` | \`software_factory.config.set\` | Human-gated config create/rotation for plain values or secret refs. Secret refs store only a vault pointer and raw secret-shaped plain values are rejected. | Tenant-admin | Call with \`{"software_project_id":"<project-id>","environment":"preview","key_name":"PUBLIC_BASE_URL","value_kind":"plain","plain_value":"https://preview.example.com"}\`. |
45892
45917
  | \`rost_list_forge_secret_requests\` | \`software_factory.secret_request.list\` | List missing-secret requests and their approval Task ids/statuses. It returns request metadata only \u2014 no secret values and no vault refs. | Tenant | Call with \`{}\` or \`{"status":"pending"}\`. |
@@ -49101,6 +49126,7 @@ var COMMAND_MANIFEST = [
49101
49126
  { "id": "software_factory.config.set", "namespace": "software_factory", "action": "config.set", "title": "Set Forge config", "description": "Create or rotate a Forge project config entry. Secret config stores only a vault ref pointer; raw values are never accepted for secret_ref entries.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "software_project_id", "flag": "software-project-id", "type": "string", "required": true }, { "name": "environment", "flag": "environment", "type": "enum", "required": true, "enumValues": ["development", "preview", "production"] }, { "name": "key_name", "flag": "key-name", "type": "string", "required": true }, { "name": "value_kind", "flag": "value-kind", "type": "enum", "required": true, "enumValues": ["plain", "secret_ref"] }, { "name": "plain_value", "flag": "plain-value", "type": "string", "required": false }, { "name": "vault_ref", "flag": "vault-ref", "type": "string", "required": false }], "hasComplexInput": false, "help": "Set or rotate a Forge project config key. Secret entries store only vault refs and are human-gated." },
49102
49127
  { "id": "software_factory.conformance.record_findings", "namespace": "software_factory", "action": "conformance.record_findings", "title": "Record Forge conformance findings", "description": "The plan-conformance reviewer records one or more findings against a build request; open findings route the request back to implementation. Recording is evidence, not a decision \u2014 accepting a gap is a separate human gate. Requires the Forge add-on.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "build_request_id", "flag": "build-request-id", "type": "string", "required": true }, { "name": "phase_run_id", "flag": "phase-run-id", "type": "string", "required": false }], "hasComplexInput": true, "help": "Record structured Forge plan-conformance findings as reviewer evidence. Open findings route the request back to implementation; accepting a gap remains a separate human gate." },
49103
49128
  { "id": "software_factory.developer_team.install", "namespace": "software_factory", "action": "developer_team.install", "title": "Install Forge Developer Team", "description": "Install AND activate the governed Forge Developer Team: 7 seats (1 human lead + 6 agents), first-party skills, authority presets, and a conservative token budget. Approving this ACTIVATES the 6 agents as live occupancies at a pr_only, observe-first posture: they open pull requests but never merge or deploy without a human. Entitlement-gated and human-confirmed.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "steward_seat_id", "flag": "steward-seat-id", "type": "string", "required": true }, { "name": "software_project_id", "flag": "software-project-id", "type": "string", "required": false }, { "name": "assign_skills", "flag": "assign-skills", "type": "boolean", "required": false }, { "name": "acknowledge_autonomy_ceiling", "flag": "acknowledge-autonomy-ceiling", "type": "boolean", "required": false }], "hasComplexInput": true, "help": "Install the governed Forge Developer Team template with seats, draft Charters, skills, project authority grants, and audit records. Tenant-admin and human-gated; creates no live agent occupancy." },
49129
+ { "id": "software_factory.developer_team.uninstall", "namespace": "software_factory", "action": "developer_team.uninstall", "title": "Uninstall Forge Developer Team", "description": "Tear down the governed Forge Developer Team (ADR-0018 \xA76): end the auto-staffed agent occupancies in a no-orphan-safe order, decommission the agents, and revoke the team's project authority and secret grants. The human Forge Lead seat is left intact; re-installing re-staffs the team. The entitlement-lapse variant runs the same teardown path without re-checking the Forge paywall. Owner-only, human-gated, and audited.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "reason", "flag": "reason", "type": "string", "required": false }, { "name": "trigger", "flag": "trigger", "type": "enum", "required": false, "enumValues": ["manual", "entitlement_lapse"] }], "hasComplexInput": false, "help": "Tear down the Forge Developer Team (teardown \u2014 ADR-0018 \xA76): end the agent occupancies in a no-orphan-safe order, decommission the agents, and revoke the team's authority and secret grants. The human Forge Lead seat stays. Owner-only and human-gated; the entitlement-lapse variant runs the same teardown path." },
49104
49130
  { "id": "software_factory.gate.decide", "namespace": "software_factory", "action": "gate.decide", "title": "Decide a Forge gate", "description": "A human approves or rejects a Forge gate. The resolver is recorded (never an agent \u2014 invariant #7); sensitive gates (security sign-off, merge/deploy, authority change, production deploy) also write a linked human decision. Requires confirmation.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "gate_id", "flag": "gate-id", "type": "string", "required": true }, { "name": "decision", "flag": "decision", "type": "enum", "required": true, "enumValues": ["approve", "reject"] }, { "name": "rationale", "flag": "rationale", "type": "string", "required": false }], "hasComplexInput": false, "help": "A human approves or rejects a Forge gate; an agent caller routes to /approvals and can never self-approve. Sensitive gates record a human decision." },
49105
49131
  { "id": "software_factory.github.installation_token.create", "namespace": "software_factory", "action": "github.installation_token.create", "title": "Create a Forge GitHub installation token", "description": "Mint a short-lived GitHub App installation token for one bound repository after server-side policy evaluation. The token is returned once and never persisted.", "requiredScope": "tenant", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "software_project_id", "flag": "software-project-id", "type": "string", "required": true }, { "name": "repository_id", "flag": "repository-id", "type": "integer", "required": true }, { "name": "requested_actions", "flag": "requested-actions", "type": "array", "required": true, "itemType": "string" }, { "name": "requested_automation_mode", "flag": "requested-automation-mode", "type": "enum", "required": false, "enumValues": ["plan_only", "pr_only", "merge_after_checks", "deploy_preview", "deploy_production"] }, { "name": "seat_id", "flag": "seat-id", "type": "string", "required": false }], "hasComplexInput": false, "help": "Mint a short-lived GitHub App installation token for one bound repository after policy evaluation; token material is returned once and never stored." },
49106
49132
  { "id": "software_factory.github.installation.bind", "namespace": "software_factory", "action": "github.installation.bind", "title": "Bind Forge GitHub repositories to projects", "description": "Bind already-connected GitHub repositories to Forge projects. Owner-only and human-gated; operates on repositories already verified and connected in this tenant, so no GitHub re-authorization is required. Available any time, add or re-map bindings.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": false, "fields": [{ "name": "app_slug", "flag": "app-slug", "type": "string", "required": false }, { "name": "installation_id", "flag": "installation-id", "type": "integer", "required": true }], "hasComplexInput": true, "help": "Bind already-connected GitHub repositories to Forge projects from the Forge GitHub settings flow. Owner-only and human-gated; no GitHub re-authorization required." },
@@ -51670,13 +51696,43 @@ function parseSemver2(value) {
51670
51696
  }
51671
51697
 
51672
51698
  // src/runner-serve.ts
51673
- import { execFile as execFileCallback3, spawn } from "node:child_process";
51699
+ import { execFile as execFileCallback4, spawn } from "node:child_process";
51674
51700
  import { createHash } from "node:crypto";
51675
51701
  import { chmod, mkdir as mkdir2, readFile as readFile3, rename, rm as rm3, statfs, writeFile as writeFile2 } from "node:fs/promises";
51676
51702
  import { cpus, homedir as homedir2, hostname as hostname3, platform, totalmem, tmpdir } from "node:os";
51677
51703
  import path4 from "node:path";
51678
51704
  import { setTimeout as sleep2 } from "node:timers/promises";
51705
+ import { promisify as promisify4 } from "node:util";
51706
+
51707
+ // src/forge-workspace.ts
51708
+ import { execFile as execFileCallback3 } from "node:child_process";
51679
51709
  import { promisify as promisify3 } from "node:util";
51710
+ var execFile3 = promisify3(execFileCallback3);
51711
+ var MODEL_SPAWN_ENV_ALLOWLIST = [
51712
+ "PATH",
51713
+ "HOME",
51714
+ "LANG",
51715
+ "LC_ALL",
51716
+ "TMPDIR",
51717
+ "SHELL",
51718
+ "NODE_OPTIONS"
51719
+ ];
51720
+ function buildModelSpawnEnv(base) {
51721
+ const out = {};
51722
+ for (const key of MODEL_SPAWN_ENV_ALLOWLIST) {
51723
+ const value = base[key];
51724
+ if (typeof value === "string") {
51725
+ out[key] = value;
51726
+ }
51727
+ }
51728
+ return out;
51729
+ }
51730
+ var CLONE_TIMEOUT_MS = 10 * 6e4;
51731
+ var FETCH_TIMEOUT_MS = 5 * 6e4;
51732
+ var PUSH_TIMEOUT_MS = 5 * 6e4;
51733
+ var GIT_MAX_BUFFER = 64 * 1024 * 1024;
51734
+ var FORGE_GIT_AUTHOR_NAME = `${BRAND.name} ${RSF_ADDON_BRAND.shortName}`;
51735
+ var FORGE_GIT_AUTHOR_EMAIL = `${RSF_ADDON_BRAND.cliGroup}@${BRAND_DISTRIBUTION.cliBinName}.invalid`;
51680
51736
 
51681
51737
  // src/runner-sandbox.ts
51682
51738
  import { existsSync as existsSync2, realpathSync } from "node:fs";
@@ -51913,7 +51969,7 @@ async function sweepStaleRunnerTempFiles(dir, options = {}) {
51913
51969
  }
51914
51970
 
51915
51971
  // src/runner-serve.ts
51916
- var execFile3 = promisify3(execFileCallback3);
51972
+ var execFile4 = promisify4(execFileCallback4);
51917
51973
  var RUNNER_WORK_ORDER_TOOLS = [
51918
51974
  "mcp__rost__rost_get_context",
51919
51975
  "mcp__rost__rost_report_status",
@@ -52276,7 +52332,7 @@ async function detectCapabilities(cliVersion, env, homeDir) {
52276
52332
  }
52277
52333
  async function probe(command) {
52278
52334
  try {
52279
- const { stdout, stderr } = await execFile3(command, ["--version"], { timeout: 1500 });
52335
+ const { stdout, stderr } = await execFile4(command, ["--version"], { timeout: 1500 });
52280
52336
  return { installed: true, version: (stdout || stderr).trim() || null, auth_state: "ready" };
52281
52337
  } catch {
52282
52338
  return { installed: false, version: null, auth_state: "unknown" };
@@ -52284,7 +52340,7 @@ async function probe(command) {
52284
52340
  }
52285
52341
  async function probeGit() {
52286
52342
  try {
52287
- const { stdout, stderr } = await execFile3("git", ["--version"], { timeout: 1500 });
52343
+ const { stdout, stderr } = await execFile4("git", ["--version"], { timeout: 1500 });
52288
52344
  const raw = (stdout || stderr).trim();
52289
52345
  return { installed: true, version: /(\d+\.\d+(?:\.\d+)?)/.exec(raw)?.[1] ?? (raw || null) };
52290
52346
  } catch {
@@ -52293,7 +52349,7 @@ async function probeGit() {
52293
52349
  }
52294
52350
  async function probeGh() {
52295
52351
  try {
52296
- const { stdout, stderr } = await execFile3("gh", ["--version"], { timeout: 1500 });
52352
+ const { stdout, stderr } = await execFile4("gh", ["--version"], { timeout: 1500 });
52297
52353
  const raw = (stdout || stderr).trim().split("\n")[0]?.trim() ?? "";
52298
52354
  const authenticated = await probeGhAuth();
52299
52355
  return { installed: true, version: /(\d+\.\d+\.\d+)/.exec(raw)?.[1] ?? (raw || null), authenticated };
@@ -52303,7 +52359,7 @@ async function probeGh() {
52303
52359
  }
52304
52360
  async function probeGhAuth() {
52305
52361
  try {
52306
- await execFile3("gh", ["auth", "status"], { timeout: 1500 });
52362
+ await execFile4("gh", ["auth", "status"], { timeout: 1500 });
52307
52363
  return true;
52308
52364
  } catch {
52309
52365
  return false;
@@ -52515,6 +52571,7 @@ async function spawnRunnerTurn(appUrl2, workOrder, runtime, kind, sandbox, state
52515
52571
  };
52516
52572
  const child = spawn(command, args, {
52517
52573
  cwd: tmpdir(),
52574
+ env: buildModelSpawnEnv(process.env),
52518
52575
  stdio: ["ignore", "pipe", "pipe"]
52519
52576
  });
52520
52577
  let out = "";
@@ -52642,13 +52699,13 @@ function usage() {
52642
52699
  }
52643
52700
 
52644
52701
  // src/runner-service.ts
52645
- import { execFile as execFileCallback4 } from "node:child_process";
52702
+ import { execFile as execFileCallback5 } from "node:child_process";
52646
52703
  import { realpathSync as realpathSync2 } from "node:fs";
52647
52704
  import { access as access2, mkdir as mkdir3, readFile as readFile4, rm as rm4, writeFile as writeFile3 } from "node:fs/promises";
52648
52705
  import { homedir as homedir3 } from "node:os";
52649
52706
  import path5 from "node:path";
52650
- import { promisify as promisify4 } from "node:util";
52651
- var execFile4 = promisify4(execFileCallback4);
52707
+ import { promisify as promisify5 } from "node:util";
52708
+ var execFile5 = promisify5(execFileCallback5);
52652
52709
  var SERVICE_VERBS = ["install-service", "start", "stop", "restart", "status", "logs", "uninstall"];
52653
52710
  function isServiceVerb(value) {
52654
52711
  return value !== void 0 && SERVICE_VERBS.includes(value);
@@ -53207,7 +53264,7 @@ function escapePlist(value) {
53207
53264
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
53208
53265
  }
53209
53266
  var defaultExec = async (file2, args, options) => {
53210
- const result = await execFile4(file2, args, options?.env ? { env: options.env } : {});
53267
+ const result = await execFile5(file2, args, options?.env ? { env: options.env } : {});
53211
53268
  return { stdout: String(result.stdout), stderr: String(result.stderr) };
53212
53269
  };
53213
53270
  function assertNever2(value) {