Files
hyperframes/packages
James RussoandClaude Opus 4.8 13b115e006 fix(cli): close skills removed-detection power-user gaps (follow-up to #1740) (#1743)
* fix(cli): close skills removed-detection power-user gaps (follow-up to #1740)

Address power-user follow-ups deferred from #1740 (skills removed-detection):

- `--dir` installs now run removed-detection. `locateInstall` hardcoded
  scope "project" for every `--dir`, so a `--dir ~/.claude/skills` (a global
  install) read a non-existent `<cwd>/skills-lock.json` and found zero
  removed skills. New `scopeForDir` infers global vs project from whether the
  dir is under $HOME, so the right lock is read.
- Pin the upstream lock paths to vercel-labs/skills@v1.5.13 (verified against
  src/skill-lock.ts + src/local-lock.ts) and warn loudly when the lock is
  absent where expected, so removed-detection no longer silently no-ops if
  upstream moves the lock. checkSkills returns lockMissing; --json surfaces it.
- skills update gains --source/--dir (parity with check), plumbed into its
  internal prune checkSkills() so the prune respects the same overrides.
- Add the missing test for the all-rejected-names early-return in
  runSkillsRemove (no skills remove spawned when every candidate name is
  rejected), plus tests for the --dir scope inference and update flag parity.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(cli): scope --dir by CWD-containment before HOME (project installs under $HOME)

Address Magi's REQUEST_CHANGES on #1743 (88daa820). The new scopeForDir
heuristic treated every explicit --dir under $HOME as GLOBAL, but the common
project-local case is also under $HOME (e.g. ~/work/proj/.claude/skills, or
--dir .claude/skills run from ~/work/proj). So checkSkills could read the
GLOBAL lock and `skills update --dir ...` could prune with `skills remove -g`
even when the user pointed at a PROJECT install — a wrong-scope prune.

Change precedence to CWD-containment FIRST, then HOME:
- dir resolves under cwd  -> project (even when cwd is itself under $HOME)
- else dir under home     -> global
- else                    -> project (safe default, never prune globally)

Keeps the existing resolve/normalize + trailing-separator guard (so /home/user2
does not false-match /home/user). scopeForDir now takes cwd; locateInstall
threads opts.cwd through.

Add a regression test for Magi's exact failing case: cwd nested under home
(cwd = <home>/work/proj) with --dir <cwd>/.claude/skills resolves to PROJECT.
Existing tests stay green (global --dir ~/.claude/skills from an unrelated cwd
still resolves to GLOBAL).

Also (Miga's nit): drop the redundant `as string | undefined` casts on the
citty args in skills.ts (citty already infers that type), and clarify the
`skills update` --dir/--source help text to note they scope removed-detection
only, not the install location.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 10:39:05 -07:00
..
2026-06-26 00:51:34 -04:00
2026-06-26 00:51:34 -04:00
2026-06-26 00:51:34 -04:00
2026-06-16 13:16:09 -04:00
2026-06-26 00:51:34 -04:00