b13b39e729fce349a2973b47d8925ddbb76e82fe
-c operand ordering; fix test socket paths
`bash -c` does not bind to the token that follows it: short-option parsing
continues and the command string is the first operand, so `bash -c -l <cmd>`
runs `<cmd>` as a login shell. brush's clap CLI instead binds `-c` to the next
token and rejects one shaped like an option, so every command the agent CLI
sent as `-c -l <cmd>` inside naros-agent failed with
error: a value is required for '-c <COMMAND>' but none was supplied
Since narOS diverts /bin/sh, /bin/bash and /bin/dash to nash, that broke every
command in the container. nash's compat fallback did not cover it either: it
read "-l" as the command, which parses fine as bash, so no fallback fired.
Normalize the argv before clap sees it, hoisting short options that sit between
the `-c` group and its command ahead of that group (`-c -l cmd` -> `-l -c cmd`),
including value-taking ones (`-c -o xtrace cmd`, `-c -oxtrace cmd`). Only short
options are hoisted — bash itself rejects long options once short-option parsing
has begun — and anything not positively identified as an option ends the scan,
so a command string is never mistaken for a flag. Teach nash's dash_c_command()
the same rule so the parse-failure fallback checks the real command.
Also repair the observe test harness, which could not run under a normal macOS
TMPDIR: it named its socket directory with `{:?}` of an Instant (~45 chars),
overflowing sun_path, and never cleaned up, so a recycled pid inherited a stale
socket and failed the bind with AlreadyExists. Route every scratch directory
through a helper that keeps names short, falls back to /tmp when the socket path
would not fit, clears stale state, and drops the directory when the sink dies.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
shell/ — nash, the Nucleic agent shell
Design doc: docs/NASH.md. Vendored fork base:
third_party/brush/ (brush, pinned at
brush-shell-v0.4.0; fork patches are marked with // nash: comments).
nash/— the shell binary (M0: transparent embedding of the brush CLI).nash-observe/— event model, taps, and transport (lands in M1).corpus/— transcript-replay compat harness:replay.pyruns every command incorpus.jsonlunder bash and nash in identical fresh workspaces and diffs exit/stdout/filesystem (stderr reported separately). Divergences are tracked incorpus/DIVERGENCES.md.
Build & test:
cargo build --release # binary: target/release/nash
python3 corpus/replay.py --nash <path> # M0/M3 gate: >= 99% parity
Languages
Rust
79.6%
Python
20.4%