fix(subagent): keep .codewhale/state out of the user's git status

Before: opening any conversation in a git workspace created
.codewhale/state/subagents.v1.lock, so the person's own `git status` (and
the desktop Review panel) listed an untracked ".codewhale/" they never
made.

After: when the coordination lock creates .codewhale/state it also writes
a .gitignore containing "*" there, which ignores the lock, the state
JSON and itself. Only the state folder is ignored; anything a person
commits elsewhere under .codewhale/ is untouched. An existing .gitignore
is left alone, and a failed write leaves behaviour as before.

Evidence: built codewhale-cli at this commit and started the desktop app
on a fresh git workspace (Xvfb harness). .codewhale/state held .gitignore
and subagents.v1.lock, and `git status --short` printed nothing. Engine
v0.10.1 on the same setup lists "?? .codewhale/". The codewhale-tui lib
test binary could not be built here (rustc was OOM-killed at 15 GB), so
the coordination tests are left to CI. rustfmt --check passes and
scripts/check-blocking-calls-budget.py is within budget (538 sites).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_018hVPRff6jfJiVouZtvhZgJ
This commit is contained in:
Claude committed 2026-10-11 12:21:38 +00:00
1 parent 2e8bc7bc7a
commit 491d3df155
1 file changed
+4
+4
View File
@@ -3668,6 +3668,10 @@ impl CoordinationProcessLock {
// `create_dir_all` follows links and would populate the target.
reject_root_relative_symlinks(&requested_root, &lock_dir.join(SUBAGENT_STATE_LOCK_FILE))?;
fs::create_dir_all(&lock_dir)?;
let ignore = lock_dir.join(".gitignore");
if !ignore.exists() {
let _ = fs::write(&ignore, "*\n");
}
// Creating a missing root can change its canonical spelling on
// Windows (for example by adding a `\\?\` prefix). Re-resolve both
// sides before checking containment.