* style: format codebase
* style: format codebase
* refactor: extract skill install dialog footer and content
Extract footer and content sections from SkillInstallDialog and
SkillInstallManagementDialog into separate components for improved
maintainability and clarity of component responsibilities.
* fix(wsl): read machine output from a fenced login shell
Orca runs WSL reads through the distro's *interactive* login shell so
PATH matches the user's own terminal (nvm, mise and asdf only install
into rc files interactive shells read). An interactive shell also runs
the distro's rc/motd, and stock Ubuntu 24.04 writes its "run a command
as administrator" hint to stdout -- no user customization required.
Every caller parsing that stream was reading the banner as data:
statPath -> "To run a command as administrator...\n\ndirectory"
readPath -> banner prepended to the contents of every file read
preflight -> banner prepended to `gh --version` / auth output
`.trim()` cannot recover any of these, so a WSL worktree's file
explorer sees no valid entry types and file reads return junk.
Three call sites had independently grown their own marker to survive
this (`__ORCA_AGENT_PATH__`, `ORCA_WSL_GIT_READ_ENV_V1`, and a
`>/dev/null` fd dance), which is the tell that it belongs in one place.
Fence the payload once, in the shared builder, and hand callers a
reader that returns just their bytes. The fence carries a per-call
nonce so `cat`-ing a file that happens to quote a marker is not
truncated. Exit status is preserved, so the ENOENT mapping still works.
wsl-git-read-environment drops its bespoke marker and parsing.
* test(wsl): fence the login-shell path-lookup boundary test
It asserted a raw interactive login-shell read matched an absolute path,
so the distro rc banner made it fail on any stock Ubuntu. It is part of
the shell-contracts CI gate, where it skips on Linux and hid the break.
* docs(wsl): record the guest command-execution contract
Both failure modes are silent - the command runs, exits 0, and returns
the wrong bytes - so the rules need to live somewhere a reader will
find them before writing the next wsl.exe call site.
* fix(codex): fence the WSL Codex identity probe
buildWslCodexBinaryStamp reads the login shell's stdout positionally --
path before the first newline, version after -- through an interactive
login shell. On a stock Ubuntu the rc banner lands ahead of the payload,
so the first newline falls inside the banner and the stamp becomes
path="To run a command as administrator..." with the rest as version.
Both halves are non-empty, so nothing throws: the stamp is silently
wrong, and an unstable stamp reads as "the Codex binary changed" and
reissues the trust grant.
The identity script ends in `exec`, so it never writes a closing fence;
the reader returns everything after the opening one, which is exactly
this case.
buildWslCodexIdentityArgs becomes buildWslCodexIdentityProbe and returns
the reader with the argv so the two cannot drift apart. The other three
WSL Codex commands are deliberately left unfenced: availability is
exit-code only, and app-server/login hand stdout to a long-running
program.
* fix(wsl): harden the capture fence after review
- readStdout now takes the LAST opening fence, matching the lastIndexOf
the wsl-git-read-environment marker used deliberately: a login shell
can echo the command text before running it, repeating the fence.
- local-worktree-filesystem throws instead of falling back to raw stdout
when the fence is missing. The fallback silently reinstated the bug
being fixed -- statPath would return the banner as a file type and
readPath would return banner+contents, with no signal. Preflight keeps
its fallback; its matchers scan the whole blob and tolerate a prefix.
- The exit-status test asserted only that the script CONTAINS `exit $?`,
which is true for any input and never executed those lines. It now
runs a real distro and asserts status 2 reaches the caller, which is
what statPath's ENOENT mapping depends on.
- Corrected the doc: a sed backreference has no `$`, so `--` never
rewrote it. Replaced with the positional and shell-local cases that
were measured to differ.
* fix(wsl): stop running a login shell for filesystem reads
statPath/readPath/rm run coreutils at standard paths and shell builtins.
They need nothing from the user's PATH, so there was never a reason to
start a login shell -- and starting one is what put the distro's rc/motd
on the stdout these callers parse.
Fencing that output treated the symptom. Using a plain `sh -c` removes
the cause: no profile, no rc, no banner, by construction. The fence and
its missing-fence error go away with it.
The fence stays where it is actually needed: the three places that must
run the user's shell to resolve their PATH (the preflight CLI probe, the
WSL git environment probe, and the Codex identity probe).
Net -12 lines.
---------
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>