- CLAUDE.md: add "Question the question" and "One clarifying question" rules to Tone and Interaction — XY problem detection, false premise checks, and explicit reframe pattern before answering - Add claude/ detail-file directory (topic docs referenced from CLAUDE.md) - Add ABOUT.md, FUTURE.md - Update memory/, scripts/, settings.yaml with accumulated session changes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
31 lines
2.4 KiB
Markdown
31 lines
2.4 KiB
Markdown
# Skills Gotchas
|
|
|
|
## Broken symlinks cause silent failures under set -e
|
|
|
|
**Symptom:** install.sh fails with exit 1 on a broken symlink.
|
|
**Cause:** `readlink -f` on a broken symlink returns an empty string, causing comparison failure under `set -e`.
|
|
**Fix:** Remove stale symlinks before re-running install. When skills move directories (e.g., from `~/dev/claude/custom-claude-skills/` to `~/dev/claude/projects/custom-claude-skills/`), old symlinks break.
|
|
|
|
## `$VAR` and `${VAR}` in bang-command paths rejected by permission checker
|
|
|
|
**Symptom:** Skill fails with "Shell expansion syntax in paths requires manual approval" on `cat $HOME/dev/claude/...` or `cat ${HOME}/...`.
|
|
**Cause:** Claude Code's Bash permission checker rejects any `$VAR` or `${VAR}` expansion in file path arguments, even if the outer command matches an `allowed-tools` pattern.
|
|
**Fix:** Replace bang-commands that need dynamic paths with plain-text instructions telling Claude to use the Read tool at runtime. The Read tool bypasses the shell permission checker entirely.
|
|
|
|
## `$()` command substitution in bang-commands is rejected
|
|
|
|
**Symptom:** Bang-command like `git log --since="$(git log ...)"` fails even though `Bash(git *)` is in allowed-tools.
|
|
**Cause:** The permission checker rejects any command containing `$()` subshells regardless of the outer pattern match.
|
|
**Fix:** Keep bang-commands simple. If complex logic is needed, either (a) have the skill instructions tell Claude to run it via tool calls instead, or (b) create a thin wrapper shell script that runs the `$()` substitution internally and call the wrapper from the bang-command (see `list-transcripts-here.sh` for the wrapper pattern).
|
|
|
|
## Relative paths in bang-commands resolve differently based on CWD
|
|
|
|
**Symptom:** `cat ../claude-foundations/settings.yaml` resolves to the wrong path (outside sandbox) when skill is invoked from an unexpected CWD.
|
|
**Fix:** Use `CLAUDE_PROJECT_ROOT` env var instead of relative paths. Env var expansion (without `$`) isn't rejected by the permission checker when used in the SKILL.md body instructions rather than bang-commands.
|
|
|
|
## Skills created mid-session are not available as slash commands
|
|
|
|
**Symptom:** A newly created skill doesn't appear when you type `/skillname`.
|
|
**Cause:** Skills are discovered at session start, not dynamically during the session.
|
|
**Fix:** Start a new Claude Code session to pick up newly created skills.
|