@rosthq/cli 0.7.31 → 0.7.33

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"}
package/dist/index.js CHANGED
@@ -42464,6 +42464,16 @@ var softwareDeveloperTeamRoleSchema = external_exports.enum([
42464
42464
  "qa_release",
42465
42465
  "fold_memory"
42466
42466
  ]);
42467
+ var softwareDeveloperTeamLaneSchema = external_exports.enum(["runner", "cloud"]);
42468
+ var softwareDeveloperTeamLaneOverridesSchema = external_exports.object({
42469
+ forge_lead: softwareDeveloperTeamLaneSchema.optional(),
42470
+ planner: softwareDeveloperTeamLaneSchema.optional(),
42471
+ builder: softwareDeveloperTeamLaneSchema.optional(),
42472
+ plan_conformance_reviewer: softwareDeveloperTeamLaneSchema.optional(),
42473
+ security_reviewer: softwareDeveloperTeamLaneSchema.optional(),
42474
+ qa_release: softwareDeveloperTeamLaneSchema.optional(),
42475
+ fold_memory: softwareDeveloperTeamLaneSchema.optional()
42476
+ }).strict();
42467
42477
  var softwareEnvironmentSchema = external_exports.enum(["development", "preview", "production"]);
42468
42478
  var softwareGrantStatusSchema = external_exports.enum(["active", "revoked"]);
42469
42479
  var softwareConfigValueKindSchema = external_exports.enum(["plain", "secret_ref"]);
@@ -43045,7 +43055,14 @@ var softwareDeveloperTeamInstallInputSchema = external_exports.object({
43045
43055
  // auto-activate unless the owner explicitly acknowledges that posture. Never
43046
43056
  // silently inherit a more-permissive-than-designed ceiling (invariant #10). A
43047
43057
  // tenant within the envelope (locked_down/balanced) never needs this.
43048
- acknowledge_autonomy_ceiling: external_exports.boolean().default(false)
43058
+ acknowledge_autonomy_ceiling: external_exports.boolean().default(false),
43059
+ // DER-1317 (T0.2a): optionally pin an individual role to a specific execution
43060
+ // lane. Omitted roles staff their declared default lane (phase-owning agents =
43061
+ // `runner`; the human `forge_lead` seat is never staffed with an agent, so its
43062
+ // override is inert). `.nullable()` for the same confirm-replay round-trip
43063
+ // reason as `software_project_id` above (JSONB re-parse of a human-confirmed
43064
+ // command tolerates a JSON `null` for an omitted object).
43065
+ lane_overrides: softwareDeveloperTeamLaneOverridesSchema.nullable().optional()
43049
43066
  }).strict();
43050
43067
  var softwareDeveloperTeamSeatSummarySchema = external_exports.object({
43051
43068
  role: softwareDeveloperTeamRoleSchema,
@@ -45132,7 +45149,7 @@ External connectors are being rolled out provider by provider, conservatively (r
45132
45149
  order: 48,
45133
45150
  title: "CLI and MCP installation guide",
45134
45151
  summary: "Install the public CLI, register remote token-backed MCP clients, and find the full command and tool catalog.",
45135
- version: "2026-07-05.1",
45152
+ version: "2026-07-05.2",
45136
45153
  public: true,
45137
45154
  audiences: ["human", "cli", "mcp", "in_app_agent"],
45138
45155
  stages: ["company_setup", "staffing"],
@@ -45869,7 +45886,7 @@ Several rows here are seat-operating commands (\`task.create\`, the \`signal.*\`
45869
45886
  | \`rost_create_a_forge_authority_profile\` | \`software_factory.authority_profile.create\` | Define a Forge authority profile (a named seat capability preset). Owner-only; defaults to the read_only preset. | Tenant-admin | Call with \`{"name":"Builder","preset":"contributor"}\`. |
45870
45887
  | \`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. |
45871
45888
  | \`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. |
45872
- | \`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; 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. Non-interactive callers receive a confirmation handoff. |
45889
+ | \`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. |
45873
45890
  | \`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"}\`. |
45874
45891
  | \`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"}\`. |
45875
45892
  | \`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"}\`. |
@@ -49083,7 +49100,7 @@ var COMMAND_MANIFEST = [
49083
49100
  { "id": "software_factory.config.list", "namespace": "software_factory", "action": "config.list", "title": "List Forge config", "description": "List active Forge config metadata for project environments. Plain config values may be returned; secret refs are represented only as has_secret_ref.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "software_project_id", "flag": "software-project-id", "type": "string", "required": false }, { "name": "environment", "flag": "environment", "type": "enum", "required": false, "enumValues": ["development", "preview", "production"] }], "hasComplexInput": false, "help": "List active Forge config entries. Plain config may be shown; secret refs are represented only as metadata." },
49084
49101
  { "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." },
49085
49102
  { "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." },
49086
- { "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": false, "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." },
49103
+ { "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." },
49087
49104
  { "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." },
49088
49105
  { "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." },
49089
49106
  { "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." },
@@ -51653,13 +51670,43 @@ function parseSemver2(value) {
51653
51670
  }
51654
51671
 
51655
51672
  // src/runner-serve.ts
51656
- import { execFile as execFileCallback3, spawn } from "node:child_process";
51673
+ import { execFile as execFileCallback4, spawn } from "node:child_process";
51657
51674
  import { createHash } from "node:crypto";
51658
51675
  import { chmod, mkdir as mkdir2, readFile as readFile3, rename, rm as rm3, statfs, writeFile as writeFile2 } from "node:fs/promises";
51659
51676
  import { cpus, homedir as homedir2, hostname as hostname3, platform, totalmem, tmpdir } from "node:os";
51660
51677
  import path4 from "node:path";
51661
51678
  import { setTimeout as sleep2 } from "node:timers/promises";
51679
+ import { promisify as promisify4 } from "node:util";
51680
+
51681
+ // src/forge-workspace.ts
51682
+ import { execFile as execFileCallback3 } from "node:child_process";
51662
51683
  import { promisify as promisify3 } from "node:util";
51684
+ var execFile3 = promisify3(execFileCallback3);
51685
+ var MODEL_SPAWN_ENV_ALLOWLIST = [
51686
+ "PATH",
51687
+ "HOME",
51688
+ "LANG",
51689
+ "LC_ALL",
51690
+ "TMPDIR",
51691
+ "SHELL",
51692
+ "NODE_OPTIONS"
51693
+ ];
51694
+ function buildModelSpawnEnv(base) {
51695
+ const out = {};
51696
+ for (const key of MODEL_SPAWN_ENV_ALLOWLIST) {
51697
+ const value = base[key];
51698
+ if (typeof value === "string") {
51699
+ out[key] = value;
51700
+ }
51701
+ }
51702
+ return out;
51703
+ }
51704
+ var CLONE_TIMEOUT_MS = 10 * 6e4;
51705
+ var FETCH_TIMEOUT_MS = 5 * 6e4;
51706
+ var PUSH_TIMEOUT_MS = 5 * 6e4;
51707
+ var GIT_MAX_BUFFER = 64 * 1024 * 1024;
51708
+ var FORGE_GIT_AUTHOR_NAME = `${BRAND.name} ${RSF_ADDON_BRAND.shortName}`;
51709
+ var FORGE_GIT_AUTHOR_EMAIL = `${RSF_ADDON_BRAND.cliGroup}@${BRAND_DISTRIBUTION.cliBinName}.invalid`;
51663
51710
 
51664
51711
  // src/runner-sandbox.ts
51665
51712
  import { existsSync as existsSync2, realpathSync } from "node:fs";
@@ -51896,7 +51943,7 @@ async function sweepStaleRunnerTempFiles(dir, options = {}) {
51896
51943
  }
51897
51944
 
51898
51945
  // src/runner-serve.ts
51899
- var execFile3 = promisify3(execFileCallback3);
51946
+ var execFile4 = promisify4(execFileCallback4);
51900
51947
  var RUNNER_WORK_ORDER_TOOLS = [
51901
51948
  "mcp__rost__rost_get_context",
51902
51949
  "mcp__rost__rost_report_status",
@@ -52259,7 +52306,7 @@ async function detectCapabilities(cliVersion, env, homeDir) {
52259
52306
  }
52260
52307
  async function probe(command) {
52261
52308
  try {
52262
- const { stdout, stderr } = await execFile3(command, ["--version"], { timeout: 1500 });
52309
+ const { stdout, stderr } = await execFile4(command, ["--version"], { timeout: 1500 });
52263
52310
  return { installed: true, version: (stdout || stderr).trim() || null, auth_state: "ready" };
52264
52311
  } catch {
52265
52312
  return { installed: false, version: null, auth_state: "unknown" };
@@ -52267,7 +52314,7 @@ async function probe(command) {
52267
52314
  }
52268
52315
  async function probeGit() {
52269
52316
  try {
52270
- const { stdout, stderr } = await execFile3("git", ["--version"], { timeout: 1500 });
52317
+ const { stdout, stderr } = await execFile4("git", ["--version"], { timeout: 1500 });
52271
52318
  const raw = (stdout || stderr).trim();
52272
52319
  return { installed: true, version: /(\d+\.\d+(?:\.\d+)?)/.exec(raw)?.[1] ?? (raw || null) };
52273
52320
  } catch {
@@ -52276,7 +52323,7 @@ async function probeGit() {
52276
52323
  }
52277
52324
  async function probeGh() {
52278
52325
  try {
52279
- const { stdout, stderr } = await execFile3("gh", ["--version"], { timeout: 1500 });
52326
+ const { stdout, stderr } = await execFile4("gh", ["--version"], { timeout: 1500 });
52280
52327
  const raw = (stdout || stderr).trim().split("\n")[0]?.trim() ?? "";
52281
52328
  const authenticated = await probeGhAuth();
52282
52329
  return { installed: true, version: /(\d+\.\d+\.\d+)/.exec(raw)?.[1] ?? (raw || null), authenticated };
@@ -52286,7 +52333,7 @@ async function probeGh() {
52286
52333
  }
52287
52334
  async function probeGhAuth() {
52288
52335
  try {
52289
- await execFile3("gh", ["auth", "status"], { timeout: 1500 });
52336
+ await execFile4("gh", ["auth", "status"], { timeout: 1500 });
52290
52337
  return true;
52291
52338
  } catch {
52292
52339
  return false;
@@ -52498,6 +52545,7 @@ async function spawnRunnerTurn(appUrl2, workOrder, runtime, kind, sandbox, state
52498
52545
  };
52499
52546
  const child = spawn(command, args, {
52500
52547
  cwd: tmpdir(),
52548
+ env: buildModelSpawnEnv(process.env),
52501
52549
  stdio: ["ignore", "pipe", "pipe"]
52502
52550
  });
52503
52551
  let out = "";
@@ -52625,13 +52673,13 @@ function usage() {
52625
52673
  }
52626
52674
 
52627
52675
  // src/runner-service.ts
52628
- import { execFile as execFileCallback4 } from "node:child_process";
52676
+ import { execFile as execFileCallback5 } from "node:child_process";
52629
52677
  import { realpathSync as realpathSync2 } from "node:fs";
52630
52678
  import { access as access2, mkdir as mkdir3, readFile as readFile4, rm as rm4, writeFile as writeFile3 } from "node:fs/promises";
52631
52679
  import { homedir as homedir3 } from "node:os";
52632
52680
  import path5 from "node:path";
52633
- import { promisify as promisify4 } from "node:util";
52634
- var execFile4 = promisify4(execFileCallback4);
52681
+ import { promisify as promisify5 } from "node:util";
52682
+ var execFile5 = promisify5(execFileCallback5);
52635
52683
  var SERVICE_VERBS = ["install-service", "start", "stop", "restart", "status", "logs", "uninstall"];
52636
52684
  function isServiceVerb(value) {
52637
52685
  return value !== void 0 && SERVICE_VERBS.includes(value);
@@ -53190,7 +53238,7 @@ function escapePlist(value) {
53190
53238
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
53191
53239
  }
53192
53240
  var defaultExec = async (file2, args, options) => {
53193
- const result = await execFile4(file2, args, options?.env ? { env: options.env } : {});
53241
+ const result = await execFile5(file2, args, options?.env ? { env: options.env } : {});
53194
53242
  return { stdout: String(result.stdout), stderr: String(result.stderr) };
53195
53243
  };
53196
53244
  function assertNever2(value) {