Repository navigation
Conversation
…A-4682) zsh reached the ZDOTDIR wrapper only when an OpenCode/MiMo/Codex/agent-teams overlay or a startup command asked for it. A plain pane whose sole Orca-injected env was a worktree-scoped ORCA_HISTFILE took the unwrapped fast path, so nothing ran the restore block and macOS /etc/zshrc reassigned HISTFILE back to ~/.zsh_history — worktree history isolation was a silent no-op on the default path (#11044 all over again). Gate the wrapper on the injected ORCA_HISTFILE in all three launch paths: desktop (LocalPtyProvider), daemon (pty-subprocess), and relay. On the desktop the decision is re-run after injectHistoryEnv, since ORCA_HISTFILE does not exist yet where the original gate is evaluated.
📝 WalkthroughWalkthroughThe change adds scoped zsh history detection and restoration for local and relay PTY launches. It removes unauthorized inherited 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
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 |
…h wrappers out of OSC 133 The scoped-history wrapper gate keys off ORCA_HISTFILE, which the daemon fork and the relay both inherit from the Orca pane that launched them — reintroducing the #11146 cross-worktree leak for panes with scoping OFF. Drop it on both sides unless the spawn itself injected it, mirroring the desktop guard. Wrapping for history alone also enrolled every plain zsh pane in OSC 133, which drives agent-status drops and the git-status refresh signal. Gate the zsh wrapper's OSC 133 registration on ORCA_SHELL_COMMAND_MARKERS and launch history-only panes with it off, so their command lifecycle is unchanged. Also scrub the wrapper/history env in the daemon test harness so those tests are hermetic on a machine running inside a wrapped Orca pane.
… to children The gate flag went into the pane's PTY env, so it was exported to every child. An Orca started from a history-only pane inherited it and silenced 133;A/C/D for every overlay and startup pane it spawned, stranding agent rows on 'working'. Pin it in both wrapped launch configs and unset it in the wrapper after the gate is read. Also stop returning a wrapper ZDOTDIR for a history-only pane when wrapper generation failed, which would have dropped the user's whole zsh config.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/zsh-scoped-histfile.live-shell.test.ts (1)
241-253: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winAdd scoped-history handling to the relay launch configuration.
src/relay/pty-shell-launch.tswraps zsh only for overlays or startup markers. With the environment at Line 244, it returns an unwrapped login launch and does not preserveHISTFILEon hosts that clobber it. IncludeORCA_HISTFILEin the zsh wrapper condition. SetORCA_SHELL_COMMAND_MARKERSto'0'only when scoped history is the sole wrapper reason.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 5149a15e-2333-40c9-9ba6-58d3e8a857df
📒 Files selected for processing (16)
src/main/daemon/daemon-zsh-shell-ready-rcfile.tssrc/main/daemon/pty-subprocess-managed-agent-env.test.tssrc/main/daemon/pty-subprocess-test-harness.tssrc/main/daemon/pty-subprocess.tssrc/main/daemon/shell-ready.tssrc/main/providers/local-pty-provider-spawn-env.test.tssrc/main/providers/local-pty-provider-test-harness.tssrc/main/providers/local-pty-provider.tssrc/main/providers/local-pty-shell-ready-wrapper-generation.test.tssrc/main/providers/local-pty-shell-ready-wrapper-generation.tssrc/main/providers/local-pty-shell-ready.tssrc/main/pty/zsh-history-restore-wrapper.tssrc/main/shell-templates.tssrc/main/zsh-scoped-histfile.live-shell.test.tssrc/relay/pty-handler-spawn-environment.test.tssrc/relay/pty-handler.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- src/main/providers/local-pty-provider-spawn-env.test.ts
- src/main/providers/local-pty-provider.ts
- src/main/providers/local-pty-provider-test-harness.ts
Included review availability: Your plan includes up to 10 reviews per rolling hour; 2 remain after this review.
| const blocked = join(mkdtempSync(join(tmpdir(), 'orca-daemon-userdata-')), 'userdata') | ||
| writeFileSync(blocked, '') |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Remove the temporary test directory.
Each run leaves the directory created by mkdtempSync in the system temporary directory. Keep its parent path and remove it in finally.
Proposed fix
- const blocked = join(mkdtempSync(join(tmpdir(), 'orca-daemon-userdata-')), 'userdata')
+ const userDataPath = mkdtempSync(join(tmpdir(), 'orca-daemon-userdata-'))
+ const blocked = join(userDataPath, 'userdata')
@@
} finally {
consoleError.mockRestore()
process.env.ORCA_USER_DATA_PATH = previousUserDataPath
+ rmSync(userDataPath, { recursive: true, force: true })
if (platform) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const blocked = join(mkdtempSync(join(tmpdir(), 'orca-daemon-userdata-')), 'userdata') | |
| writeFileSync(blocked, '') | |
| const userDataPath = mkdtempSync(join(tmpdir(), 'orca-daemon-userdata-')) | |
| const blocked = join(userDataPath, 'userdata') |
|
Flagging this for a human review rather than merging it with the rest of the batch. The underlying defect is real and confirmed: What gives me pause is not any single finding, it is the shape of the review history. Each round fixed its predecessor's findings and introduced a new one in the same class:
Both regressions were inheritance leaks through the pane env, which is the same mechanism as the bug being fixed. That is a sign the change sits on a surface where env flows are easy to get wrong, not that any individual fix was careless. Blast radius is also the largest of the batch: this routes nearly every macOS/Linux zsh pane through the ZDOTDIR wrapper, a path that previously only agent panes took. Two open nits from the final review, neither blocking:
The other four PRs in this batch (#15193, #15194, #15195, #15196) are contained and went through the readiness checklist with zero P0. This one has not been through it. 🤖 Reviewed with Claude Code |
|
Superseded by #15258, which is merged. This PR's approach was abandoned rather than iterated. The root defect was structural: it used a negative, exported switch ( #15258 inverts both properties. One It also lands the things this PR never got to:
The two nits raised here — the unguarded relay wrapper generator and the leaked Thanks for the review pressure on this one; the objections raised here are what produced the design that shipped. |
ELI5
Orca gives each worktree its own shell history file. On macOS,
/etc/zshrcoverwritesHISTFILEon every zsh startup, so Orca launches zsh through a small wrapper that puts the right value back afterwards. But that wrapper was only turned on when something else needed it (a Codex/OpenCode overlay, or a startup command). A plain terminal pane got no wrapper — so its per-worktree history was quietly thrown away and every worktree shared~/.zsh_history. This turns the wrapper on when a scoped history is the only reason to need it, without changing anything else about how those panes behave.What Changed
ORCA_HISTFILE(set only when this spawn injected a worktree-scoped history) now counts as a reason to launch zsh through the ZDOTDIR wrapper, on all three launch paths:src/relay/pty-shell-launch.ts— one line inhasOverlayRestoreEnv. Ordering was already correct on both relay paths:injectRelayHistoryEnvruns beforegetRelayShellLaunchConfigin the spawn path and in the revive path.src/main/daemon/pty-subprocess.ts— added to the no-marker gate.ORCA_HISTFILEis injected client-side indaemon-pty-adapter.ts(withHistoryIsolation) beforeoptscross into the subprocess, so it is present when the gate runs.src/main/providers/local-pty-provider.ts—injectHistoryEnvruns ~65 lines after the wrapper gate, soORCA_HISTFILEdoes not exist yet there. Rather than reorder injection (its output feeds the WSL/CodexWSLENVbranches), a second, narrow decision runs right after injection and applies the wrapper only when the first gate declined. It also setsgetFallbackShellReadyConfigso a zsh→bash fallback stays consistent withupdateHistoryEnvForFallback.src/main/pty/zsh-history-restore-wrapper.tsholds the shared predicate (ORCA_HISTFILEpresent and shell basename is exactlyzsh) so desktop and daemon cannot drift.Review-driven corrections are in the follow-up commits:
1. An inherited
ORCA_HISTFILEcan no longer wrap a pane (regression guard for #11146)The gate keys off
ORCA_HISTFILE, and both the daemon fork and the relay server merge their ownprocess.envinto every spawn env. Orca launched from inside an Orca pane inherits that pane's exportedORCA_HISTFILE. Before this fix, a pane that took an early return — history scoping OFF, noworktreeId, or a reconnect wheresessionId !== undefined && isNewSession !== true— would have been wrapped and pointed at the launching worktree's history file. Pre-PR that inherited value was inert on an unwrapped pane; the new gate made it live.src/main/daemon/pty-subprocess.tsnow callsremoveInheritedOrcaHistFile(env, opts.env)next toremoveUnspecifiedPaneIdentityEnv— the value survives only when this spawn'sopts.envcarries it.src/relay/pty-handler.tsdeletesORCA_HISTFILEat the end ofbuildSpawnEnv, so onlyinjectRelayHistoryEnv(which runs after) can set it. A client-sent one names a path on the client and is dropped too.local-pty-provider.ts, "Credit: fix(terminal): keep worktree HISTFILE after macOS /etc/zshrc #11146"); it is now pinned by a test that seedsprocess.env.ORCA_HISTFILEwith scoping off.2. History-only wrapping no longer enrolls a pane in OSC 133
The wrapper
.zshrcregistered the OSC 133precmd/preexechooks unconditionally (outside the[[ ! -o login ]]guard, so login panes too). Turning the wrapper on for plain panes would therefore have made every command in nearly every zsh pane emit133;A/C/D, which feedshandleCommandFinished→paneForegroundAgentTracker.onCommandFinished()/dropCommandFinishedStatusIfSameTurnanddispatchTerminalCommandFinishedEvent→ the git-status push-signal refresh. That is a real behavior change for panes that emitted no markers at all before, and it is not what this PR is for.getZshOsc133RegistrationBlock()insrc/main/shell-templates.tsnow owns that block (it was duplicated verbatim in the desktop and daemon rcfiles) and gates it onORCA_SHELL_COMMAND_MARKERS— absent or non-0means register, exactly as today.getHistoryRestoreShellLaunchConfig()(desktop + daemon) is the markerless zsh wrapper plusORCA_SHELL_COMMAND_MARKERS=0, and is used only when a scoped history is the sole reason to wrap. Any pane wrapped for an overlay or a startup command is untouched and still registers OSC 133.3. The OSC 133 suppression no longer escapes the pane that needs it
ORCA_SHELL_COMMAND_MARKERS=0goes into the pane's PTY env, so zsh exports it to every child of that pane, and nothing unset or scrubbed it. Since this PR makes a plain zsh pane history-only wrapped, runningpn devor theorcaCLI from one handed that0to the new Orca'sprocess.env— and bothlocal-pty-provider.ts({...process.env, ...args.env}) andpty-subprocess.tsmergeprocess.envinto every spawn env, whilegetWrappedShellLaunchConfigpinnedORCA_SHELL_READY_MARKER/ORCA_SHELL_STARTUP_IDENTITYbut not this one. The inherited0therefore survivedObject.assign(finalEnv, shellLaunch.env)and suppressed the hooks for every Codex/OpenCode/agent-teams overlay pane and every startup-command pane that instance spawned: no133;A/C/D, sohandleCommandFinished→paneForegroundAgentTracker.onCommandFinished()never fired and agent rows stayed stuck on "working". Same inheritance-leak class as correction 1, which was fixed in production forORCA_HISTFILEbut only in the test harness for this flag.Two layers, because they close different paths:
ORCA_SHELL_COMMAND_MARKERS: '1'in the zsh branch ofgetWrappedShellLaunchConfig(desktop and daemon), beside the two markers already pinned there. This is what protects an Orca instance whoseprocess.envis already polluted — by an older build, or by any route other than the wrapper. Sitting next to the existing pins also makes it much harder to drop silently in a later edit.unset ORCA_SHELL_COMMAND_MARKERSat the end ofgetZshOsc133RegistrationBlock(), right after the gate is read. This stops the export at its source, so nothing downstream of a history-only pane ever sees it — not just Orca, but relay servers, daemons, and user scripts. Mirrors the existingunset ORCA_SHELL_STARTUP_IDENTITYinSHELL_STARTUP_IDENTITY_MARKER_BLOCK. Only the one gate reads the variable, so unsetting after it is free.Deliberately not added: a third scrub beside
removeInheritedOrcaHistFile. It would be dead weight — the pin already overrides the inherited value on every wrapped path, and on an unwrapped pane the variable has no reader at all. The relay needs nothing either: its zsh overlay wrapper has no OSC 133 block.4. A failed wrapper write no longer costs the user their whole zsh config
ensureShellReadyWrappersAtswallows write errors and logs "Shell will launch without wrapper", butgetWrappedShellLaunchConfigreturnedZDOTDIR: <root>/zshregardless. On a persistent failure (read-only userData, bad perms, full disk) zsh would launch pointed at a directory with no.zshenv/.zshrcand none of the user's zsh config would be sourced. Pre-existing, but this PR would have extended it from agent-only panes to essentially every macOS/Linux zsh pane.getHistoryRestoreShellLaunchConfig(desktop + daemon) now returns the plain unwrapped launch whenshellReadyWrappersExist()is false. Deliberately scoped to this PR's new path only: gating the ready-marker and overlay configs the same way would silently disable startup-command delivery for agent panes on a false negative, which is a separate blast radius and belongs in its own change. The cost here is losing scoped history for that pane — exactly the pre-PR behavior — instead of losing the user's shell config.For accuracy on one point from review: the git-status consumer is not undebounced.
useGitStatusPushSignalRefresh'sfetchStatusisstatusSchedulerRef.current.signal(), which goes throughcreateGitStatusRefreshScheduler(activity debounce plus anactivityMinGapMsfloor, #7983). The change was still worth avoiding — the agent-status path and the per-command fan-out are real — but the consequence is bounded by that scheduler.Test hermeticity
src/main/providers/local-pty-provider-test-harness.tsandsrc/main/daemon/pty-subprocess-test-harness.tsnow clear inheritedZDOTDIR/HISTFILE/ORCA_*wrapper and overlay markers. The runner is normally itself a child of an Orca zsh pane, so those vars sit inprocess.env; without this, wrapper assertions pass vacuously on a dev machine and unwrapped ones fail for unrelated reasons (I hit exactly this while writing the tests, and again in the new relay test — which scrubs the overlay keys locally for the same reason).Why
/etc/zshrcon macOS contains an unguardedHISTFILE=${ZDOTDIR:-$HOME}/.zsh_historyand runs before any file the user controls, which is whyZSH_HISTFILE_RESTORE_BLOCKexists (#11044). Verified on this machine:The restore block only runs from the wrapper
.zshrc/.zlogin, and the wrapper is only reached viaZDOTDIR. So on the desktop path — history isolation ON (default,terminalScopeHistoryByWorktree: true), no Codex managed home, no OpenCode overlay, no agent-teams shim, no startup command — the feature was a no-op: every worktree shared one history. The relay had the same hole but far narrower, sinceORCA_REMOTE_CLI_BIN_DIRis set whenever the handshake reportshostPlatform; it only opened against an older host that reports none.Blast radius (the main review risk — please read)
History isolation is default-ON, so this puts nearly every plain macOS/Linux zsh pane onto the ZDOTDIR wrapper — the exact path the fast path existed to avoid. Stating that plainly rather than burying it:
/bin/zsh -li -c exit, empty$HOME, 20 launches each, real generated wrappers): plain 12 ms, wrapped 14 ms → ~2 ms fixed overhead. The wrapper sources four extra small files; the user's own rc files run either way and dominate.ORCA_SHELL_COMMAND_MARKERS=0, so these panes emit no OSC 133 and drive no command-finished consumers — same as before the PR. Panes wrapped for an overlay or a startup command are unaffected by the gate: the flag is pinned to'1'in every wrapped launch config, and the wrapperunsets it after reading it, so the suppression cannot reach a child process or a later Orca instance (see correction 3).ZDOTDIRpointing at an empty directory. The ready-marker and overlay configs still return theirZDOTDIRunconditionally on that failure — pre-existing, unchanged here, and called out in correction 4.ORCA_SHELL_READY_MARKER=0), so no OSC 777 ready marker either.ZDOTDIRbefore sourcing each of their startup files and restores it at the end (getZshFinalZdotdirRestoreBlock), the same contract already in production for every agent pane.injectHistoryEnvsetsORCA_HISTFILEfor it too: no common/etc/bashrcclobbersHISTFILE, and wrapping bash would be a much larger behavior change (it also switches the pane to--rcfile).ORCA_HISTFILEis deleted on all three paths), when the caller supplied its ownHISTFILE(injection early-returns without settingORCA_HISTFILE), or when the history dir could not be created.ORCA_HISTFILEand therefore no wrapper — unchanged, and deliberately not asserted in tests.Linked Issue
STA-4682 (claim 3). Follow-up to #15018. Same failure mode as #11044; regression guard for #11146.
Fixes #
Visual Proof
N/A— shell launch configuration only; no UI surface changes.Testing
Platform: macOS (Apple Silicon, Darwin 25.3), real
/bin/zsh5.9 — every command and vacuity check below was run there and nowhere else. Not manually exercised on Linux/Windows/SSH; the daemon and relay paths are covered by unit tests, and the Windows/WSL paths are explicitly excluded by the gate.Vacuity check (each new test fails without the fix)
All rows below were measured on macOS (Apple Silicon, Darwin 25.3,
/bin/zsh5.9). Not re-measured on Linux or Windows. That matters for the live-shell rows: their premise is that a system/etc/zshrcclobbers an injectedHISTFILE, which macOS always does and a stock Linux image usually does not.zsh-scoped-histfile.live-shell.test.tsnow probes for that clobber at module load and skips the cases that depend on it (itWithHistfileClobber) when it does not happen, so those cases report "skipped" on such a host instead of passing vacuously. The OSC 133 case does not depend on the clobber and runs everywhere zsh exists.pty-shell-launch.test.ts› wraps zsh when a worktree-scoped history must survive shell startupsrc/relay/pty-shell-launch.tszsh-scoped-histfile.live-shell.test.ts› keeps the scoped HISTFILE for a relay plain pane (real zsh)src/relay/pty-shell-launch.ts/etc/zshrcdefault instead of the scoped pathlocal-pty-provider-spawn-env.test.ts› uses shell wrapper when worktree-scoped history must survive shell startupsrc/main/providers/local-pty-provider.tspty-subprocess-managed-agent-env.test.ts› uses shell wrapper when worktree-scoped history must survive shell startupsrc/main/daemon/pty-subprocess.tszsh-scoped-histfile.live-shell.test.ts› keeps the scoped HISTFILE for a local plain pane (real zsh)requiresZshHistoryRestoreWrapperforced tofalse/etc/zshrcclobbersHISTFILEpty-handler-spawn-environment.test.ts› drops an inheritedORCA_HISTFILEwhen the pane has history scoping offdelete result.ORCA_HISTFILEinbuildSpawnEnvZDOTDIRset under the tempHOMEpty-subprocess-managed-agent-env.test.ts› drops anORCA_HISTFILEthe daemon inherited from the pane that launched itremoveInheritedOrcaHistFilecalllocal-pty-shell-ready-wrapper-generation.test.ts› OSC 133 block gated onORCA_SHELL_COMMAND_MARKERSif [[ 1 == 1 ]]zsh-scoped-histfile.live-shell.test.ts› local plain pane registers no__orca_osc133_precmd(real zsh, reads$precmd_functions)ORCA_SHELL_COMMAND_MARKERSnot set by the launch configlocal-pty-provider-spawn-env.test.ts+pty-subprocess-managed-agent-env.test.ts›ORCA_SHELL_COMMAND_MARKERS === '0'for history-only wrappingORCA_SHELL_COMMAND_MARKERSrenamed in both launch configslocal-pty-provider-spawn-env.test.ts› ignores an inherited command-marker suppression for an overlay pane / for a startup-command paneORCA_SHELL_COMMAND_MARKERS: '1'pin inlocal-pty-shell-ready.ts'0'reached the spawn envpty-subprocess-managed-agent-env.test.ts› ignores a command-marker suppression the daemon inherited from its launcherdaemon/shell-ready.tszsh-scoped-histfile.live-shell.test.ts› keeps a history-only pane out of OSC 133, without leaking that to children (real zsh)unset ORCA_SHELL_COMMAND_MARKERSingetZshOsc133RegistrationBlock()ORCA_SHELL_COMMAND_MARKERS=0set (and would export it)local-pty-shell-ready-wrapper-generation.test.ts› leaves a history-only pane unwrapped when the wrapper files could not be writtenshellReadyWrappersExist()guard inlocal-pty-shell-ready.tsZDOTDIRanywaypty-subprocess-managed-agent-env.test.ts› leaves a history-only pane unwrapped when the wrapper files could not be writtendaemon/shell-ready.tsNegative tests added alongside each (plain zsh with no Orca env still takes the unwrapped fast path; history scoping off ⇒ no wrapper even with an inherited
ORCA_HISTFILE; an overlay-wrapped pane still registers OSC 133; a caller-injectedORCA_HISTFILEis preserved).The live-shell cases are the coverage that was missing: the original ones pre-write the wrapper
ZDOTDIRand can only prove the wrapper content is right. The new ones build the launch config through the real config functions and spawn real zsh with exactly that args/env pair. Their docblock now says so explicitly — they do not driveLocalPtyProvider.spawn; which panes reach those functions is unit-covered inlocal-pty-provider-spawn-env.test.tsandpty-subprocess-managed-agent-env.test.ts.AI Disclosure
Claude Opus.
Review
Highest-value things to check:
ORCA_SHELL_COMMAND_MARKERSpolarity and containment: absent means register, so every existing wrapper user is unchanged and only the new history-only launch opts out. It is pinned to'1'in both wrapped launch configs andunsetby the wrapper immediately after the gate reads it, so an inherited value can neither reach a wrapper nor escape the pane that set it. Wrapper files are rewritten on the firstensureShellReadyWrapperscall of each process, so there is no stale-file window.ORCA_HISTFILEscrubs: daemon keeps a value only whenopts.envcarries it (mirrorsremoveUnspecifiedPaneIdentityEnv); the relay drops it unconditionally inbuildSpawnEnvbecause onlyinjectRelayHistoryEnv, which runs after, may set it there.injectHistoryEnvand only when the first gate produced no config (posixShellLaunch === null). Nothing between there andspawnShellWithFallbackmutatesshellPath, and for zsh the wrapper'sargsare['-l'], identical to the existing default — only env changes.Agent skill upstream boundary
Notes
Deliberately scoped out of this PR (STA-4682 has five claims):
fish_history) — separate PR.fish_historyinto a WSL guest creates a file only a guest-sidewsl.exe --exec fishcan find;deleteRelayHistoryhardcodes['bash_history','zsh_history']under a single root; and the relay revive path callsresolveDefaultShell()and ignores the stored shell override. Injecting without the matching deletion counterpart would be strictly worse than today's no-op, so it needs its own design.HOME/XDG_DATA_HOMEdiffer from the relay process's, so the path is unreachable.HISTFILE—injectRelayHistoryEnvearly-returns on a caller-suppliedHISTFILE, so a revived pane can end up with a scopedHISTFILEand noORCA_HISTFILE. That behavior predates this PR and is unchanged by it.Cross-platform: the desktop hook is guarded by
!wslInfo && process.platform !== 'win32'; the daemon and relay gates only fire for a shell basename of exactlyzsh(so neverwsl.exe,cmd.exe,pwsh). Folder workspaces behave exactly like git worktrees here — the gate keys offworktreeId, which both have. Remote wire compatibility: no protocol change;ORCA_HISTFILEwas already crossing the wire, only the host's local interpretation of it changed, and an old host simply keeps today's behavior.ORCA_SHELL_COMMAND_MARKERSis host-local env consumed by a wrapper file the same build writes, so it never crosses a version boundary.Checklist
N/Awith reasonpnpm lint,pnpm typecheck, targetedvitestpass locally (full suite left to CI;pnpm buildnot run)