Skip to content

refactor: resolve host process state through Effect#2959

Open
juliusmarminge wants to merge 3 commits into
mainfrom
codex/effect-runtime-build-target
Open

refactor: resolve host process state through Effect#2959
juliusmarminge wants to merge 3 commits into
mainfrom
codex/effect-runtime-build-target

Conversation

@juliusmarminge
Copy link
Copy Markdown
Member

@juliusmarminge juliusmarminge commented Jun 4, 2026

Summary

  • add shared @t3tools/shared/hostProcess references for host platform, architecture, and process env
  • migrate desktop artifact resolution/build, scripts, SSH/Tailscale helpers, server environment/telemetry/diagnostics, provider drivers, provider runtimes, and text-generation factories to read ambient platform/env through Effect references/config instead of direct process.* access
  • keep explicit platform/env arguments as test seams where callers already provide them, but move ambient defaults into Effect bodies
  • keep lockfile churn minimal; pnpm-lock.yaml only records the new @t3tools/tailscale -> @t3tools/shared workspace dependency

Validation

  • vp install
  • vp install --frozen-lockfile
  • vp check
  • vp run typecheck
  • vp test scripts/lib/build-target-arch.test.ts scripts/build-desktop-artifact.test.ts packages/ssh/src/auth.test.ts packages/ssh/src/command.test.ts packages/ssh/src/tunnel.test.ts packages/tailscale/src/tailscale.test.ts

Notes

  • Tried full vp test, but stopped it after it started collecting vendored .repos tests and hit existing unrelated web test failures in saved-environment/thread-subscription/message timeline suites.
  • Remaining direct process.* uses are mostly pure helper seams, terminal internals, config/bootstrap paths, test fixtures/examples, package dist output, and the shared reference defaults.

Note

Medium Risk
Wide cross-cutting refactor touching spawn options, PATH/command resolution, and many formerly sync APIs; behavior should match defaults but regressions on Windows/WSL and provider child processes are plausible.

Overview
Introduces HostProcessPlatform and HostProcessArchitecture as Effect context references (with process.* defaults) and routes platform/arch decisions through them across desktop, server, providers, terminals, diagnostics, telemetry, and build scripts.

Server/runtime behavior shifts from ad hoc process.platform / process.env reads to yield* HostProcessPlatform, Config-backed env (browser launch, terminals, maintenance), and extendEnv on spawns where only overrides are passed. Several helpers become Effect APIs (fixPath, readProcessRows, resolveBrowserLaunch, isCommandAvailableForPlatform, resolveWindowsEnvironment, etc.), and resolveFdPath now requires an explicit platform argument.

Desktop wires platform into DesktopEnvironment and window/menu code; standalone .mjs scripts use node:os with lint exceptions instead of process.platform. Tests gain HostProcessPlatform layers instead of mutating process.platform or passing platform into every call.

Reviewed by Cursor Bugbot for commit 646023a. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Replace direct process.platform/process.arch reads with injectable HostProcessPlatform and HostProcessArchitecture Effect services

  • Introduces HostProcessPlatform and HostProcessArchitecture as Context.Reference values in packages/shared/src/hostProcess.ts, defaulting to process.platform/process.arch so existing runtimes are unaffected.
  • Replaces direct process.platform/process.arch reads across the server, desktop, SSH, terminal, provider, and script layers with yield* HostProcessPlatform / yield* HostProcessArchitecture, enabling injection in tests and controlled environments.
  • Adds a new t3code/no-global-process-runtime oxlint rule that flags direct process.platform, process.arch, and node:os platform/arch calls in application code, enforcing the pattern going forward.
  • Converts several synchronous functions (isCommandAvailable, resolveCommandPath, isWindowsCommandNotFound, fixPath, resolveWindowsEnvironment, etc.) to Effect.fn generators that read platform from the service rather than globals.
  • Replaces process.env reads in environment-sensitive paths (browser launch, command lookup, terminal env, SSH display) with scoped Effect Config providers, reducing implicit global state.
  • Behavioral Change: child processes across drivers, SSH, terminal, and build scripts now set shell: true only on Windows (via HostProcessPlatform); previously some paths used unconditional or inconsistent shell settings. extendEnv: true replaces manual process.env spreading in several spawn sites.

Macroscope summarized 646023a.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 4, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ad76c148-eb14-4092-a951-38e7e50c760a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/effect-runtime-build-target

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jun 4, 2026
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: WoA heuristics ignore build platform
    • Added an optional buildPlatform parameter to resolveHostProcessArch and passed the build platform from getDefaultBuildArch, so WoA env var heuristics are skipped when the target platform is not Windows.

Create PR

Or push these changes by commenting:

@cursor push c3131c09e1
Preview (c3131c09e1)
diff --git a/scripts/lib/build-target-arch.test.ts b/scripts/lib/build-target-arch.test.ts
--- a/scripts/lib/build-target-arch.test.ts
+++ b/scripts/lib/build-target-arch.test.ts
@@ -83,7 +83,7 @@
   it.effect("does not apply Windows host env heuristics for non-Windows targets", () =>
     Effect.gen(function* () {
       const arch = yield* getDefaultBuildArch("linux", { archChoices: ["x64", "arm64"] }).pipe(
-        withHostRuntime("linux", "x64", {
+        withHostRuntime("win32", "x64", {
           PROCESSOR_ARCHITECTURE: "AMD64",
           PROCESSOR_ARCHITEW6432: "ARM64",
         }),

diff --git a/scripts/lib/build-target-arch.ts b/scripts/lib/build-target-arch.ts
--- a/scripts/lib/build-target-arch.ts
+++ b/scripts/lib/build-target-arch.ts
@@ -40,13 +40,19 @@
 const optionToUndefined = <A>(value: Option.Option<A>): A | undefined =>
   Option.getOrUndefined(value);
 
-export const resolveHostProcessArch = Effect.fn("resolveHostProcessArch")(function* () {
+export const resolveHostProcessArch = Effect.fn("resolveHostProcessArch")(function* (
+  buildPlatform?: BuildPlatform,
+) {
   const platform = yield* HostProcessPlatform;
   const processArch = yield* HostProcessArchitecture;
   if (processArch === "arm64") return "arm64";
   if (processArch === "x64") {
     if (platform !== "win32") return "x64";
 
+    // Only apply WoA heuristics when building for Windows (or when no build
+    // platform is specified, e.g. bare host-arch queries).
+    if (buildPlatform !== undefined && buildPlatform !== "win") return "x64";
+
     // On Windows-on-Arm, x64 Node/Bun can run under emulation while the host
     // still reports ARM64 via the processor environment variables.
     const env = yield* WindowsProcessorArchitectureConfig;
@@ -63,7 +69,7 @@
   platform: BuildPlatform,
   platformConfig: PlatformConfig,
 ) {
-  const hostArch = yield* resolveHostProcessArch();
+  const hostArch = yield* resolveHostProcessArch(platform);
   if (hostArch && platformConfig.archChoices.includes(hostArch)) {
     return hostArch;
   }

You can send follow-ups to the cloud agent here.

Comment thread scripts/lib/build-target-arch.ts
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Jun 4, 2026

Approvability

Verdict: Needs human review

2 blocking correctness issues found. Major infrastructure refactor introducing Effect-based host process state injection across the codebase. Unresolved review comments identify a high-severity bug in child process environment handling (dev-runner.ts) and a medium-severity bug in execute permission checking (shell.ts) that could cause runtime issues.

You can customize Macroscope's approvability policy. Learn more.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

🚀 Expo continuous deployment is ready!

  • Project → t3-code
  • Platforms → android, ios
  • Scheme → t3code-preview
  🤖 Android 🍎 iOS
Fingerprint 50af7188c45504c4cf76a4d9ba23a0d6e9b94177 2c1319138333022ef53422fedb7381e34b960fe8
Build Details Build Permalink
DetailsDistribution: INTERNAL
Build profile: preview:dev
Runtime version: 50af7188c45504c4cf76a4d9ba23a0d6e9b94177
App version: 0.1.0
Git commit: 164949f8f5f21bed252d05c476b4eee02aae5b5f
Build Permalink
DetailsDistribution: INTERNAL
Build profile: preview:dev
Runtime version: 2c1319138333022ef53422fedb7381e34b960fe8
App version: 0.1.0
Git commit: 164949f8f5f21bed252d05c476b4eee02aae5b5f
Update Details Update Permalink
DetailsBranch: pr-2959
Runtime version: 50af7188c45504c4cf76a4d9ba23a0d6e9b94177
Git commit: 164949f8f5f21bed252d05c476b4eee02aae5b5f
Update Permalink
DetailsBranch: pr-2959
Runtime version: 2c1319138333022ef53422fedb7381e34b960fe8
Git commit: 164949f8f5f21bed252d05c476b4eee02aae5b5f
Update QR

@juliusmarminge juliusmarminge force-pushed the codex/effect-runtime-build-target branch from 0e3f530 to 761cc7f Compare June 4, 2026 19:14
@github-actions github-actions Bot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Jun 4, 2026
@juliusmarminge juliusmarminge force-pushed the codex/effect-runtime-build-target branch from 761cc7f to d3e884f Compare June 4, 2026 19:42
@juliusmarminge juliusmarminge changed the title refactor(desktop): resolve build target from Effect context refactor: resolve host process state through Effect Jun 4, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Jun 4, 2026
@juliusmarminge juliusmarminge force-pushed the codex/effect-runtime-build-target branch from d3e884f to 5744aa5 Compare June 4, 2026 20:11
@macroscopeapp macroscopeapp Bot dismissed their stale review June 4, 2026 20:11

Dismissing prior approval to re-evaluate 5744aa5

@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Jun 4, 2026
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Editor check ignores host env
    • Replaced isCommandAvailable() (which uses process.platform/process.env) with isCommandAvailableForPlatform() using the yielded HostProcessPlatform and HostProcessEnv values, making the availability check consistent with the spawn behavior.

Create PR

Or push these changes by commenting:

@cursor push 26a4a08a64
Preview (26a4a08a64)
diff --git a/apps/server/src/process/externalLauncher.ts b/apps/server/src/process/externalLauncher.ts
--- a/apps/server/src/process/externalLauncher.ts
+++ b/apps/server/src/process/externalLauncher.ts
@@ -14,7 +14,6 @@
 } from "@t3tools/contracts";
 import { HostProcessEnv, HostProcessPlatform } from "@t3tools/shared/hostProcess";
 import {
-  isCommandAvailable,
   isCommandAvailableForPlatform,
   type PlatformCommandAvailabilityOptions,
 } from "@t3tools/shared/shell";
@@ -347,13 +346,14 @@
 export const launchEditorProcess = Effect.fn("externalLauncher.launchEditorProcess")(function* (
   launch: EditorLaunch,
 ): Effect.fn.Return<void, ExternalLauncherError, ChildProcessSpawner.ChildProcessSpawner> {
-  if (!isCommandAvailable(launch.command)) {
+  const platform = yield* HostProcessPlatform;
+  const env = yield* HostProcessEnv;
+
+  if (!isCommandAvailableForPlatform(launch.command, { platform, env })) {
     return yield* new ExternalLauncherError({
       message: `Editor command not found: ${launch.command}`,
     });
   }
-
-  const platform = yield* HostProcessPlatform;
   const isWin32 = platform === "win32";
   yield* launchAndUnref(
     {

You can send follow-ups to the cloud agent here.

Comment thread apps/server/src/process/externalLauncher.ts
@juliusmarminge juliusmarminge force-pushed the codex/effect-runtime-build-target branch from 5744aa5 to 8857505 Compare June 4, 2026 20:22
Comment thread apps/server/src/process/externalLauncher.ts Outdated
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Terminal drops non-whitelisted env
    • Restored HostProcessEnv Context.Reference in hostProcess.ts and used it as the base for createTerminalSpawnEnv so spawned terminals inherit the full host process.env (minus blocklisted keys), while keeping readTerminalHostEnv for shell resolution.

Create PR

Or push these changes by commenting:

@cursor push d2667f4b40
Preview (d2667f4b40)
diff --git a/apps/server/src/terminal/Layers/Manager.ts b/apps/server/src/terminal/Layers/Manager.ts
--- a/apps/server/src/terminal/Layers/Manager.ts
+++ b/apps/server/src/terminal/Layers/Manager.ts
@@ -10,7 +10,7 @@
   type TerminalSummary,
 } from "@t3tools/contracts";
 import { makeKeyedCoalescingWorker } from "@t3tools/shared/KeyedCoalescingWorker";
-import { HostProcessPlatform } from "@t3tools/shared/hostProcess";
+import { HostProcessEnv, HostProcessPlatform } from "@t3tools/shared/hostProcess";
 import { getTerminalLabel } from "@t3tools/shared/terminalLabels";
 import * as Config from "effect/Config";
 import * as DateTime from "effect/DateTime";
@@ -990,6 +990,7 @@
     const logsDir = options.logsDir;
     const historyLineLimit = options.historyLineLimit ?? DEFAULT_HISTORY_LINE_LIMIT;
     const platform = yield* HostProcessPlatform;
+    const hostEnv = yield* HostProcessEnv;
     const baseEnv = yield* readTerminalHostEnv;
     const shellResolver = options.shellResolver ?? (() => defaultShellResolver(platform, baseEnv));
     const processRunner = yield* ProcessRunner.ProcessRunner;
@@ -1668,7 +1669,7 @@
           Effect.andThen(
             Effect.gen(function* () {
               const shellCandidates = resolveShellCandidates(shellResolver, platform, baseEnv);
-              const terminalEnv = createTerminalSpawnEnv(baseEnv, session.runtimeEnv);
+              const terminalEnv = createTerminalSpawnEnv(hostEnv, session.runtimeEnv);
               const spawnResult = yield* trySpawn(shellCandidates, terminalEnv, session);
               ptyProcess = spawnResult.process;
               startedShell = spawnResult.shellLabel;

diff --git a/packages/shared/src/hostProcess.ts b/packages/shared/src/hostProcess.ts
--- a/packages/shared/src/hostProcess.ts
+++ b/packages/shared/src/hostProcess.ts
@@ -15,4 +15,11 @@
   },
 );
 
+export const HostProcessEnv = Context.Reference<NodeJS.ProcessEnv>(
+  "@t3tools/shared/hostProcess/HostProcessEnv",
+  {
+    defaultValue: () => process.env,
+  },
+);
+
 export const isHostWindows = Effect.map(HostProcessPlatform, (platform) => platform === "win32");

You can send follow-ups to the cloud agent here.

Comment thread apps/server/src/terminal/Layers/Manager.ts
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Low

ensureNodePtySpawnHelperExecutable().pipe(

The cached ensureNodePtySpawnHelperExecutableCached effect is missing the HostProcessPlatform service. After the refactoring, ensureNodePtySpawnHelperExecutable now requires HostProcessPlatform, but lines 114-117 only provide FileSystem.FileSystem and Path.Path. When spawn is called, the cached effect will fail at runtime with a service-not-found error.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file apps/server/src/terminal/Layers/NodePTY.ts around line 114:

The cached `ensureNodePtySpawnHelperExecutableCached` effect is missing the `HostProcessPlatform` service. After the refactoring, `ensureNodePtySpawnHelperExecutable` now requires `HostProcessPlatform`, but lines 114-117 only provide `FileSystem.FileSystem` and `Path.Path`. When `spawn` is called, the cached effect will fail at runtime with a service-not-found error.

Evidence trail:
apps/server/src/terminal/Layers/NodePTY.ts lines 41-59 (ensureNodePtySpawnHelperExecutable yields HostProcessPlatform at line 43), lines 18-39 (resolveNodePtySpawnHelperPath yields HostProcessPlatform line 22 and HostProcessArchitecture line 23), lines 104-123 (layer construction with cached effect only providing FileSystem and Path at lines 115-116). apps/server/src/terminal/Services/PTY.ts line 52 (spawn interface: Effect<PtyProcess, PtySpawnError> with R=never). https://github.com/Effect-TS/effect-smol packages/effect/src/Effect.ts line 6986 (Effect.cached signature: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>>, inner effect preserves R).

@juliusmarminge juliusmarminge force-pushed the codex/effect-runtime-build-target branch from 0d4ef3a to cf151de Compare June 4, 2026 22:14
@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Jun 4, 2026
Comment thread scripts/dev-runner.ts
hasExplicitDevUrl: input.devUrl !== undefined,
});

const hostPlatform = yield* HostProcessPlatform;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High scripts/dev-runner.ts:418

Changing baseEnv from process.env to {} combined with extendEnv: true breaks the delete operations in createDevRunnerEnv. The function deletes variables like T3CODE_MODE, T3CODE_NO_BROWSER, and T3CODE_HOST from output to prevent them from reaching the child, but since baseEnv is now an empty object and extendEnv: true copies process.env into the child separately, these deletes become no-ops. The child will incorrectly inherit those variables from process.env even when the code attempts to exclude them. For example, if T3CODE_MODE=desktop is set in the parent environment and the user runs dev:web mode, the child will receive T3CODE_MODE=desktop despite the delete statements.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file scripts/dev-runner.ts around line 418:

Changing `baseEnv` from `process.env` to `{}` combined with `extendEnv: true` breaks the `delete` operations in `createDevRunnerEnv`. The function deletes variables like `T3CODE_MODE`, `T3CODE_NO_BROWSER`, and `T3CODE_HOST` from `output` to prevent them from reaching the child, but since `baseEnv` is now an empty object and `extendEnv: true` copies `process.env` into the child separately, these deletes become no-ops. The child will incorrectly inherit those variables from `process.env` even when the code attempts to exclude them. For example, if `T3CODE_MODE=desktop` is set in the parent environment and the user runs `dev:web` mode, the child will receive `T3CODE_MODE=desktop` despite the delete statements.

Evidence trail:
...

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Empty env blocks PATH fallback
    • Added Effect.map after orElseSucceed in both readCommandLookupEnv definitions to detect empty env objects and fall back to process.env, ensuring the nullish coalescing in resolveCommandPathForPlatform correctly uses the host PATH.

Create PR

Or push these changes by commenting:

@cursor push c445860c82
Preview (c445860c82)
diff --git a/apps/server/src/process/externalLauncher.ts b/apps/server/src/process/externalLauncher.ts
--- a/apps/server/src/process/externalLauncher.ts
+++ b/apps/server/src/process/externalLauncher.ts
@@ -96,7 +96,10 @@
 }).pipe(Config.map(compactEnv));
 
 const readBrowserLaunchEnv = BrowserLaunchEnvConfig.pipe(Effect.orElseSucceed(() => ({})));
-const readCommandLookupEnv = CommandLookupEnvConfig.pipe(Effect.orElseSucceed(() => ({})));
+const readCommandLookupEnv = CommandLookupEnvConfig.pipe(
+  Effect.orElseSucceed(() => ({})),
+  Effect.map((env) => (Object.keys(env).length > 0 ? env : process.env)),
+);
 
 function parseTargetPathAndPosition(target: string): Option.Option<TargetPathAndPosition> {
   const match = TARGET_WITH_POSITION_PATTERN.exec(target);

diff --git a/apps/server/src/provider/providerMaintenance.ts b/apps/server/src/provider/providerMaintenance.ts
--- a/apps/server/src/provider/providerMaintenance.ts
+++ b/apps/server/src/provider/providerMaintenance.ts
@@ -35,7 +35,10 @@
   PATHEXT: Config.string("PATHEXT").pipe(Config.option),
 }).pipe(Config.map(compactEnv));
 
-const readCommandLookupEnv = CommandLookupEnvConfig.pipe(Effect.orElseSucceed(() => ({})));
+const readCommandLookupEnv = CommandLookupEnvConfig.pipe(
+  Effect.orElseSucceed(() => ({})),
+  Effect.map((env) => (Object.keys(env).length > 0 ? env : process.env)),
+);
 
 export interface ProviderMaintenanceCapabilities {
   readonly provider: ProviderDriverKind;

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit c395992. Configure here.

Comment thread apps/server/src/process/externalLauncher.ts
}

function isExecutableFile(
const isExecutableFile = Effect.fn("shell.isExecutableFile")(function* (
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium src/shell.ts:377

The execute permission check in isExecutableFile changed from accessSync(..., constants.X_OK) (verifies current user can execute) to (stat.mode & 0o111) !== 0 (any execute bit set). This returns true for files the current user cannot execute—for example, a file with mode 0o700 owned by root returns true when running as non-root, causing resolveCommandPathForPlatform to return paths that fail at actual execution time.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file packages/shared/src/shell.ts around line 377:

The execute permission check in `isExecutableFile` changed from `accessSync(..., constants.X_OK)` (verifies current user can execute) to `(stat.mode & 0o111) !== 0` (any execute bit set). This returns `true` for files the current user cannot execute—for example, a file with mode `0o700` owned by root returns `true` when running as non-root, causing `resolveCommandPathForPlatform` to return paths that fail at actual execution time.

Evidence trail:
- Diff confirmed the change: packages/shared/src/shell.ts, old code `accessSync(filePath, constants.X_OK)` replaced with `(stat.mode & 0o111) !== 0` at line 396 (commit REVIEWED_COMMIT vs MERGE_BASE)
- Effect FileSystem AccessFileOptions at https://github.com/Effect-TS/effect/blob/main/packages/platform/src/FileSystem.ts — only supports `ok`, `readable`, `writable` (no `executable`)
- `isExecutableFile` consumed by `resolveCommandPathForPlatform` at lines 399-445 (packages/shared/src/shell.ts)

@juliusmarminge juliusmarminge force-pushed the codex/effect-runtime-build-target branch from c395992 to 1f88949 Compare June 4, 2026 22:54
@juliusmarminge juliusmarminge force-pushed the codex/effect-runtime-build-target branch 2 times, most recently from 4cc4960 to 93faea0 Compare June 5, 2026 05:28
@juliusmarminge juliusmarminge force-pushed the codex/effect-runtime-build-target branch from 93faea0 to 646023a Compare June 5, 2026 05:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant