fix(skill): use find instead of ls+glob in cache resolvers (zsh compatibility)
zsh errors on globs that match nothing instead of returning the literal pattern (bash's default), and `2>/dev/null` does not suppress the error because it comes from the shell's glob expansion before `ls` even runs. Under Codex (which executes the SKILL.md bash via zsh), STEP 0 and the Step 1 / comparison-mode resolvers emitted noisy "no matches found" errors on machines without a Claude plugin cache populated. Replaces all three `ls -d $HOME/.claude/plugins/cache/last30days-skill/last30days/*/` invocations with `find ... -mindepth 1 -maxdepth 1 -type d 2>/dev/null`. find is POSIX-portable, errors silently when the base dir doesn't exist, and never triggers shell glob errors. `sort -V | tail -1` precedence preserved (verified: picks 3.10.0 over 3.2.1 over 3.1.0). Trailing-slash strip removed because find doesn't append slashes. Observed in Codex session running /last30days against PR #400 with the Claude plugin cache deleted - bash output was: zsh:1: no matches found: /Users/.../last30days/*/ After fix: clean empty output, exit 0, STEP 0 correctly treats it as "no cache present, do not hop", resolver falls through to per-harness skill dirs as designed.
This commit is contained in:
@@ -67,7 +67,7 @@ Before reading anything else in this file, check whether you loaded SKILL.md fro
|
|||||||
**Run this check:**
|
**Run this check:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
CLAUDE_CACHE_LATEST=$(ls -d "$HOME/.claude/plugins/cache/last30days-skill/last30days"/*/ 2>/dev/null | sort -V | tail -1)
|
CLAUDE_CACHE_LATEST=$(find "$HOME/.claude/plugins/cache/last30days-skill/last30days" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sort -V | tail -1)
|
||||||
CLAUDE_CACHE_LATEST="${CLAUDE_CACHE_LATEST%/}"
|
CLAUDE_CACHE_LATEST="${CLAUDE_CACHE_LATEST%/}"
|
||||||
echo "CLAUDE_CACHE_LATEST=$CLAUDE_CACHE_LATEST"
|
echo "CLAUDE_CACHE_LATEST=$CLAUDE_CACHE_LATEST"
|
||||||
```
|
```
|
||||||
@@ -586,8 +586,7 @@ When the user asks "X vs Y" (or "X vs Y vs Z"), the engine fans out N full `pipe
|
|||||||
# Comparison mode skips Step 1, so resolve SKILL_ROOT inline here (same precedence
|
# Comparison mode skips Step 1, so resolve SKILL_ROOT inline here (same precedence
|
||||||
# walk as Step 1 — keep the two in sync if you edit either).
|
# walk as Step 1 — keep the two in sync if you edit either).
|
||||||
SKILL_ROOT=""
|
SKILL_ROOT=""
|
||||||
CLAUDE_PLUGIN_ROOT="$(ls -d "$HOME/.claude/plugins/cache/last30days-skill/last30days/"*/ 2>/dev/null | sort -V | tail -1)"
|
CLAUDE_PLUGIN_ROOT="$(find "$HOME/.claude/plugins/cache/last30days-skill/last30days" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sort -V | tail -1)"
|
||||||
CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT%/}"
|
|
||||||
if [ -n "$CLAUDE_PLUGIN_ROOT" ]; then
|
if [ -n "$CLAUDE_PLUGIN_ROOT" ]; then
|
||||||
if [ -f "$CLAUDE_PLUGIN_ROOT/skills/last30days/scripts/last30days.py" ]; then
|
if [ -f "$CLAUDE_PLUGIN_ROOT/skills/last30days/scripts/last30days.py" ]; then
|
||||||
SKILL_ROOT="$CLAUDE_PLUGIN_ROOT/skills/last30days"
|
SKILL_ROOT="$CLAUDE_PLUGIN_ROOT/skills/last30days"
|
||||||
@@ -900,8 +899,9 @@ SKILL_ROOT=""
|
|||||||
|
|
||||||
# 1. Claude Code plugin cache (versioned, sort -V picks freshest). Two cache layouts ship in the wild:
|
# 1. Claude Code plugin cache (versioned, sort -V picks freshest). Two cache layouts ship in the wild:
|
||||||
# nested ({cache}/{version}/skills/last30days/scripts/...) and flat ({cache}/{version}/scripts/...).
|
# nested ({cache}/{version}/skills/last30days/scripts/...) and flat ({cache}/{version}/scripts/...).
|
||||||
CLAUDE_PLUGIN_ROOT="$(ls -d "$HOME/.claude/plugins/cache/last30days-skill/last30days/"*/ 2>/dev/null | sort -V | tail -1)"
|
# `find` (not `ls + glob`) because zsh errors on globs that match nothing, leaking
|
||||||
CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT%/}"
|
# noisy "no matches found" stderr in Codex/zsh sessions even with 2>/dev/null.
|
||||||
|
CLAUDE_PLUGIN_ROOT="$(find "$HOME/.claude/plugins/cache/last30days-skill/last30days" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sort -V | tail -1)"
|
||||||
if [ -n "$CLAUDE_PLUGIN_ROOT" ]; then
|
if [ -n "$CLAUDE_PLUGIN_ROOT" ]; then
|
||||||
if [ -f "$CLAUDE_PLUGIN_ROOT/skills/last30days/scripts/last30days.py" ]; then
|
if [ -f "$CLAUDE_PLUGIN_ROOT/skills/last30days/scripts/last30days.py" ]; then
|
||||||
SKILL_ROOT="$CLAUDE_PLUGIN_ROOT/skills/last30days"
|
SKILL_ROOT="$CLAUDE_PLUGIN_ROOT/skills/last30days"
|
||||||
|
|||||||
Reference in New Issue
Block a user