Unify launch env resolution on the server + introduce project/worktree/thread env vars#3004
Unify launch env resolution on the server + introduce project/worktree/thread env vars#3004tarik02 wants to merge 19 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Resolve authoritative T3CODE_* vars server-side for terminals and provider sessions, strip inherited runtime keys from spawns, and simplify clients to pass only cwd/thread context. Consolidate managed env helpers in shared and collapse terminal launch env wiring. Co-authored-by: Cursor <cursoragent@cursor.com>
ApprovabilityVerdict: Needs human review This PR introduces a new server-side LaunchEnv service that centralizes environment variable resolution, changing where and how runtime context (project, thread, worktree) is propagated to terminals and AI providers. This architectural change affects multiple subsystems and warrants human review. You can customize Macroscope's approvability policy. Learn more. |
Resolve launch env at RPC time instead of layer construction, and derive project context from threadId server-side so terminal open/restart no longer trust client projectId. Co-authored-by: Cursor <cursoragent@cursor.com>
Allow optional client projectId when the thread is not yet persisted, while still resolving project context from the server thread when it exists. Co-authored-by: Cursor <cursoragent@cursor.com>
Bind the terminal launch-env resolver at manager construction without unsafe casts, strip managed T3CODE_* keys in ACP spawns, merge per-session env for Grok, and pass projectId from setup scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
LaunchEnv no longer explicitly provides OrchestrationProjectionSnapshotQuery and RepositoryIdentityResolver since these dependencies are already available through the main application's OrchestrationLayerLive context. Changes: - LaunchEnvLayerLive now directly exports LaunchEnvLive (simplified from factory) - Dependencies auto-wire via Effect's context propagation - Removed makeLaunchEnvLayerLive factory which was building redundant layers - Updated ProviderCommandReactor.test to use simplified LaunchEnvLayerLive - Cleaner layer composition with no duplicate OrchestrationProjectionSnapshotQuery provision This reduces PR scope from 154 changed files to 3, maintaining the same functionality while improving architectural clarity by eliminating unnecessary layer wrapping. Co-authored-by: Cursor <cursoragent@cursor.com>
… line - Delete LaunchEnvLive.ts from Layers/ - it was just re-exporting LaunchEnvLive from Services/LaunchEnv.ts with no additional composition or transformation - Update imports to get LaunchEnvLive directly from Services/LaunchEnv.ts - Fix duplicate line in OrchestrationEngineHarness.integration.ts (378-379) - Cleaner architecture: no unnecessary layer wrapper files This simplifies the LaunchEnv module structure - the Services file already exports the Layer, so an intermediate Layers file added no value and just increased indirection. Co-authored-by: Cursor <cursoragent@cursor.com>
Follow app architecture pattern: Service files define only interface and class, implementation and Layer creation live in Layers/ files. Changes: - Services/LaunchEnv.ts: Contract only (Shape, types, service class with JSDoc) - Layers/LaunchEnvLive.ts: Implementation (makeResolveLaunchEnv, makeResolveForThread, Layer) - Update imports in server.ts, ProviderCommandReactor.test.ts, OrchestrationEngineHarness This matches the architectural pattern used throughout the codebase (e.g., OrchestrationEngine, ProviderService) where Shape and class live in Services/ and concrete implementations live in Layers/. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
What Changed
Server now owns
T3CODE_*launch env for terminal and provider child processes.LaunchEnvto resolve home, project, thread, and worktree context from server state.projectId.T3CODE_*keys stripped from inherited and client-supplied env.T3CODE_*; they send cwd/worktree context plusprojectIdwhen needed.Closes #3003
Why
Make t3code provide
T3CODE_PROJECT_ROOT/T3CODE_WORKTREE_PATH(and related launch context) from one authoritative server path. Unified environment resolution between terminal and provider child processes, with managed-key filtering so parent/custom/client env cannot override or leak extraT3CODE_*values.UI Changes
No UI changes.
Checklist
Note
Unify launch environment resolution on the server and introduce project/worktree/thread env vars
LaunchEnvDI service (LaunchEnv.ts) that resolvesT3CODE_HOME,T3CODE_PROJECT_ROOT,T3CODE_PROJECT_ID,T3CODE_THREAD_ID, andT3CODE_WORKTREE_PATHfrom server config and projection queries, replacing ad-hoc client-side env construction.TerminalManager.open,.restart, and.attachnow pre-resolve worktreePath and env viaLaunchEnvbefore spawning, mapping lookup failures toTerminalCwdErrororTerminalSessionLookupError.ProviderCommandReactorpasses aLaunchEnv-derived env map toproviderService.startSession, so provider sessions (Claude, Codex, Cursor, Grok, OpenCode) receive authoritative context env.mergeProviderSessionEnvironment, which strips managedT3CODE_*keys from the base process env before applying overrides.ChatView,ThreadTerminalDrawer,ProjectSetupScriptRunner, mobileThreadRouteScreen) no longer builds or sendsruntimeEnv; only aprojectIdis forwarded and managed keys are stripped from any custom env before transmission.isManagedRuntimeEnvKeyandstripManagedRuntimeEnvKeysare added to@t3tools/shared/launchEnvand used throughout to enforce the boundary between managed and user-defined env keys.TerminalManagernow requires aLaunchEnvprovider in its options; existing callers that do not provide one will fail to compile.Macroscope summarized f189f37.
Note
Medium Risk
Touches terminal spawn, provider child processes, and env merging across adapters; wrong resolution could break scripts/agents, but behavior is covered by new LaunchEnv and integration tests.
Overview
Server-authoritative
T3CODE_*launch env replaces client-built runtime env for terminals, setup scripts, and provider sessions.A new
LaunchEnvservice resolvesT3CODE_HOME, project root/id, thread id, and worktree path fromServerConfigand projection snapshots.resolveForThreadloads thread/project from the server (ignoring clientprojectIdwhen the thread exists) and only accepts clientprojectIdfor draft threads not yet in the projection.TerminalManagerresolves env on open/restart/attach before PTY spawn; clients sendprojectId, cwd, and worktree path instead of full env.ProviderCommandReactorpassesLaunchEnv-derived env intostartSession; adapters merge it viamergeProviderSessionEnvironment.Managed-key policy:
@t3tools/shared/launchEnvaddsstripManagedRuntimeEnvKeys/isManagedRuntimeEnvKey; server merges strip clientT3CODE_*overrides and provider spawns strip inherited managed keys.projectScriptRuntimeEnvis removed from shared; web/mobile only forward non-managed custom env when needed.Contracts add optional
projectIdon terminal open/restart/attach and optionalenvon provider session start. Effect layer wiring pullsLaunchEnvLiveinto terminal, reactors, and integration harnesses.Reviewed by Cursor Bugbot for commit f189f37. Bugbot is set up for automated code reviews on this repo. Configure here.