Component: crates/cli (status/pin/diff for dir entries) | Severity: Medium-High (leads to data loss via false confidence) | Status: Reproduced
All dir-entry comparisons iterate the cache file list. A file the user deleted locally reads as "not modified" (missing installed file → return Ok(false)), and a file the user added is never examined at all. So: status clean, diff "clean - no local modifications", pin "matches upstream - nothing to pin" (writes no patch). The user reasonably believes their customization is captured; a fresh clone+install won't have the added file, and install --update resurrects the deleted one.
Where: crates/cli/src/commands/status.rs:29-32; crates/cli/src/commands/multi_target.rs:54-59; crates/cli/src/commands/pin.rs:101-118 (also deletes patches for files missing from the representative).
Repro:
# installed dir skill 'd' with files SKILL.md + helper.md
rm .claude/skills/d/helper.md && echo notes > .claude/skills/d/notes.md
skillfile status # clean
skillfile diff d # 'd' is clean - no local modifications
skillfile pin d # 'd' matches upstream - nothing to pin
Expected: additions/deletions reported as modifications; pin either captures them (add-file patches / deletion records) or errors "cannot pin added/deleted files" so the user knows.
Actual: fully invisible.
Fix sketch: in the dir comparison, walk the union of cache and installed file sets; report installed-only files as added and cache-only-with-missing-installed as deleted; make pin at minimum refuse with a message listing them (full capture support can come later).
Tests:
- Unit (
crates/cli/src/commands/multi_target.rs or status.rs): cache={a}, installed={a,b} → modified; cache={a,b}, installed={a} → modified.
- Functional (
tests/cli.rs): the repro; assert status marks the entry and pin does not claim success.
Component:
crates/cli(status/pin/diff for dir entries) | Severity: Medium-High (leads to data loss via false confidence) | Status: ReproducedAll dir-entry comparisons iterate the cache file list. A file the user deleted locally reads as "not modified" (missing installed file →
return Ok(false)), and a file the user added is never examined at all. So:statusclean,diff"clean - no local modifications",pin"matches upstream - nothing to pin" (writes no patch). The user reasonably believes their customization is captured; a fresh clone+install won't have the added file, andinstall --updateresurrects the deleted one.Where:
crates/cli/src/commands/status.rs:29-32;crates/cli/src/commands/multi_target.rs:54-59;crates/cli/src/commands/pin.rs:101-118(also deletes patches for files missing from the representative).Repro:
Expected: additions/deletions reported as modifications;
pineither captures them (add-file patches / deletion records) or errors "cannot pin added/deleted files" so the user knows.Actual: fully invisible.
Fix sketch: in the dir comparison, walk the union of cache and installed file sets; report installed-only files as added and cache-only-with-missing-installed as deleted; make
pinat minimum refuse with a message listing them (full capture support can come later).Tests:
crates/cli/src/commands/multi_target.rsorstatus.rs): cache={a}, installed={a,b} → modified; cache={a,b}, installed={a} → modified.tests/cli.rs): the repro; assert status marks the entry and pin does not claim success.