Files
orcs-code/src/utils/Shell.ts
KRATOS a4c6757023 fix(shell): recover when CWD path was replaced by a non-directory (#871)
* 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
2026-04-24 11:34:08 +08:00

17 KiB