* fix(platform): search mise shims dir so mise-installed CLIs are detected
- Add ~/.local/share/mise/shims (and MISE_DATA_DIR override + legacy ~/.mise/shims) to wellKnownUserToolchainBins.
- This makes Pi, Kimi, and other mise-managed coding agents visible to the daemon even when launched from GUI contexts with stripped PATH.
- Added tests for default and MISE_DATA_DIR cases.
- Also pinned pnpm@10.33.2 in root mise.toml for better mise ergonomics.
Before/after: more local CLIs now appear in the runtime picker (Kimi, Pi, Antigravity, Kilo, etc.).
Refs: discussion in session around improving detection for common mise users.
* fix(platform): address Copilot review on mise shims logic
- Generalize the shims comment (no hard-coded CLI examples).
- Make per-version Node toolchain scanning respect MISE_DATA_DIR
(use the same mise root for installs as for shims).
- Avoid duplicate shims entries when MISE_DATA_DIR makes legacy path
identical to the primary one.
Addresses the three inline comments from copilot-pull-request-reviewer
on PR #3319.
* test(platform): extend MISE_DATA_DIR test to cover installs scanning
Addresses non-blocking review feedback from @nettee on PR #3319.
The previous test only asserted shims behavior under a custom
MISE_DATA_DIR. This extends it to also create fixture trees under
customMise/installs/node/... and customMise/installs/npm-openai-codex/...
and assert that the install paths are discovered while default-root
paths are excluded.
This makes the test robust against regressions in the installs
scanning logic (existingMiseNpmPackageBinDirs + node version dirs).
* fix(platform): only fall back to ~/.mise/shims when no MISE_DATA_DIR is set
Addresses the remaining non-blocking review comment from @nettee on PR #3319.
When an explicit MISE_DATA_DIR is provided, we no longer inject the
legacy ~/.mise/shims path. This prevents stale shims from a previous
mise layout from being re-introduced into detection.
Also added a regression assertion in the MISE_DATA_DIR test.
* fix(daemon): make claude-stream dedup robust when final assistant wrapper lacks msgId
Prevents duplicated text and thinking output (especially visible during
design system generation with AMR/Vela).
Root cause: the textStreamed guard fell back to whenever the
final message arrived without a string uid=501(ramarivera) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),399(com.apple.access_ssh),33(_appstore),98(_lpadmin),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),400(com.apple.access_remote_ae) (common in some
AMR flows and design system tasks), causing the full content to be
re-emitted even if it had already been delivered via streaming deltas.
Fix: track whether any text or thinking was streamed via deltas for the
current message and use that as a reliable fallback for the final wrapper
instead of only trusting presence.
* revert: remove dedup from claude-stream (PR #3319 should stay clean)
* fix(platform): support live system proxy changes
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Honor lowercase proxy env vars within a single source before merging proxy-aware envs.\n\nGenerated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Refresh provider request proxy env on each dispatcher creation and cover it with a focused regression test.
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): enable node env proxy for user proxy vars
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* fix(platform): support live system proxy changes
Generated-By: looper 0.9.1 (runner=fixer, agent=opencode)
* feat: add support for VP_HOME environment variable in agent resolution
- Introduced a new .node-version file to specify Node.js version.
- Enhanced agent resolution tests to include scenarios for VP_HOME, ensuring proper handling of Vite+ global installs.
- Updated platform code to resolve user-scoped home directories, allowing for custom Vite+ installations to be prioritized.
- Added tests to verify that the resolution logic correctly honors the VP_HOME environment variable and integrates with existing user toolchain paths.
* feat: enhance VP_HOME support in sidecars and platform
- Updated the PACKAGED_CHILD_ENV_ALLOWLIST to include VP_HOME for environment variable forwarding.
- Exported functions resolvePackagedChildBaseEnv and resolvePackagedPathEnv for better accessibility in tests.
- Added tests to validate VP_HOME handling in packaged child environments and ensure correct path resolution.
- Adjusted wellKnownUserToolchainBins to prioritize VP_HOME/bin in the toolchain path resolution.
* fix(daemon, packaged): unbreak GUI-launched agent detection on minimal PATHs (#442)
GUI-launched daemons (Finder/Dock on macOS, .desktop on Linux) inherit a
stripped PATH from launchd / the desktop session and don't read the
user's interactive shell rc files, so any CLI installed via `npm i -g`
under a sudo-free prefix like ~/.npm-global was silently undetected.
Two layers maintained their own copies of the user-toolchain bin list
(`apps/daemon/src/agents.ts:userToolchainDirs` for the resolver,
`apps/packaged/src/sidecars.ts:resolvePackagedPathEnv` for the packaged
sidecar PATH builder) and had already drifted on `~/.asdf/shims` and
`~/Library/pnpm`. Adding ~/.npm-global to one side would have
preserved the same anti-pattern.
Extracts `wellKnownUserToolchainBins` into @open-design/platform as the
single source of truth, has both layers consume it, and extends the
list to cover ~/.npm-global/bin, ~/.npm-packages/bin, plus
$NPM_CONFIG_PREFIX/bin / $npm_config_prefix/bin for users with a
non-standard prefix. New vitest coverage in the platform package and
a regression test in apps/daemon/tests/agents.test.ts modelled on the
existing mise case.
Verified end-to-end: under PATH=/usr/bin:/bin:/usr/sbin:/sbin (the
launchd default a `.app` actually inherits), `resolveAgentExecutable`
now returns ~/.npm-global/bin/gemini instead of null.
* fix(daemon): isolate OD_AGENT_HOME resolution from $NPM_CONFIG_PREFIX leakage
Address review feedback on PR #614:
- mrcfps spotted that the daemon wrapper called wellKnownUserToolchainBins
without passing `env`, so the helper read its default process.env. A
developer or CI runner with NPM_CONFIG_PREFIX / npm_config_prefix
exported would inject that real <prefix>/bin into resolveOnPath() even
while the OD_AGENT_HOME hook pointed home at a temp fixture, making
agent-detection tests environment-dependent. Reproduced locally: with
OD_AGENT_HOME=<tmp> + NPM_CONFIG_PREFIX=/Users/me/.npm-global,
resolveAgentExecutable({ bin: 'codex' }) returned the real machine's
binary instead of null. Wrapper now passes `env: {}` whenever
homeOverride is set, alongside the existing includeSystemBins gate.
- lefarcen suggested also handling whitespace-only NPM_CONFIG_PREFIX
values (e.g. NPM_CONFIG_PREFIX=" ") so the helper does not emit a
bogus "<whitespace>/bin" entry. Added a .trim() check before
appending.
- lefarcen also suggested a comment pointer from the daemon wrapper to
the platform helper so readers don't have to grep. Added the
reference inline.
Coverage:
- packages/platform/tests/index.test.ts: new whitespace-prefix case.
- apps/daemon/tests/agents.test.ts: new env-isolation regression
asserting that OD_AGENT_HOME + NPM_CONFIG_PREFIX cannot leak the
real prefix bin into the sandbox.
* test(daemon): preserve $NPM_CONFIG_PREFIX across the env-isolation case (#614)
Address mrcfps's second-round review on PR #614: the env-isolation
regression sets `process.env.NPM_CONFIG_PREFIX = realPrefix` in its
body and then unconditionally `delete`s it in `finally`. On a developer
machine or CI runner that already exported `NPM_CONFIG_PREFIX`, that
mutates the worker-wide env for every later test, making downstream
env-sensitive assertions order-dependent.
Move the save/restore into the file's existing afterEach hook (mirroring
the OD_AGENT_HOME / OD_DAEMON_URL / OD_TOOL_TOKEN pattern) and drop the
in-test `delete`. Same coverage, no worker-state mutation.
* fix(platform): prioritise $NPM_CONFIG_PREFIX over the conventional npm guesses (#614)
Address mrcfps's third-round review on PR #614: when the user has
explicitly configured a prefix via $NPM_CONFIG_PREFIX (or
$npm_config_prefix), that's where `npm i -g` puts the *current*
binaries. The conventional guesses ~/.npm-global / ~/.npm-packages
often hold *stale* installs from an older prefix the user has since
rewritten — searching the env-driven prefix first matches npm's own
resolution order (env > .npmrc > default) and gives "explicit beats
convention" semantics.
Move the env-driven push above the conventional `dirs.push(.npm-global,
.npm-packages)`. Add a vitest case in the platform package that asserts
$NPM_CONFIG_PREFIX/bin's index in the result is strictly less than
~/.npm-global/bin's and ~/.npm-packages/bin's.
`resolveOnPath()` and the packaged PATH builder both preserve insertion
order, so first hit wins and the new ordering propagates to both
layers.
* fix(platform): lift $NPM_CONFIG_PREFIX above every conventional bin (#614)
Address mrcfps's fourth-round review on PR #614: the previous fix only
moved $NPM_CONFIG_PREFIX/bin ahead of ~/.npm-global / ~/.npm-packages,
but ~/.local/bin still appeared earlier in the array. Under a minimal
GUI-launch PATH a stale agent in ~/.local/bin (also a shared dumping
ground for pip --user / cargo install / hand-built binaries) could
outrank the user's *current* explicit npm prefix.
Move the env-driven push to the head of `dirs` so the explicit prefix
wins over every conventional location below — ~/.local/bin included.
Matches npm's own resolution order (env > .npmrc > default) across the
whole list, not just the npm-prefix block.
Tightened the existing order test to assert `explicitIdx === 0` and
that ~/.local/bin's index is strictly greater than the explicit
prefix's index, so a future drift would fail loudly.
* chore: enforce test directory conventions
Move package, app, and tool tests out of src and add guard enforcement so source directories stay source-only.
* ci: use guard and package-scoped tests
Run the new repository guard in CI and keep test execution aligned with package-scoped commands after removing root aliases.
* ci: align stable release guard check
Use the new repository guard in stable release verification after replacing the residual-JS-only script.
* chore: tighten test layout enforcement
Enforce sibling tests directories, typecheck moved test suites with dedicated configs, and refresh remaining guidance that pointed at src-based tests.
* chore: clarify no-emit test tsconfigs
Explicitly disable declaration-only emit in test tsconfigs so review tooling sees they are no-emit typecheck configs.