Repository navigation
Conversation
Add HostEnvironment to the kernel and captureHostEnvironment to host-kit. The CLI, the daemon executable and the client factory capture it once; startDaemonRuntime requires it and the request scope exposes it. Host-kit, kernel and daemon-contracts no longer read the process environment or working directory. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…irectory Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Platform packages may not read process; they take the environment and working directory of the enclosing command host. Unit tests enter the live process environment as their host. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Size Report
Startup median (7 runs, lower is better):
|
There was a problem hiding this comment.
All reported issues were addressed across 178 files
You’re at about 91% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
All reported issues were addressed across 39 files (changes from recent commits).
You’re at about 93% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
…CLI env plumbing Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
The code needs no changes before merge, but the kernel-errors mutation checks are red and must pass first. I reviewed commit 5effcd7. All five kernel-errors shards fail the Stryker dry run on one test, host-kit/src/code-signature.test.ts:149 ("the daemon source graph stamps the walker that produced it"). That test is unchanged and passes in the unit lanes. The shards passed in run 38965344815. The related-test set for these shards grew from 1372 to 1607 files, which pulled this test in. The new global setup file (https://github.com/callstack/agent-device/blob/5effcd7/src/__tests__/host-environment-setup.ts#L8) imports host-kit/command and so exec.ts and kernel/errors, so I think it caused that growth. I did not reproduce the failure in the sandbox. The walker probably resolves workspace symlinks outside the sandbox root, but I have not proven that. The "Affected decision-kernel mutants" check fails after the dry run ("13 report(s), expected 18"), and Smoke Tests was still running when I looked. No conflicts. The next step is to remove the global aroundEach setup, or to make that test work in the sandbox. Re-run the kernel-errors shards after that. Not blocking, and you can take or leave these. The setup file binds every unit test to the live process.env and process.cwd(), so no test can see host_environment_unscoped (exec.ts:140). Please bind createTestHostEnvironment only in suites that enter through the daemon or CLI, and add one test that calls a commandHostEnvironment() consumer outside a scope and expects that reason. Also, createAgentDeviceClient(config, { host }) at https://github.com/callstack/agent-device/blob/5effcd7/src/agent-device-client.ts#L89 uses host only in stateDir(), while the daemon client still reads process.env and process.cwd() (daemon-client-lifecycle.ts:97-140, 818). Either every resolution the client makes should read the same host, or deps.host can wait for #3751. Finally, RequestExecutionScope.host (https://github.com/callstack/agent-device/blob/5effcd7/packages/daemon/src/server/request-execution-scope.ts#L263) has no production reader except its own test, because daemon handlers use the ambient commandHostEnvironment() (19 call sites). Would one channel per layer be simpler? host-kit would keep the ALS scope only for spawn env and the DEVELOPER_DIR overlay. Daemon handlers would read host from RequestExecutionScope or the runtime deps they already get. Platform code would take host from its existing host or tool-provider object, as AndroidAdbHost.environment does. That would remove the throwing ambient accessor and the test-wide shim, and a missing host would become a type error. #3750, #3751 and #3752 will copy whatever shape this PR sets. Could we settle in #3747 or an ADR whether HostEnvironment travels explicitly or ambiently before they land? The open inline threads still apply. The two P2 threads on connection.ts (#3763 (comment) on the home path, #3763 (comment) on provider profile) and the P2 thread on bundletool lookup (#3763 (comment)) are still open. One lower-priority thread also applies: #3763 (comment). |
There was a problem hiding this comment.
All reported issues were addressed across 9 files (changes from recent commits).
You’re at about 94% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
The global setup made every test related to every mutated source. Suites that reach host-reading code through neither a daemon request nor the CLI bind a host with bindTestCommandHost(). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…kages Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… scenarios Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Pushed |
|
There was a problem hiding this comment.
All reported issues were addressed across 97 files (changes from recent commits).
You’re at about 94% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
Thanks for the PR. The host capture is a good direction, but one defect in the client needs a fix before merge. CI is green at d522d25 (23 checks, none failing), and there are no conflicts. createAgentDeviceClient now accepts Not blocking, and you can take or leave these: Could the AsyncLocalStorage scope keep only what it already owns, which is spawn env ( I did not trace every public SDK export (artifacts, android-adb, limrun, ai-sdk) to prove none reaches This is reviewed at d522d25. Before merge, the client needs to resolve every state dir read from one host, and the scope question for #3750 and #3751 needs an answer. |
createAgentDeviceClient's default transport, the daemon launch and the CLI run's transport read the host the client was given, not the process. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
All reported issues were addressed across 11 files (changes from recent commits).
You’re at about 95% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
Pushed Also taken from the non-blocking list: On the ambient versus explicit question: the ambient |
…rectory Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Thanks for the update. Since the review at d522d25 (#3763 (comment)), the client now resolves the policy against
Not blocking, and fine to take or leave: Could Of the open inline threads, the cubic-dev-ai thread on the policy path (#3763 (comment)) still applies until the spawn cwd is fixed. These no longer apply and you can resolve them: the I did not run any test or daemon; the daemon cwd finding is traced from the spawn options and the entry capture, and I did not check whether other daemon reads also resolve relative env values against the inherited cwd. Remote artifact upload still reads process env and cwd, which I accepted as deferred to #3751 without tracing it. At f4616b9 Smoke Tests are queued, and Repo Guards & Compatibility and Coverage are still running with no failure yet. This change touches the daemon-client route that smoke runs use, so a failure there would likely be related. There are no conflicts. Before merge, please launch the daemon with |
…ment * origin/main: test: move the daemon-composition tests off the daemon's testing exports (#3742) fix(android): ignore emulator log lines in -list-avds output (#3743) # Conflicts: # packages/daemon/src/server/__tests__/request-router-fill-text-stdin.test.ts # packages/daemon/src/server/__tests__/request-router-macos-app-lease.test.ts # packages/daemon/src/server/__tests__/request-router-provider-credentials.test.ts # packages/daemon/src/server/__tests__/request-router-record-runtime-lock.test.ts # packages/daemon/src/server/__tests__/request-router-recording-health.test.ts # packages/daemon/src/server/__tests__/request-router-replay-scope.test.ts # packages/daemon/src/server/__tests__/request-router-screenshot.test.ts # packages/daemon/src/sessions/request-handler-chain-routing.test.ts # src/__tests__/daemon-composition/app-event-delivery.test.ts # src/__tests__/daemon-composition/gesture-admission-parity.test.ts # src/__tests__/daemon-composition/http-server-limrun-uploaded-apps.test.ts # src/__tests__/daemon-composition/request-router-android-perf.test.ts # src/__tests__/daemon-composition/request-router-android-snapshot-helper.test.ts # src/__tests__/daemon-composition/request-router-open-claim-recovery.test.ts # src/__tests__/daemon-composition/request-router-replay-test-ime.test.ts
…g test Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…rectory Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… cleared it Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Pushed
|
…nd remaining packages (#3775) * refactor(host): thread the client host through remote artifact preparation and materialization Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(host): pass the composition's env to the platform runtime, diagnostics, toolchain and deployment hosts Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(host): refuse a relative provider app path that names no working directory Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(host): require the host's env and cwd where the CLI resolves options, binding and auth Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test(host): keep the upload client suite under its size ratchet Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(host): pass the run's host to CLI command handlers Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test(host): bind host-taking commands once in a shared helper Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * docs(changelog): resolveHubAppReference needs cwd for a relative app path Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test(host): give the new handler suites a host Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
|
The code is ready for review at 870cf66. The earlier review (#3763 (comment)) found no problems, and the new #3775 changes in this round do not change that. The harness env ordering is now fixed, so the cubic P2 thread on harness.ts:119 no longer applies, so you can resolve it. Not blocking, and you can take or leave these: the harness builds its gateway with The only open item is CI. Smoke Tests are queued or running with no failure yet. #3775 changes the root composition env and the CLI handler host, which the smoke route uses, so a smoke failure here would need a look. Smoke Tests must pass at 870cf66 before merge. I did not run tests. I reviewed #3775's 98 files for new process.env or cwd reads, layer crossings and the resolveHubAppReference contract, but not its test call-site churn line by line. The changes merged from main (#3776, #3714, #3762) are upstream, and I checked them only where they meet host plumbing. |
… host claims directory on a failed release Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
All reported issues were addressed across 3 files (changes from recent commits).
You’re at about 97% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
…rding scenario Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
The code in 9f3e58f is clean. The new commits since 870cf66 only add a daemon unit test, the provider-scenario harness changes, and a comment in the iOS record-trace scenario, and they fix the earlier gap. I read abandonDeviceClaim and writeOwnedDeviceClaim at this head and the new test matches what they do. I did not run the new device-claim-admission test or its mutation. Smoke Tests is still running and has no failure yet. The new commits do not touch the smoke route, but the PR as a whole changes entry-point host plumbing that smoke exercises, so any failure there needs its own check. The PR has no known conflicts, and Smoke Tests must finish green before merge. One open inline thread from another reviewer does not apply: the comment in ios-record-trace.test.ts lines 115-116 is accurate. #3775 merged into this branch, but the PATH and Swift-cache readers on this route still read the process environment at head (swift-cache.ts:140 and buildSwiftToolEnv() defaulting to process.env). #3777 migrates them, including src/platform-runtime-screen-recording-finalizer-host.ts. I only checked #3777 through its file list and PR body, not its contents. Please resolve it: #3763 (comment) |
…ment * origin/main: build(package): stop shipping Swift test sources (#3785) fix(scroll): take edge hints from a same-rect scrollable ancestor (#3784) docs(agents): write agent docs in ASD-STE100 and remove misleading docs (#3723) fix(daemon): retain cleanup locks and preserve healed snapshots (#3760) # Conflicts: # packages/daemon/src/sessions/__tests__/replay-repair/session-replay-repair-record-exclusion.test.ts
|
Reviewed cb17bb3. The code looks good, and I found no new problems since the earlier review at 9f3e58f. The range-diff shows the earlier commits unchanged, plus one test-comment commit (779dcab) and the merge with The one merge conflict, in the replay-repair test, is resolved correctly: every All checks pass, and there are no conflicts. Nothing else blocks human review. |
…orm and capture packages (#3777) * refactor(capture-kit): read swift cache, app-log and PNG worker settings from the command host The PNG worker starts with an empty environment and reports unavailability through diagnostics instead of a process warning. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(provision-kit): read proxy settings from the command host Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(react-native): read dev-server settings from the command host The detached companion process starts with an explicit env and cwd, and its process entry captures its host from its own spawn environment. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix(host): run the dev-server helpers inside the client's and the SDK's host The helpers moved from process reads to the command host, so the released agent-device/metro functions and the client bind one at their boundary. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(platform-apple): give detached runner and bridge children an explicit env and cwd Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(platform-apple): read runner settings from the command host The runner reaches the host through its port. The container bundle ids were fixed at import time from the process environment; they are now resolved from the host a caller passes in. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix(host): run the daemon clean script's runner lease cleanup inside its own host Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(host): hand leaf modules their environment instead of importing the command host The eager-closure budgets forbid the host-kit command import in the install source download, the app-log file policy and the Maestro HTTP helper, so their callers pass the environment they already hold. Client tests that change PATH give the client a host instead. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test(host): bind the command host in the install-artifact suites Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix(host): answer review of the platform host environment change Redaction patterns come from the command host, the maestro child reads its own environment without a working-directory lookup, local ~ install sources expand against the host environment, and the runner launch resolves its host inside the try that closes its log descriptor. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(react-native): take the host explicitly instead of reading the command host Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(platforms): pass the host explicitly where a platform package reads configuration Android install artifacts read the environment from the Android adb host port, Apple install artifacts take it as an option from the root deployment executor, and the Apple runner names its host port member hostEnvironment. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(daemon): hand the app-log marker the request host's environment Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix(capture-kit): report an unavailable PNG worker in the first diagnostics scope that sees it A startup pre-warm runs outside any scope, where the event is dropped; it no longer latches the one-time report. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test(host): share the test command host binding through test-kit and test the runner's bound host behaviorally test-kit no longer depends on capture-kit: its app-log live-handle alias is gone (callers use the capture-kit constructor) and its keyboard fixture builds its own snapshot state. capture-kit's tests take the helper from test-kit. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(capture-kit): expose the app-log live handle adapter through its own entry Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(test-kit): build the test app-log handle without importing capture-kit Replaces the capture-kit subpath entry, which grew the declared export surface. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(capture-kit): take the host explicitly for Swift cache and recording tooling capture-kit no longer reads the command host, so its suites need no bound host and its local test-host copy is gone; the root recording seams supply the host. test-kit keeps depending on capture-kit again, and capture-kit does not depend on test-kit. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix(capture-kit): report a worker that dies under a request in that request Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * refactor(platform-android): take the install environment from the caller The Android adb host port's environment is bound at module load, so a host whose environment differs from the process's got the process's proxy settings on a network install. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test(platform-apple): pin the detached snapshot bridge's starting directory Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test(capture-kit): fail when the pre-warm starts no worker to kill Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test(host): keep the provider scenario host's Swift cache directory for scenarios that set it on the process Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix(capture-kit): key the cached Swift helper paths on the host they were built for The video validator is cached per Swift cache root and the overlay scripts per working directory, so a second host does not reuse the first host's paths. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test(host): give the Android recording scenarios their host env through the harness Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test(host): scenarios name their own host env; the harness no longer forwards the process's Swift cache Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test(host): drop the iOS recording scenario's process-env block now that capture-kit takes the host Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
This PR is ready. The code at fab82cc looks right to me, and the earlier review at cb17bb3 still holds. All 23 checks pass at fab82cc, and there are no conflicts. I read the diff and ran no tests myself. I could not see the check names, so I can't confirm which device lanes ran. The device-facing spawn changes (runner xcodebuild, snapshot bridge, swiftc, companion) match the old behavior on the daemon route, because host env equals the process env captured at startup and requestEnv still layers on top. Not blocking, and you can take or leave these: |
…ped Metro session read; changelog the PNG worker change Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Applied at
|
|
The delta from fab82cc to 4f6dd3e looks right. It touches only CHANGELOG.md and one catch in metro-session-hints.ts, and One observability gap, not blocking on its own: in png-worker-client.ts, On simplicity: the new concept is a one-time, process-wide report that waits for a diagnostics scope, and capture-kit detects a scope by counting the keys of |
…e that takes the fallback; the daemon pre-warms it inside a daemon diagnostics scope Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
All reported issues were addressed across 5 files (changes from recent commits).
You’re at about 99% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
Applied at |
|
The earlier review at 4f6dd3e is mostly resolved. At 595fa48 the code is not ready yet: one issue remains. All 23 checks pass on 595fa48, and I have no known conflicts to report. The remaining issue is the open thread on worker failures after the scope closes (#3763 (comment)). The rule: every transition of the PNG worker to unavailable (spawn failure, async load error, or mid-life exit) must reach daemon.log exactly once, with or without an active scope. Today the scope at daemon-runtime.ts closes once obtainWorker() returns. Later events fall into request scopes, and successful requests drop them without --debug. One owner can enforce the rule: markWorkerUnavailable could call a daemon-supplied onUnavailable sink, registered through prewarmPngWorker and wrapped in withDaemonDiagnosticsScope. Please add a daemon test whose worker emits 'error' after construction. The CHANGELOG line about png_worker_unavailable then holds as written. I did not run the new daemon test or the capture-kit test. I did not reproduce an async worker load failure. I read the code path in handleWorkerFailure and the unforced request flush instead. Other open threads still apply. The Cubic thread above is the P2 that holds (daemon.log gap). The P2 on repeated events per failed job (#3763 (comment)) holds, but it is noise only, and the once-per-transition sink fixes it. The P3 on send-failure text used as the unavailable reason (#3763 (comment)) holds and does not block. Not blocking: the CHANGELOG.md:5 entry says a worker that cannot start leaves a png_worker_unavailable event in daemon.log, which is only true once the fix above lands. You can take it or leave it. |
…le once, through a daemon-registered sink with a typed reason Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
All reported issues were addressed across 5 files (changes from recent commits).
You’re at about 99% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
Applied at
|
|
I found no code problems in d1f3001. The earlier findings from 595fa48 (#3763 (comment)) are fixed, and nothing from that review remains. Smoke Tests is still running on d1f3001, so it has not failed. This delta changes daemon startup ( The cubic-dev-ai P2 thread on the sink surviving |
Summary
Part of #3747. Closes #3749.
This branch is the whole HostEnvironment adoption: #3775 (root
src/and the remaining packages) and #3777 (platform and capture packages) are merged into it, on top of this PR's own foundation.HostEnvironment = { env, cwd }now has one owner. Entry points capture it once, and the daemon runtime, request scope and command spawning receive it instead of readingprocess. About 260 files change, most of them test call sites.HostEnvironmentis in@agent-device/kernel/source-value.captureHostEnvironment(process)is in@agent-device/host-kit/process. It copies the environment.src/bin.ts,src/cli.ts(runCli(argv, deps, host)),src/daemon.tsandcreateAgentDeviceClient(config, { host })capture once. A client built without a host capturesprocessand then reads only that host: its default transport, daemon launch, state dir andstateDir()all resolve from it.startDaemonRuntimerequireshost.DaemonRuntimeDepsInput.hostreplacesenv.RequestRouterDeps.hostandRequestExecutionScope.hostcarry it. Request handlers, claim writers, lease admission and the reapers inpackages/daemonread configuration from that host explicitly (throughRequestHandlerChainParams.hostor the env their constructor receives), not from the ambient scope.withCommandHost({ host, requestEnv }, fn)replaceswithRequestCommandEnv. Spawned commands start fromhost.env.commandHostEnvironment()still gives platform and root code that host and throws outside one; it is meant for command execution only, and their owners (refactor(platforms): read host settings from HostEnvironment in platform and capture packages #3750, refactor: read host settings from HostEnvironment in root src and remaining packages #3751) convert the remaining readers to explicit hosts.whichCmd,resolveUserPath,expandSessionPath, the device-claim functions,loadDaemonPolicy,launchDaemonProcessand kernel allowlist and simulator-set resolvers take env or cwd as parameters.process.envorprocess.cwd().Behavior changes: a relative state dir without a
cwdis refused (relative_state_dir_without_cwd; callers now pass one), and a relativeAGENT_DEVICE_CLAIMS_DIRis refused (relative_claims_dir; the store is shared by every daemon on the host, so it used to depend on where one of them started). Suites that reach host-reading code outside a daemon request or the CLI bind a host withbindTestCommandHost()from test-kit; there is no global test setup.The root
src/readers (#3775) and the platform and capture packages (#3777) now read host settings fromHostEnvironment, merged into this branch.commandHostEnvironment()remains the ambient host for command execution and for a number of platform-side readers that still call it; narrowing it further is a follow-up.Validation
pnpm check:affected --run --head fab82cc123(exactCommit) passed, with currentmain, #3775 and #3777 merged.Behavior note (PNG worker):
packages/capture-kit/src/png-worker-client.tsno longer callsprocess.emitWarningwhen the worker is unavailable and starts with env{}. The daemon registers a sink when it pre-warms the worker; every transition to unavailable (spawn failure, missing entry, load error, exit) reachesdaemon.logexactly once aspng_worker_unavailablewith a typedreasonand itsdetail, with or without an active scope. Requests then use the in-process fallback without repeating the event (also in CHANGELOG).🤖 Generated with Claude Code