agentsclimarketplace

Setup wayfinder

Skill glitchwerks/claude-wayfinder/skills/setup-wayfinder

Deterministic, auditable agent/skill dispatch for Claude Code. A typed seven-decision scoring kernel runs after the router has read the conversation — post-cognitive routing instead of prose-scanning. Auto-generates its catalog from skill sidecars and agent frontmatter.

Install
npx -y skills add glitchwerks/claude-wayfinder --skill setup-wayfinder

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Materialize the claude-wayfinder Python venv at ${CLAUDE_PLUGIN_DATA}/venv/ and write the setup-state flag. Use when: - User types /setup-wayfinder - User says "set up claude-wayfinder", "install wayfinder dependencies" - User says "wayfinder isn't working", "fix wayfinder", "repair wayfinder" - SessionStart banner indicates setup is required and the user wants to proceed - Plugin version bumped and re-setup needed Do NOT trigger on casual mentions of "wayfinder" without setup/install/fix intent.

SKILL.md

9.3 KB, as published. Nobody here has run it

Setup claude-wayfinder

Materialize the Python venv at ${CLAUDE_PLUGIN_DATA}/venv/ so plugin hooks can spawn a Python that has claude_wayfinder importable. Write the setup-state flag so hooks know setup completed.

The behavior described below is mirrored by tests/integration/setup_pipeline.py. If you change anything here, update that file too (CI's test_skill_pipeline_sync.py enforces this).

Step 1: Resolve ${CLAUDE_PLUGIN_DATA}

The plugin data directory path is keyed <plugin>-<marketplace> by the harness, and the same plugin resolves under different marketplace keys across surfacesclaude-wayfinder-glitchwerks on a CLI surface, claude-wayfinder-inline on a desktop/ccd surface. Two sources are available, in priority order:

  • Runtime env var $CLAUDE_PLUGIN_DATA (no braces) — the test seam, but the harness sets it to whichever plugin invoked the current surface, so another plugin's data dir can leak in (e.g. codex-inline). Honor it only when its basename is a same-plugin key: claude-wayfinder-<marketplace> with exactly one marketplace segment after the plugin name (-glitchwerks, -inline, …). This admits every marketplace variant while rejecting two leak classes — unrelated plugins (codex-inline) and prefix-colliding sibling plugins whose own name starts with claude-wayfinder- (e.g. claude-wayfinder-helper → key claude-wayfinder-helper-inline, which has a second - segment). Do not require an exact -glitchwerks match — that is the bug this guard replaces (it rejected the legitimate -inline desktop key and silently misinstalled into the CLI-keyed dir, leaving every desktop session stuck on the "requires setup" banner). Do not loosen it to a bare claude-wayfinder-* prefix either — that re-admits the sibling-plugin collision.
  • Harness-rendered literal ${CLAUDE_PLUGIN_DATA} (braces) — the harness substitutes this token in the skill body at load time with this session's correct data dir. Prefer it over a hardcoded -glitchwerks slug whenever the runtime env var is unusable (cross-plugin leak, or unset).
  • Computed slug (claude-wayfinder-glitchwerks) — last resort only, for raw execution outside the harness where neither source above is available.

Use the Bash tool:

PLUGIN_NAME="claude-wayfinder"
EXPECTED_SLUG="claude-wayfinder-glitchwerks"

# Harness-rendered literal (braces): substituted at skill-load with THIS session's
# data dir (…/claude-wayfinder-inline on desktop, …/claude-wayfinder-glitchwerks on
# CLI) — correct per-session. Keep the braces; do NOT rewrite to $CLAUDE_PLUGIN_DATA.
HARNESS_DATA="${CLAUDE_PLUGIN_DATA}"

if [ -n "$CLAUDE_PLUGIN_DATA" ]; then
  ACTUAL_SLUG=$(basename "$CLAUDE_PLUGIN_DATA")
  case "$ACTUAL_SLUG" in
    ${PLUGIN_NAME}-*-*)
      # Prefix-colliding SIBLING plugin: a different plugin whose name starts with
      # "claude-wayfinder-" (e.g. claude-wayfinder-helper → key
      # claude-wayfinder-helper-inline) leaves TWO segments after the plugin name.
      # Our own keys are exactly claude-wayfinder-<marketplace> (one segment, e.g.
      # -inline | -glitchwerks). Reject the collision — use the harness literal.
      echo "Warning: \$CLAUDE_PLUGIN_DATA basename '$ACTUAL_SLUG' has extra segments after '${PLUGIN_NAME}-' (prefix-colliding sibling plugin?). Using harness-rendered data dir." >&2
      PLUGIN_DATA="$HARNESS_DATA" ;;
    ${PLUGIN_NAME}-*)
      # Same-plugin key, single marketplace segment (e.g. claude-wayfinder-inline |
      # -glitchwerks) — honor it.
      PLUGIN_DATA="$CLAUDE_PLUGIN_DATA" ;;
    *)
      # Cross-plugin leak (e.g. codex-inline) — fall back to the harness literal.
      echo "Warning: \$CLAUDE_PLUGIN_DATA basename '$ACTUAL_SLUG' is not a ${PLUGIN_NAME}-* dir (cross-plugin leak?). Using harness-rendered data dir." >&2
      PLUGIN_DATA="$HARNESS_DATA" ;;
  esac
else
  PLUGIN_DATA="$HARNESS_DATA"
fi

# Safety net: if the harness literal was never interpolated (raw execution outside
# the harness leaves it empty), compute the canonical slug as a last resort.
if [ -z "$PLUGIN_DATA" ]; then
  PLUGIN_DATA="$HOME/.claude/plugins/data/$EXPECTED_SLUG"
fi

# Normalize Git-Bash POSIX paths (/c/Users/...) to native Windows form (C:/Users/...)
# so the venv_path stored in setup-state.json (Step 7) is readable by Node's
# fs.existsSync on Windows. Git Bash expands $HOME to /c/Users/... rather than
# C:/Users/..., which Node does not recognise as a valid Windows path (#186).
# On non-Windows or paths that don't match the /X/... pattern, this is a no-op.
case "$PLUGIN_DATA" in
  /[a-zA-Z]/*)
    drive=$(printf '%s' "$PLUGIN_DATA" | cut -c2 | tr '[:lower:]' '[:upper:]')
    rest=$(printf '%s' "$PLUGIN_DATA" | cut -c3-)
    PLUGIN_DATA="${drive}:${rest}"
    ;;
esac

mkdir -p "$PLUGIN_DATA"
echo "$PLUGIN_DATA"

The test seam is preserved: tests that want to override the path can still set $CLAUDE_PLUGIN_DATA to any directory whose basename is a single-segment same-plugin key claude-wayfinder-<seg> (e.g., a tmpdir created as …/claude-wayfinder-XXXX/, where XXXX has no further -). Cross-plugin leaks (codex-inline) and prefix-colliding sibling plugins (claude-wayfinder-helper-inline) are rejected and no longer cause silent misinstall into another plugin's data dir.

Step 2: Discover Python ≥3.11

Try these candidates in order, stopping at the first that probes successfully:

  1. Prior interpreter from any existing setup-state.json's interpreter field (if a flag is currently being re-setup).
  2. $CLAUDE_WAYFINDER_BOOTSTRAP_PYTHON if set.
  3. py -3 on Windows.
  4. python3 then python on PATH.

Probe each candidate with:

<candidate> -c "import sys; sys.exit(0 if sys.version_info >= (3, 11) else 1)"

Exit 0 = success, save the candidate as PYTHON.

If all candidates fail, ask the user:

No Python ≥3.11 found. I tried: $CLAUDE_WAYFINDER_BOOTSTRAP_PYTHON, py -3, python3, python. Please provide an absolute path to a Python ≥3.11 interpreter (e.g., C:\Python313\python.exe or /usr/local/bin/python3.12). If you don't have one installed, you'll need to install Python first.

Probe the user-provided path the same way. If it works, save it (will be persisted in the flag's interpreter field for future re-setup runs).

Step 3: Wipe the existing venv

Per spec § 2 D4, always wipe + recreate. No idempotency.

rm -rf "$PLUGIN_DATA/venv"

(On Windows PowerShell: Remove-Item -Recurse -Force -ErrorAction SilentlyContinue "$env:PLUGIN_DATA\venv")

Step 4: Create the venv

"$PYTHON" -m venv "$PLUGIN_DATA/venv"

If this fails:

  • Surface the stderr verbatim to the user.
  • Offer the common-cause hint: on Debian/Ubuntu, sudo apt install python3-venv is often needed.
  • Wipe any partial state. Do not write the flag. Stop.

Step 5: Install claude-wayfinder from PyPI

The version to install is the plugin's current version, read from ${CLAUDE_PLUGIN_ROOT}/pyproject.toml (preferred) or ${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json. Pin exactly:

VENV_PYTHON="$PLUGIN_DATA/venv/bin/python"  # or Scripts/python.exe on Windows
"$VENV_PYTHON" -m pip install "claude-wayfinder==$PLUGIN_VERSION"

If pip fails:

  • Surface stderr verbatim.
  • Wipe the half-built venv (always-wipe invariant).
  • Do not write the flag.
  • Tell the user to check network/PyPI and retry.

Step 6: Verify import

"$VENV_PYTHON" -c "import claude_wayfinder"

If this fails after a successful pip install, the wheel is corrupt:

  • Surface the import error.
  • Suggest pip cache purge then retry.
  • Wipe the venv. Do not write the flag.

Step 7: Write the setup-state flag

Always-wipe contract: the Write tool's read-before-overwrite invariant is hostile on re-setup, where the prior file exists but its contents are about to be discarded — use a shell heredoc instead.

Bash (Git Bash on Windows or POSIX):

TS=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
cat > "$PLUGIN_DATA/setup-state.json" <<EOF
{
  "version": "$PLUGIN_VERSION",
  "venv_path": "$PLUGIN_DATA/venv",
  "interpreter": "$PYTHON",
  "installed_at": "$TS"
}
EOF

PowerShell:

$ts = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
@"
{
  "version": "$PluginVersion",
  "venv_path": "$PluginData/venv",
  "interpreter": "$Python",
  "installed_at": "$ts"
}
"@ | Set-Content -Path "$PluginData/setup-state.json" -NoNewline

If the write fails (disk full, permission), wipe the venv (otherwise orphaned), surface the write error.

Step 8: Tell the user

On success, tell the user:

✓ claude-wayfinder setup complete.

  • venv: <path>
  • interpreter: <which Python was used>
  • version: <plugin version>

Open a new session for the dispatch matcher and catalog refresh to activate. The next check-catalog-health.js SessionStart hook will see the flag and proceed normally.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.