* fix(shell): recover when CWD path was replaced by a non-directory
Closes#844.
When the session's cached working directory is renamed on disk and
a file is subsequently created at the old path (e.g. `mv orig renamed
&& touch orig`), every Bash tool invocation failed with
`ENOTDIR: not a directory, posix_spawn '/usr/bin/zsh'` (exit 126),
and `!`-prefixed commands silently failed. No recovery was possible
without restarting the session.
Root cause: the pre-spawn guard in `src/utils/Shell.ts:exec()` used
`realpath(cwd)` to detect a missing CWD. `realpath()` succeeds on
any existing path — file or directory — so a path that was replaced
with a regular file slipped past the check. spawn() was then called
with `cwd` pointing at a non-directory and failed with ENOTDIR.
Fix: replace `realpath()` with `stat().isDirectory()` for both the
primary CWD check and the `getOriginalCwd()` fallback check. When
the cached CWD is no longer a directory, fall back to the original
CWD (as before) and update state so subsequent tools recover
transparently.
Verification:
- Repro: `mkdir -p /tmp/x/orig && mv /tmp/x/orig /tmp/x/renamed
&& touch /tmp/x/orig`, then exec with stale cwd=/tmp/x/orig
- Before: exit 126, stderr "ENOTDIR: not a directory, posix_spawn"
- After: exit 0, cwd transparently recovered to originalCwd
- `bun test` — no new regressions (pre-existing model/provider
test failures are unrelated and present on main)
* fix(shell): drop now-unused realpath import
Squash the current repository state back into one baseline commit while
preserving the README reframing and repository contents.
Constraint: User explicitly requested a single squashed commit with subject "asdf"
Confidence: high
Scope-risk: broad
Reversibility: clean
Directive: This commit intentionally rewrites published history; coordinate before future force-pushes
Tested: git status clean; local history rewritten to one commit; force-pushed main to origin and instructkr
Not-tested: Fresh clone verification after push