runPluginBuild called node:child_process spawn with shell: false, so bare
commands like `npm` failed on Windows with `spawn npm ENOENT` because npm
is a .cmd script. Route through the shared spawnProcess helper, which
already selects shell: true for bare commands and .cmd/.bat scripts on
Windows and quotes arguments for cmd.exe.
Side effects inherited from spawnProcess, on every platform:
- Child env is sanitized via createExternalCommandProcessEnv, stripping
ELECTRON_RUN_AS_NODE, ESBUILD_BINARY_PATH and PASEO_* control keys that
previously leaked from the daemon into plugin builds.
- windowsHide: true, so builds no longer flash a console window on Windows.
Adds behavioral tests for preparation.ts. Windows cases use it.runIf and
run only on Windows hosts; CI is ubuntu-only.
Co-authored-by: ABorakati <ABorakati@users.noreply.github.com>
* test(e2e): boot the Playwright harness on Windows
The harness could not start on Windows. Metro was launched with
spawn("npx", ...) and the isolated daemon resolved its runner with
execSync("which tsx") — npx is a .cmd shim that Node's bare spawn
cannot launch, and `which` does not exist there.
Route both through process.execPath instead of the node_modules/.bin
shims. Node refuses to spawn .cmd or .bat without shell: true, and
shell: true is the wrong escape hatch: it concatenates argv unescaped
(DEP0190), splits paths containing spaces, and sends kill signals to
cmd.exe rather than the real child. Spawning Node directly has none of
those properties and is identical on POSIX, so no platform branch is
needed. The same reasoning fixes the published-server npm install,
which passed "npm.cmd" to execFileSync and had been failing with
EINVAL on Windows since Node's CVE-2024-27980 mitigation landed.
Teardown now kills the process tree. A Windows signal reaches only the
direct child, so Metro's and the supervisor's forked workers kept the
listening port and the next run failed to bind.
The daemon startup deadline goes from 20s to 90s. A cold tsx start was
measured at 25s on Windows and exceeded 60s under load; the loop still
fails immediately on a crashed child, so the ceiling only costs time
that a genuinely slow start needs.
The fake editor and gh binaries the harness puts on PATH gain .cmd
wrappers, because Windows resolves PATH entries by PATHEXT and cannot
execute an extension-less shebang file. The wrappers point at the same
payload file so the recorded command name stays "cursor", "code", or
"gh" on every platform.
The asdf-backed local Elixir relay stays POSIX-only and now says so
before spawning.
* test(ci): follow shared e2e daemon launcher
---------
Co-authored-by: ABorakati <ABorakati@users.noreply.github.com>
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
`worktree.setup` ran two POSIX-only command strings, but lifecycle commands
go through PowerShell on Windows, so worktree creation failed at:
PASEO_DEV_MANAGED_HOME=1 PASEO_DEV_SEED_HOME=... ./scripts/dev-home.sh
-> PASEO_DEV_MANAGED_HOME=1 : The term ... is not recognized
PowerShell has no `VAR=value cmd` prefix syntax. The `cp` entry was broken the
same way: `$PASEO_SOURCE_CHECKOUT_PATH` is an undefined *PowerShell* variable,
not an env var, so it expanded to empty and the copy resolved to
`/packages/server/.env`.
Neither entry can be expressed portably in a single shell string, and `bash` is
not guaranteed on Windows, so move both steps into a Node script that reads its
inputs from `process.env` — matching the existing
`node ./scripts/seed-ios-native-cache.mjs` entry. One code path, no platform
branching.
`scripts/dev-home.sh` is unchanged and still sourced by the bash service
scripts; only the setup-time seeding is ported.
One behavior change: a missing `packages/server/.env` in the source checkout is
now skipped with a log instead of aborting setup. It is untracked local config,
and the old `cp` hard-failed worktree creation for anyone without one.
Co-authored-by: ABorakati <ABorakati@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* feat: live provider quota panel (Claude + Codex)
Adds Claude and Codex plan usage to the context window percentage circle tooltip, querying their respective APIs directly using existing CLI auth tokens.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: address review feedback - restore quota trigger, guard NaN date
- Re-add triggerFetch() on agent idle/error in agent status subscription
- Guard formatResetsAtLabel against NaN from malformed API date strings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: resolve composer conflict and stub subscribe in websocket tests
* feat(quota): add cursor, copilot, zai, grok, and kimi quota UI and improve type safety
* feat(quota): make Claude and Codex pluggable, and map additional quota/credits metrics
* security(quota): fix shell injection vulnerability by migrating exec to execFile
* revert: restore original scripts/dev.ps1 and packages/desktop/scripts/dev.ps1
* Fix i18n resource test expectation
* Fix quota tooltip empty-provider state
* Preserve zero values in Grok quota
* Fix empty quota fetch state
* Ignore quota frames in relay reconnect tests
* Persist refreshed Codex tokens to source auth file
* fix(quota): read Claude OAuth credentials from the macOS login Keychain
On macOS, Claude Code stores its OAuth credential in the login Keychain
(generic-password item, service "Claude Code-credentials"), not in
~/.claude/.credentials.json — that file usually does not exist there, so the
Claude provider's existsSync check failed and macOS users silently got no
Claude quota. Read it via the macOS `security` CLI (its ACL only trusts
/usr/bin/security to decrypt; a native Keychain read would prompt), and stay
read-only there since Claude Code owns the refresh/persist. Linux and Windows
keep using ~/.claude/.credentials.json unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix quota keychain timeout and local host reconciliation
* Fix terminal notification test quota stub
* Ignore quota frames in terminal notification tests
* fix(quota): bypass Claude token refresh on macOS Keychain-backed logins
* fix(dev): update local dev daemon port to 6768 on Windows scripts/dev.ps1
* fix(dev): bypass Unix dev-daemon.sh on Windows in dev.ps1
* fix(client): handle and dispatch provider_quota event in DaemonClient
* fix(desktop): fix PowerShell quote stripping in desktop dev.ps1 config seeding
* fix(desktop): execute config update via temp file to avoid PowerShell quoting bugs
* fix(desktop): fix concurrently command invocation on Windows in dev.ps1
* fix(desktop): resolve path escaping and environment setting syntax errors in dev.ps1 for Windows
* Add on-demand provider usage views
* Fix Cursor usage billing dates
* Move provider usage renderer coverage to e2e
* Use provider manifest for quota fetchers
* Add provider usage fetch timeouts
* Reshape provider usage fetchers
---------
Co-authored-by: ABorakati <ABorakati@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
Co-authored-by: lumingjun <lumingjun@bytedance.com>