Skip to content

v0.3.5 — guard parity, Windows guard hook, and a plugin data-loss fix

Choose a tag to compare

@waazy-w waazy-w released this 21 Aug 19:36
· 30 commits to main since this release

A branch-coverage pass turned up six real bugs. All six are fixed here, and every one is pinned by a test that fails if it comes back.

Security

The guard's fallback matcher no longer under-blocks. guard-hook.js carries its own copy of the never-touch glob logic so the guard still works when never-touch.js cannot be loaded — but it was a looser reimplementation, and every gap was a silent hole. It had no {a,b} alternation, so a neverTouch of *.{pem,key} was entirely unenforced whenever the fallback was live. It also did not trim the glob, strip a leading /, or skip an empty one. It is now a faithful copy, and a parity test across the shipped defaults fails on any future divergence.

The guard hook runs on Windows. Its command carried the guard's config in a POSIX VAR=value prefix that cmd.exe cannot parse, so it was skipped there entirely. The deny rules left behind cover Read/Edit/Write/Grep/Glob but not Bash, while the allowlist grants Bash(cat *) — so cat .env was unguarded on Windows alone, and the README's claim that .env is covered was false on one of three platforms. The config now travels in a file that the hook reads from argv; an unreadable one fails closed, like every other unparsable input.

Data loss

The plugin hook could lose crash events permanently. It wrote to a pipe and then called process.exit(0), discarding everything past the buffer — one minified stack trace in error is enough. Claude Code received invalid JSON and dropped the briefing, and markRead() had already advanced the cursor, so those events were gone for good. The cursor now moves only once the bytes are actually flushed, and never when the write failed.

describeEvent threw on a command that would not coerce. Because the throw came before markRead, the cursor never advanced and every later prompt in that repo retried and failed identically. Every field is coerced safely now — and flattened to one line, since error is raw output from the crashed program and the briefing is line-oriented text.

Correctness

  • reproTimeoutMs was read off opts, which only ever carries cwd, so the re-run timeout was hard-wired to 30 s and every override was silently ignored. The test suite went from 45 s to 17 s.
  • A failed commit told you it left you on the branch "(--no-commit)" when autoCommit was on. It now names the actual reason.

Also

  • The Claude Code plugin is documented as a first-class install path, with update instructions for both channels.
  • 243 → 306 tests. prompt.js branch coverage 59.8% → 98.3%; recovery.js at 100% lines.

Install: npm install -g claude-phantom · Plugin: /plugin marketplace add waazy-w/claude-phantom