From bde8591f3249e333462656af28b16f94c93bc8e3 Mon Sep 17 00:00:00 2001 From: Zehua Liu Date: Mon, 23 Mar 2026 14:46:23 +1100 Subject: [PATCH 1/8] fix: support \$CLAUDE_CONFIG_DIR for custom config paths (#349) Replace hardcoded ~/.claude with \${CLAUDE_CONFIG_DIR:-\$HOME/.claude} at each layer so gstack works correctly when Claude Code is run with a custom \$CLAUDE_CONFIG_DIR. Changes: - scripts/gen-skill-docs.ts: update HOST_PATHS + all inline path strings to use the dynamic expression; add \${CLAUDE_CONFIG_DIR} pattern to the Codex rewrite regex so Codex skills still resolve to \$GSTACK_ROOT - All .tmpl files (16): replace ~/.claude/skills/gstack with the dynamic expression in bash blocks - browse/src/find-browse.ts: check \$CLAUDE_CONFIG_DIR first in global binary search fallback - bin/gstack-global-discover.ts: use \$CLAUDE_CONFIG_DIR for Claude Code projects directory - setup: add sed rule for new pattern in Kiro path rewrite - test/gen-skill-docs.test.ts: update tests to expect new path pattern Generated SKILL.md files regenerated from updated templates. Co-Authored-By: Claude Sonnet 4.6 --- autoplan/SKILL.md.tmpl | 14 +++++++------- benchmark/SKILL.md.tmpl | 2 +- bin/gstack-global-discover.ts | 3 ++- browse/src/find-browse.ts | 7 ++++++- canary/SKILL.md.tmpl | 4 ++-- codex/SKILL.md.tmpl | 10 +++++----- design-consultation/SKILL.md.tmpl | 2 +- design-review/SKILL.md.tmpl | 2 +- gstack-upgrade/SKILL.md.tmpl | 10 +++++----- land-and-deploy/SKILL.md.tmpl | 6 +++--- office-hours/SKILL.md.tmpl | 4 ++-- plan-ceo-review/SKILL.md.tmpl | 8 ++++---- plan-design-review/SKILL.md.tmpl | 2 +- plan-eng-review/SKILL.md.tmpl | 4 ++-- qa-only/SKILL.md.tmpl | 4 ++-- qa/SKILL.md.tmpl | 4 ++-- retro/SKILL.md.tmpl | 2 +- scripts/gen-skill-docs.ts | 30 ++++++++++++++++-------------- setup | 4 +++- ship/SKILL.md.tmpl | 6 +++--- test/gen-skill-docs.test.ts | 12 ++++++++---- 21 files changed, 77 insertions(+), 63 deletions(-) diff --git a/autoplan/SKILL.md.tmpl b/autoplan/SKILL.md.tmpl index 6c844d679..ada2f1017 100644 --- a/autoplan/SKILL.md.tmpl +++ b/autoplan/SKILL.md.tmpl @@ -107,7 +107,7 @@ State what you examined and why nothing was flagged (1-2 sentences minimum). Before doing anything, save the plan file's current state to an external file: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') DATETIME=$(date +%Y%m%d-%H%M%S) echo "RESTORE_PATH=$HOME/.gstack/projects/$SLUG/${BRANCH}-autoplan-restore-${DATETIME}.md" @@ -140,9 +140,9 @@ Then prepend a one-line HTML comment to the plan file: ### Step 3: Load skill files from disk Read each file using the Read tool: -- `~/.claude/skills/gstack/plan-ceo-review/SKILL.md` -- `~/.claude/skills/gstack/plan-design-review/SKILL.md` (only if UI scope detected) -- `~/.claude/skills/gstack/plan-eng-review/SKILL.md` +- `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/plan-ceo-review/SKILL.md` +- `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/plan-design-review/SKILL.md` (only if UI scope detected) +- `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/plan-eng-review/SKILL.md` **Section skip list — when following a loaded skill file, SKIP these sections (they are already handled by /autoplan):** @@ -390,14 +390,14 @@ On approval, write 3 separate review log entries so /ship's dashboard recognizes COMMIT=$(git rev-parse --short HEAD 2>/dev/null) TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"mode":"SELECTIVE_EXPANSION","via":"autoplan","commit":"'"$COMMIT"'"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"mode":"SELECTIVE_EXPANSION","via":"autoplan","commit":"'"$COMMIT"'"}' -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"issues_found":0,"mode":"FULL_REVIEW","via":"autoplan","commit":"'"$COMMIT"'"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"issues_found":0,"mode":"FULL_REVIEW","via":"autoplan","commit":"'"$COMMIT"'"}' ``` If Phase 2 ran (UI scope): ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"via":"autoplan","commit":"'"$COMMIT"'"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"via":"autoplan","commit":"'"$COMMIT"'"}' ``` Replace field values with actual counts from the review. diff --git a/benchmark/SKILL.md.tmpl b/benchmark/SKILL.md.tmpl index d0c0ecbc3..b3a0d9058 100644 --- a/benchmark/SKILL.md.tmpl +++ b/benchmark/SKILL.md.tmpl @@ -41,7 +41,7 @@ When the user types `/benchmark`, run this skill. ### Phase 1: Setup ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown") +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown") mkdir -p .gstack/benchmark-reports mkdir -p .gstack/benchmark-reports/baselines ``` diff --git a/bin/gstack-global-discover.ts b/bin/gstack-global-discover.ts index e6c64f561..548f153c0 100644 --- a/bin/gstack-global-discover.ts +++ b/bin/gstack-global-discover.ts @@ -175,7 +175,8 @@ function getGitRemote(cwd: string): string | null { // ── Scanners ─────────────────────────────────────────────────────────────── function scanClaudeCode(since: Date): Session[] { - const projectsDir = join(homedir(), ".claude", "projects"); + const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude"); + const projectsDir = join(claudeConfigDir, "projects"); if (!existsSync(projectsDir)) return []; const sessions: Session[] = []; diff --git a/browse/src/find-browse.ts b/browse/src/find-browse.ts index 93c4a26e7..3f7b2474c 100644 --- a/browse/src/find-browse.ts +++ b/browse/src/find-browse.ts @@ -37,7 +37,12 @@ export function locateBinary(): string | null { } } - // Global fallback + // Global fallback — check $CLAUDE_CONFIG_DIR first, then standard locations + const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR; + if (claudeConfigDir) { + const custom = join(claudeConfigDir, 'skills', 'gstack', 'browse', 'dist', 'browse'); + if (existsSync(custom)) return custom; + } for (const m of markers) { const global = join(home, m, 'skills', 'gstack', 'browse', 'dist', 'browse'); if (existsSync(global)) return global; diff --git a/canary/SKILL.md.tmpl b/canary/SKILL.md.tmpl index d0ddadfe8..af61ec5ae 100644 --- a/canary/SKILL.md.tmpl +++ b/canary/SKILL.md.tmpl @@ -42,7 +42,7 @@ When the user types `/canary`, run this skill. ### Phase 1: Setup ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown") +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown") mkdir -p .gstack/canary-reports mkdir -p .gstack/canary-reports/baselines mkdir -p .gstack/canary-reports/screenshots @@ -192,7 +192,7 @@ Save report to `.gstack/canary-reports/{date}-canary.md` and `.gstack/canary-rep Log the result for the review dashboard: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG ``` diff --git a/codex/SKILL.md.tmpl b/codex/SKILL.md.tmpl index 0aa7fec67..397e449b4 100644 --- a/codex/SKILL.md.tmpl +++ b/codex/SKILL.md.tmpl @@ -59,8 +59,8 @@ Parse the user's input to determine which mode to run: C) Something else — I'll provide a prompt ``` - If no diff, check for plan files scoped to the current project: - `ls -t ~/.claude/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1` - If no project-scoped match, fall back to: `ls -t ~/.claude/plans/*.md 2>/dev/null | head -1` + `ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1` + If no project-scoped match, fall back to: `ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | head -1` but warn the user: "Note: this plan may be from a different project." - If a plan file exists, offer to review it - Otherwise, ask: "What would you like to ask Codex?" @@ -126,7 +126,7 @@ CROSS-MODEL ANALYSIS: 7. Persist the review result: ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE","findings":N,"findings_fixed":N}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE","findings":N,"findings_fixed":N}' ``` Substitute: TIMESTAMP (ISO 8601), STATUS ("clean" if PASS, "issues_found" if FAIL), @@ -226,9 +226,9 @@ TMPERR=$(mktemp /tmp/codex-err-XXXXXX.txt) 3. **Plan review auto-detection:** If the user's prompt is about reviewing a plan, or if plan files exist and the user said `/codex` with no arguments: ```bash -ls -t ~/.claude/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1 +ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1 ``` -If no project-scoped match, fall back to `ls -t ~/.claude/plans/*.md 2>/dev/null | head -1` +If no project-scoped match, fall back to `ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | head -1` but warn: "Note: this plan may be from a different project — verify before sending to Codex." Read the plan file and prepend the persona to the user's prompt: "You are a brutally honest technical reviewer. Review this plan for: logical gaps and diff --git a/design-consultation/SKILL.md.tmpl b/design-consultation/SKILL.md.tmpl index ed9a4efae..eed128157 100644 --- a/design-consultation/SKILL.md.tmpl +++ b/design-consultation/SKILL.md.tmpl @@ -52,7 +52,7 @@ ls src/ app/ pages/ components/ 2>/dev/null | head -30 Look for office-hours output: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) ls ~/.gstack/projects/$SLUG/*office-hours* 2>/dev/null | head -5 ls .context/*office-hours* .context/attachments/*office-hours* 2>/dev/null | head -5 ``` diff --git a/design-review/SKILL.md.tmpl b/design-review/SKILL.md.tmpl index 84119c268..77eff9e0d 100644 --- a/design-review/SKILL.md.tmpl +++ b/design-review/SKILL.md.tmpl @@ -220,7 +220,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG ``` Write to `~/.gstack/projects/{slug}/{user}-{branch}-design-audit-{datetime}.md` diff --git a/gstack-upgrade/SKILL.md.tmpl b/gstack-upgrade/SKILL.md.tmpl index ac25894b3..c31ba0e9e 100644 --- a/gstack-upgrade/SKILL.md.tmpl +++ b/gstack-upgrade/SKILL.md.tmpl @@ -26,7 +26,7 @@ First, check if auto-upgrade is enabled: ```bash _AUTO="" [ "${GSTACK_AUTO_UPGRADE:-}" = "1" ] && _AUTO="true" -[ -z "$_AUTO" ] && _AUTO=$(~/.claude/skills/gstack/bin/gstack-config get auto_upgrade 2>/dev/null || true) +[ -z "$_AUTO" ] && _AUTO=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get auto_upgrade 2>/dev/null || true) echo "AUTO_UPGRADE=$_AUTO" ``` @@ -40,7 +40,7 @@ echo "AUTO_UPGRADE=$_AUTO" **If "Always keep me up to date":** ```bash -~/.claude/skills/gstack/bin/gstack-config set auto_upgrade true +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set auto_upgrade true ``` Tell user: "Auto-upgrade enabled. Future updates will install automatically." Then proceed to Step 2. @@ -66,9 +66,9 @@ Tell user the snooze duration: "Next reminder in 24h" (or 48h or 1 week, dependi **If "Never ask again":** ```bash -~/.claude/skills/gstack/bin/gstack-config set update_check false +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set update_check false ``` -Tell user: "Update checks disabled. Run `~/.claude/skills/gstack/bin/gstack-config set update_check true` to re-enable." +Tell user: "Update checks disabled. Run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set update_check true` to re-enable." Continue with the current skill. ### Step 2: Detect install type @@ -205,7 +205,7 @@ When invoked directly as `/gstack-upgrade` (not from a preamble): 1. Force a fresh update check (bypass cache): ```bash -~/.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \ .claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || true ``` Use the output to determine if an upgrade is available. diff --git a/land-and-deploy/SKILL.md.tmpl b/land-and-deploy/SKILL.md.tmpl index 0e84d8596..093a8175d 100644 --- a/land-and-deploy/SKILL.md.tmpl +++ b/land-and-deploy/SKILL.md.tmpl @@ -127,7 +127,7 @@ Collect evidence for each check below. Track warnings (yellow) and blockers (red ### 3.5a: Review staleness check ```bash -~/.claude/skills/gstack/bin/gstack-review-read 2>/dev/null +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read 2>/dev/null ``` Parse the output. For each review skill (plan-eng-review, plan-ceo-review, @@ -332,7 +332,7 @@ First, run the deploy configuration bootstrap to detect or read persisted deploy Then run `gstack-diff-scope` to classify the changes: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-diff-scope $(gh pr view --json baseRefName -q .baseRefName 2>/dev/null || echo main) 2>/dev/null) +eval $(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope $(gh pr view --json baseRefName -q .baseRefName 2>/dev/null || echo main) 2>/dev/null) echo "FRONTEND=$SCOPE_FRONTEND BACKEND=$SCOPE_BACKEND DOCS=$SCOPE_DOCS CONFIG=$SCOPE_CONFIG" ``` @@ -542,7 +542,7 @@ Save report to `.gstack/deploy-reports/{date}-pr{number}-deploy.md`. Log to the review dashboard: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG ``` diff --git a/office-hours/SKILL.md.tmpl b/office-hours/SKILL.md.tmpl index 33d673c17..59856fdc7 100644 --- a/office-hours/SKILL.md.tmpl +++ b/office-hours/SKILL.md.tmpl @@ -39,7 +39,7 @@ You are a **YC office hours partner**. Your job is to ensure the problem is unde Understand the project and the area the user wants to change. ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) ``` 1. Read `CLAUDE.md`, `TODOS.md` (if they exist). @@ -407,7 +407,7 @@ Count the signals. You'll use this count in Phase 6 to determine which tier of c Write the design document to the project directory. ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) ``` diff --git a/plan-ceo-review/SKILL.md.tmpl b/plan-ceo-review/SKILL.md.tmpl index 6b676a862..4b8be4347 100644 --- a/plan-ceo-review/SKILL.md.tmpl +++ b/plan-ceo-review/SKILL.md.tmpl @@ -104,7 +104,7 @@ Then read CLAUDE.md, TODOS.md, and any existing architecture docs. **Design doc check:** ```bash -SLUG=$(~/.claude/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") +SLUG=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-' || echo 'no-branch') DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-$BRANCH-design-*.md 2>/dev/null | head -1) [ -z "$DESIGN" ] && DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1) @@ -298,7 +298,7 @@ Rules: After the opt-in/cherry-pick ceremony, write the plan to disk so the vision and decisions survive beyond this conversation. Only run this step for EXPANSION and SELECTIVE EXPANSION modes. ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG/ceo-plans +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG/ceo-plans ``` Before writing, check for existing CEO plans in the ceo-plans/ directory. If any are >30 days old or their branch has been merged/deleted, offer to archive them: @@ -732,7 +732,7 @@ After producing the Completion Summary, clean up any handoff notes for this bran the review is complete and the context is no longer needed. ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) rm -f ~/.gstack/projects/$SLUG/*-$BRANCH-ceo-handoff-*.md 2>/dev/null || true ``` @@ -747,7 +747,7 @@ the same pattern. The review dashboard depends on this data. Skipping this command breaks the review readiness dashboard in /ship. ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","scope_proposed":N,"scope_accepted":N,"scope_deferred":N,"commit":"COMMIT"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","scope_proposed":N,"scope_accepted":N,"scope_deferred":N,"commit":"COMMIT"}' ``` Before running this command, substitute the placeholder values from the Completion Summary you just produced: diff --git a/plan-design-review/SKILL.md.tmpl b/plan-design-review/SKILL.md.tmpl index 46e5b6f19..d40e1f3f8 100644 --- a/plan-design-review/SKILL.md.tmpl +++ b/plan-design-review/SKILL.md.tmpl @@ -275,7 +275,7 @@ the same pattern. The review dashboard depends on this data. Skipping this command breaks the review readiness dashboard in /ship. ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","initial_score":N,"overall_score":N,"unresolved":N,"decisions_made":N,"commit":"COMMIT"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","initial_score":N,"overall_score":N,"unresolved":N,"decisions_made":N,"commit":"COMMIT"}' ``` Substitute values from the Completion Summary: diff --git a/plan-eng-review/SKILL.md.tmpl b/plan-eng-review/SKILL.md.tmpl index c9ebde44d..3bf0c783c 100644 --- a/plan-eng-review/SKILL.md.tmpl +++ b/plan-eng-review/SKILL.md.tmpl @@ -67,7 +67,7 @@ When evaluating architecture, think "boring by default." When reviewing tests, t ### Design Doc Check ```bash -SLUG=$(~/.claude/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") +SLUG=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-' || echo 'no-branch') DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-$BRANCH-design-*.md 2>/dev/null | head -1) [ -z "$DESIGN" ] && DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1) @@ -242,7 +242,7 @@ the same pattern. The review dashboard depends on this data. Skipping this command breaks the review readiness dashboard in /ship. ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"issues_found":N,"mode":"MODE","commit":"COMMIT"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"issues_found":N,"mode":"MODE","commit":"COMMIT"}' ``` Substitute values from the Completion Summary: diff --git a/qa-only/SKILL.md.tmpl b/qa-only/SKILL.md.tmpl index 293a7b368..138110675 100644 --- a/qa-only/SKILL.md.tmpl +++ b/qa-only/SKILL.md.tmpl @@ -54,7 +54,7 @@ Before falling back to git diff heuristics, check for richer test plan sources: 1. **Project-scoped test plans:** Check `~/.gstack/projects/` for recent `*-test-plan-*.md` files for this repo ```bash - source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) ls -t ~/.gstack/projects/$SLUG/*-test-plan-*.md 2>/dev/null | head -1 ``` 2. **Conversation context:** Check if a prior `/plan-eng-review` or `/plan-ceo-review` produced test plan output in this conversation @@ -74,7 +74,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** Write test outcome artifact for cross-session context: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG ``` Write to `~/.gstack/projects/{slug}/{user}-{branch}-test-outcome-{datetime}.md` diff --git a/qa/SKILL.md.tmpl b/qa/SKILL.md.tmpl index a3d02abcf..de97411d8 100644 --- a/qa/SKILL.md.tmpl +++ b/qa/SKILL.md.tmpl @@ -89,7 +89,7 @@ Before falling back to git diff heuristics, check for richer test plan sources: 1. **Project-scoped test plans:** Check `~/.gstack/projects/` for recent `*-test-plan-*.md` files for this repo ```bash - source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) ls -t ~/.gstack/projects/$SLUG/*-test-plan-*.md 2>/dev/null | head -1 ``` 2. **Conversation context:** Check if a prior `/plan-eng-review` or `/plan-ceo-review` produced test plan output in this conversation @@ -277,7 +277,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** Write test outcome artifact for cross-session context: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG ``` Write to `~/.gstack/projects/{slug}/{user}-{branch}-test-outcome-{datetime}.md` diff --git a/retro/SKILL.md.tmpl b/retro/SKILL.md.tmpl index 082620465..935240edc 100644 --- a/retro/SKILL.md.tmpl +++ b/retro/SKILL.md.tmpl @@ -524,7 +524,7 @@ Locate and run the discovery script using this fallback chain: ```bash DISCOVER_BIN="" -[ -x ~/.claude/skills/gstack/bin/gstack-global-discover ] && DISCOVER_BIN=~/.claude/skills/gstack/bin/gstack-global-discover +[ -x ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-global-discover ] && DISCOVER_BIN=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-global-discover [ -z "$DISCOVER_BIN" ] && [ -x .claude/skills/gstack/bin/gstack-global-discover ] && DISCOVER_BIN=.claude/skills/gstack/bin/gstack-global-discover [ -z "$DISCOVER_BIN" ] && which gstack-global-discover >/dev/null 2>&1 && DISCOVER_BIN=$(which gstack-global-discover) [ -z "$DISCOVER_BIN" ] && [ -f bin/gstack-global-discover.ts ] && DISCOVER_BIN="bun run bin/gstack-global-discover.ts" diff --git a/scripts/gen-skill-docs.ts b/scripts/gen-skill-docs.ts index 00b6263b4..218dd99c6 100644 --- a/scripts/gen-skill-docs.ts +++ b/scripts/gen-skill-docs.ts @@ -39,10 +39,10 @@ interface HostPaths { const HOST_PATHS: Record = { claude: { - skillRoot: '~/.claude/skills/gstack', + skillRoot: '${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack', localSkillRoot: '.claude/skills/gstack', - binDir: '~/.claude/skills/gstack/bin', - browseDir: '~/.claude/skills/gstack/browse/dist', + binDir: '${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin', + browseDir: '${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist', }, codex: { skillRoot: '$GSTACK_ROOT', @@ -492,7 +492,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \\ +\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \\ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \\ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & \`\`\` @@ -511,7 +511,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \\\`\\\`\\\`bash -~/.claude/skills/gstack/bin/gstack-review-read +\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \\\`\\\`\\\` Then write a \`## GSTACK REVIEW REPORT\` section to the end of the plan file: @@ -882,7 +882,7 @@ function generateDesignReviewLite(_ctx: TemplateContext): string { Check if the diff touches frontend files using \`gstack-diff-scope\`: \`\`\`bash -source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) +source <(\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope 2>/dev/null) \`\`\` **If \`SCOPE_FRONTEND=false\`:** Skip design review silently. No output. @@ -905,7 +905,7 @@ source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) 6. **Log the result** for the Review Readiness Dashboard: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' +\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' \`\`\` Substitute: TIMESTAMP = ISO 8601 datetime, STATUS = "clean" if 0 findings or "issues_found", N = total findings, M = auto-fixed count, COMMIT = output of \`git rev-parse --short HEAD\`.`; @@ -1163,7 +1163,7 @@ Compare screenshots and observations across pages for: **Project-scoped:** \`\`\`bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG \`\`\` Write to: \`~/.gstack/projects/{slug}/{user}-{branch}-design-audit-{datetime}.md\` @@ -1252,7 +1252,7 @@ function generateReviewDashboard(_ctx: TemplateContext): string { After completing the review, read the review log and config to display the dashboard. \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, adversarial-review, codex-review). Ignore entries with timestamps older than 7 days. For the Adversarial row, show whichever is more recent between \`adversarial-review\` (new auto-scaled) and \`codex-review\` (legacy). For Design Review, show whichever is more recent between \`plan-design-review\` (full visual audit) and \`design-review-lite\` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: @@ -1759,7 +1759,7 @@ The plan should be complete enough that when implementation begins, every test i After producing the coverage diagram, write a test plan artifact to the project directory so \`/qa\` and \`/qa-only\` can consume it as primary test input: \`\`\`bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) \`\`\` @@ -1823,7 +1823,7 @@ Coverage line: \`Test Coverage Audit: N new code paths. M covered (X%). K tests After producing the coverage diagram, write a test plan artifact so \`/qa\` and \`/qa-only\` can consume it: \`\`\`bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) \`\`\` @@ -2051,7 +2051,7 @@ DIFF_DEL=$(git diff origin/ --stat | tail -1 | grep -oE '[0-9]+ deletion' DIFF_TOTAL=$((DIFF_INS + DIFF_DEL)) which codex 2>/dev/null && echo "CODEX_AVAILABLE" || echo "CODEX_NOT_AVAILABLE" # Respect old opt-out -OLD_CFG=$(~/.claude/skills/gstack/bin/gstack-config get codex_reviews 2>/dev/null || true) +OLD_CFG=$(\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get codex_reviews 2>/dev/null || true) echo "DIFF_SIZE: $DIFF_TOTAL" echo "OLD_CFG: \${OLD_CFG:-not_set}" \`\`\` @@ -2107,7 +2107,7 @@ If the subagent fails or times out: "Claude adversarial subagent unavailable. Co **Persist the review result:** \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"medium","commit":"'"$(git rev-parse --short HEAD)"'"}' +\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"medium","commit":"'"$(git rev-parse --short HEAD)"'"}' \`\`\` Substitute STATUS: "clean" if no findings, "issues_found" if findings exist. SOURCE: "codex" if Codex ran, "claude" if subagent ran. If both failed, do NOT persist. @@ -2150,7 +2150,7 @@ If Codex is not available for steps 1 and 3, note to the user: "Codex CLI not fo **Persist the review result AFTER all passes complete** (not after each sub-step): \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"large","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}' +\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"large","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}' \`\`\` Substitute: STATUS = "clean" if no findings across ALL passes, "issues_found" if any pass found issues. SOURCE = "both" if Codex ran, "claude" if only Claude subagent ran. GATE = the Codex structured review gate result ("pass"/"fail"), or "informational" if Codex was unavailable. If all passes failed, do NOT persist. @@ -2393,6 +2393,8 @@ function processTemplate(tmplPath: string, host: Host = 'claude'): { outputPath: } // Replace remaining hardcoded Claude paths with host-appropriate paths + // Handle both the legacy ~/ form and the new ${CLAUDE_CONFIG_DIR:-$HOME/.claude} form + content = content.replace(/\$\{CLAUDE_CONFIG_DIR:-\$HOME\/\.claude\}\/skills\/gstack/g, ctx.paths.skillRoot); content = content.replace(/~\/\.claude\/skills\/gstack/g, ctx.paths.skillRoot); content = content.replace(/\.claude\/skills\/gstack/g, ctx.paths.localSkillRoot); content = content.replace(/\.claude\/skills\/review/g, '.agents/skills/gstack/review'); diff --git a/setup b/setup index 75dbf7313..63d71145b 100755 --- a/setup +++ b/setup @@ -399,7 +399,8 @@ if [ "$INSTALL_KIRO" -eq 1 ]; then done # Rewrite root SKILL.md paths for Kiro - sed -e "s|~/.claude/skills/gstack|~/.kiro/skills/gstack|g" \ + sed -e 's|${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack|~/.kiro/skills/gstack|g' \ + -e "s|~/.claude/skills/gstack|~/.kiro/skills/gstack|g" \ -e "s|\.claude/skills/gstack|.kiro/skills/gstack|g" \ -e "s|\.claude/skills|.kiro/skills|g" \ "$SOURCE_GSTACK_DIR/SKILL.md" > "$KIRO_GSTACK/SKILL.md" @@ -416,6 +417,7 @@ if [ "$INSTALL_KIRO" -eq 1 ]; then # Rewrite the default GSTACK_ROOT value and any remaining literal paths. sed -e 's|\$HOME/.codex/skills/gstack|$HOME/.kiro/skills/gstack|g' \ -e "s|~/.codex/skills/gstack|~/.kiro/skills/gstack|g" \ + -e 's|${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack|~/.kiro/skills/gstack|g' \ -e "s|~/.claude/skills/gstack|~/.kiro/skills/gstack|g" \ "$skill_dir/SKILL.md" > "$target_dir/SKILL.md" done diff --git a/ship/SKILL.md.tmpl b/ship/SKILL.md.tmpl index bd74c197a..41e498d7b 100644 --- a/ship/SKILL.md.tmpl +++ b/ship/SKILL.md.tmpl @@ -62,7 +62,7 @@ If the Eng Review is NOT "CLEAR": 1. **Check for a prior override on this branch:** ```bash - source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) grep '"skill":"ship-review-override"' ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_OVERRIDE" ``` If an override exists, display the dashboard and note "Review gate previously accepted — continuing." Do NOT ask again. @@ -72,11 +72,11 @@ If the Eng Review is NOT "CLEAR": - RECOMMENDATION: Choose C if the change is obviously trivial (< 20 lines, typo fix, config-only); Choose B for larger changes - Options: A) Ship anyway B) Abort — run /plan-eng-review first C) Change is too small to need eng review - If CEO Review is missing, mention as informational ("CEO Review not run — recommended for product changes") but do NOT block - - For Design Review: run `source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null)`. If `SCOPE_FRONTEND=true` and no design review (plan-design-review or design-review-lite) exists in the dashboard, mention: "Design Review not run — this PR changes frontend code. The lite design check will run automatically in Step 3.5, but consider running /design-review for a full visual audit post-implementation." Still never block. + - For Design Review: run `source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope 2>/dev/null)`. If `SCOPE_FRONTEND=true` and no design review (plan-design-review or design-review-lite) exists in the dashboard, mention: "Design Review not run — this PR changes frontend code. The lite design check will run automatically in Step 3.5, but consider running /design-review for a full visual audit post-implementation." Still never block. 3. **If the user chooses A or C,** persist the decision so future `/ship` runs on this branch skip the gate: ```bash - source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) echo '{"skill":"ship-review-override","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","decision":"USER_CHOICE"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` Substitute USER_CHOICE with "ship_anyway" or "not_relevant". diff --git a/test/gen-skill-docs.test.ts b/test/gen-skill-docs.test.ts index 661e7b99b..3a2a80318 100644 --- a/test/gen-skill-docs.test.ts +++ b/test/gen-skill-docs.test.ts @@ -960,19 +960,23 @@ describe('Codex generation (--host codex)', () => { // ─── Claude output regression guard ───────────────────────── - test('Claude output unchanged: review skill still uses .claude/skills/ paths', () => { + test('Claude output unchanged: review skill uses CLAUDE_CONFIG_DIR-aware paths', () => { // Codex changes must NOT affect Claude output const content = fs.readFileSync(path.join(ROOT, 'review', 'SKILL.md'), 'utf-8'); expect(content).toContain('.claude/skills/review/checklist.md'); - expect(content).toContain('~/.claude/skills/gstack'); + // Claude output now uses ${CLAUDE_CONFIG_DIR:-$HOME/.claude} instead of hardcoded ~/.claude + expect(content).toContain('${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack'); + expect(content).not.toContain('~/.claude/skills/gstack'); // Must NOT contain Codex paths expect(content).not.toContain('.agents/skills'); expect(content).not.toContain('~/.codex/'); }); - test('Claude output unchanged: ship skill still uses .claude/skills/ paths', () => { + test('Claude output unchanged: ship skill uses CLAUDE_CONFIG_DIR-aware paths', () => { const content = fs.readFileSync(path.join(ROOT, 'ship', 'SKILL.md'), 'utf-8'); - expect(content).toContain('~/.claude/skills/gstack'); + // Claude output now uses ${CLAUDE_CONFIG_DIR:-$HOME/.claude} instead of hardcoded ~/.claude + expect(content).toContain('${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack'); + expect(content).not.toContain('~/.claude/skills/gstack'); expect(content).not.toContain('.agents/skills'); expect(content).not.toContain('~/.codex/'); }); From 6ad0e3b47908b658c99cabafdbe156c0cdd95d25 Mon Sep 17 00:00:00 2001 From: Zehua Liu Date: Mon, 23 Mar 2026 14:46:36 +1100 Subject: [PATCH 2/8] regen: regenerate SKILL.md files with CLAUDE_CONFIG_DIR-aware paths All 28 generated SKILL.md files updated from fixed templates and generator. --- SKILL.md | 28 ++++++++++----------- autoplan/SKILL.md | 40 ++++++++++++++--------------- benchmark/SKILL.md | 30 +++++++++++----------- browse/SKILL.md | 28 ++++++++++----------- canary/SKILL.md | 32 +++++++++++------------ codex/SKILL.md | 36 +++++++++++++------------- cso/SKILL.md | 26 +++++++++---------- design-consultation/SKILL.md | 30 +++++++++++----------- design-review/SKILL.md | 32 +++++++++++------------ document-release/SKILL.md | 26 +++++++++---------- gstack-upgrade/SKILL.md | 10 ++++---- investigate/SKILL.md | 26 +++++++++---------- land-and-deploy/SKILL.md | 34 ++++++++++++------------- office-hours/SKILL.md | 32 +++++++++++------------ plan-ceo-review/SKILL.md | 36 +++++++++++++------------- plan-design-review/SKILL.md | 30 +++++++++++----------- plan-eng-review/SKILL.md | 34 ++++++++++++------------- qa-only/SKILL.md | 32 +++++++++++------------ qa/SKILL.md | 32 +++++++++++------------ retro/SKILL.md | 28 ++++++++++----------- review/SKILL.md | 36 +++++++++++++------------- setup-browser-cookies/SKILL.md | 28 ++++++++++----------- setup-deploy/SKILL.md | 26 +++++++++---------- ship/SKILL.md | 46 +++++++++++++++++----------------- 24 files changed, 369 insertions(+), 369 deletions(-) diff --git a/SKILL.md b/SKILL.md index 75ce5b8f2..165db5094 100644 --- a/SKILL.md +++ b/SKILL.md @@ -26,23 +26,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -50,13 +50,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"gstack","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -82,7 +82,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -93,8 +93,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -154,7 +154,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -252,7 +252,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -271,7 +271,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -313,7 +313,7 @@ Auto-shuts down after 30 min idle. State persists between calls (cookies, tabs, _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else diff --git a/autoplan/SKILL.md b/autoplan/SKILL.md index cd9f81d13..914a2d32a 100644 --- a/autoplan/SKILL.md +++ b/autoplan/SKILL.md @@ -27,23 +27,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -51,13 +51,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"autoplan","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -83,7 +83,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -94,8 +94,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -155,7 +155,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -253,7 +253,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -272,7 +272,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -416,7 +416,7 @@ State what you examined and why nothing was flagged (1-2 sentences minimum). Before doing anything, save the plan file's current state to an external file: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') DATETIME=$(date +%Y%m%d-%H%M%S) echo "RESTORE_PATH=$HOME/.gstack/projects/$SLUG/${BRANCH}-autoplan-restore-${DATETIME}.md" @@ -449,9 +449,9 @@ Then prepend a one-line HTML comment to the plan file: ### Step 3: Load skill files from disk Read each file using the Read tool: -- `~/.claude/skills/gstack/plan-ceo-review/SKILL.md` -- `~/.claude/skills/gstack/plan-design-review/SKILL.md` (only if UI scope detected) -- `~/.claude/skills/gstack/plan-eng-review/SKILL.md` +- `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/plan-ceo-review/SKILL.md` +- `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/plan-design-review/SKILL.md` (only if UI scope detected) +- `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/plan-eng-review/SKILL.md` **Section skip list — when following a loaded skill file, SKIP these sections (they are already handled by /autoplan):** @@ -699,14 +699,14 @@ On approval, write 3 separate review log entries so /ship's dashboard recognizes COMMIT=$(git rev-parse --short HEAD 2>/dev/null) TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"mode":"SELECTIVE_EXPANSION","via":"autoplan","commit":"'"$COMMIT"'"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"mode":"SELECTIVE_EXPANSION","via":"autoplan","commit":"'"$COMMIT"'"}' -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"issues_found":0,"mode":"FULL_REVIEW","via":"autoplan","commit":"'"$COMMIT"'"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"issues_found":0,"mode":"FULL_REVIEW","via":"autoplan","commit":"'"$COMMIT"'"}' ``` If Phase 2 ran (UI scope): ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"via":"autoplan","commit":"'"$COMMIT"'"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"via":"autoplan","commit":"'"$COMMIT"'"}' ``` Replace field values with actual counts from the review. diff --git a/benchmark/SKILL.md b/benchmark/SKILL.md index ac12a2801..aa3014269 100644 --- a/benchmark/SKILL.md +++ b/benchmark/SKILL.md @@ -20,23 +20,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -44,13 +44,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"benchmark","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -76,7 +76,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -87,8 +87,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -148,7 +148,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -246,7 +246,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -265,7 +265,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -298,7 +298,7 @@ plan's living status. _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -333,7 +333,7 @@ When the user types `/benchmark`, run this skill. ### Phase 1: Setup ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown") +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown") mkdir -p .gstack/benchmark-reports mkdir -p .gstack/benchmark-reports/baselines ``` diff --git a/browse/SKILL.md b/browse/SKILL.md index 901135fa8..2221c62e7 100644 --- a/browse/SKILL.md +++ b/browse/SKILL.md @@ -20,23 +20,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -44,13 +44,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"browse","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -76,7 +76,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -87,8 +87,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -148,7 +148,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -246,7 +246,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -265,7 +265,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -303,7 +303,7 @@ State persists between calls (cookies, tabs, login sessions). _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else diff --git a/canary/SKILL.md b/canary/SKILL.md index c71d51a9c..43f8af42d 100644 --- a/canary/SKILL.md +++ b/canary/SKILL.md @@ -20,23 +20,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -44,13 +44,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"canary","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -76,7 +76,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -87,8 +87,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -148,7 +148,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -246,7 +246,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -265,7 +265,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -298,7 +298,7 @@ plan's living status. _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -351,7 +351,7 @@ When the user types `/canary`, run this skill. ### Phase 1: Setup ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown") +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown") mkdir -p .gstack/canary-reports mkdir -p .gstack/canary-reports/baselines mkdir -p .gstack/canary-reports/screenshots @@ -501,7 +501,7 @@ Save report to `.gstack/canary-reports/{date}-canary.md` and `.gstack/canary-rep Log the result for the review dashboard: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG ``` diff --git a/codex/SKILL.md b/codex/SKILL.md index 5cad13f05..91889b25d 100644 --- a/codex/SKILL.md +++ b/codex/SKILL.md @@ -21,23 +21,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -45,13 +45,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"codex","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -77,7 +77,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -88,8 +88,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -149,7 +149,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -247,7 +247,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -266,7 +266,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -351,8 +351,8 @@ Parse the user's input to determine which mode to run: C) Something else — I'll provide a prompt ``` - If no diff, check for plan files scoped to the current project: - `ls -t ~/.claude/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1` - If no project-scoped match, fall back to: `ls -t ~/.claude/plans/*.md 2>/dev/null | head -1` + `ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1` + If no project-scoped match, fall back to: `ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | head -1` but warn the user: "Note: this plan may be from a different project." - If a plan file exists, offer to review it - Otherwise, ask: "What would you like to ask Codex?" @@ -418,7 +418,7 @@ CROSS-MODEL ANALYSIS: 7. Persist the review result: ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE","findings":N,"findings_fixed":N}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE","findings":N,"findings_fixed":N}' ``` Substitute: TIMESTAMP (ISO 8601), STATUS ("clean" if PASS, "issues_found" if FAIL), @@ -583,9 +583,9 @@ TMPERR=$(mktemp /tmp/codex-err-XXXXXX.txt) 3. **Plan review auto-detection:** If the user's prompt is about reviewing a plan, or if plan files exist and the user said `/codex` with no arguments: ```bash -ls -t ~/.claude/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1 +ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1 ``` -If no project-scoped match, fall back to `ls -t ~/.claude/plans/*.md 2>/dev/null | head -1` +If no project-scoped match, fall back to `ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | head -1` but warn: "Note: this plan may be from a different project — verify before sending to Codex." Read the plan file and prepend the persona to the user's prompt: "You are a brutally honest technical reviewer. Review this plan for: logical gaps and diff --git a/cso/SKILL.md b/cso/SKILL.md index 741a8f8f2..36cb86fbb 100644 --- a/cso/SKILL.md +++ b/cso/SKILL.md @@ -20,23 +20,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -44,13 +44,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"cso","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -76,7 +76,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -87,8 +87,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -148,7 +148,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -246,7 +246,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -265,7 +265,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: diff --git a/design-consultation/SKILL.md b/design-consultation/SKILL.md index 183913c03..17ad6be55 100644 --- a/design-consultation/SKILL.md +++ b/design-consultation/SKILL.md @@ -25,23 +25,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -49,13 +49,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"design-consultation","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -81,7 +81,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -92,8 +92,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -153,7 +153,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -251,7 +251,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -270,7 +270,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -327,7 +327,7 @@ ls src/ app/ pages/ components/ 2>/dev/null | head -30 Look for office-hours output: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) ls ~/.gstack/projects/$SLUG/*office-hours* 2>/dev/null | head -5 ls .context/*office-hours* .context/attachments/*office-hours* 2>/dev/null | head -5 ``` @@ -344,7 +344,7 @@ If the codebase is empty and purpose is unclear, say: *"I don't have a clear pic _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else diff --git a/design-review/SKILL.md b/design-review/SKILL.md index 34c7b5438..7500f8871 100644 --- a/design-review/SKILL.md +++ b/design-review/SKILL.md @@ -25,23 +25,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -49,13 +49,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"design-review","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -81,7 +81,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -92,8 +92,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -153,7 +153,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -251,7 +251,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -270,7 +270,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -346,7 +346,7 @@ After the user chooses, execute their choice (commit or stash), then continue wi _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -774,7 +774,7 @@ Compare screenshots and observations across pages for: **Project-scoped:** ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG ``` Write to: `~/.gstack/projects/{slug}/{user}-{branch}-design-audit-{datetime}.md` @@ -992,7 +992,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG ``` Write to `~/.gstack/projects/{slug}/{user}-{branch}-design-audit-{datetime}.md` diff --git a/document-release/SKILL.md b/document-release/SKILL.md index 125cfcdfb..966d2797c 100644 --- a/document-release/SKILL.md +++ b/document-release/SKILL.md @@ -22,23 +22,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -46,13 +46,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"document-release","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -78,7 +78,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -89,8 +89,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -150,7 +150,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -248,7 +248,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -267,7 +267,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: diff --git a/gstack-upgrade/SKILL.md b/gstack-upgrade/SKILL.md index f97f11fb7..116593001 100644 --- a/gstack-upgrade/SKILL.md +++ b/gstack-upgrade/SKILL.md @@ -28,7 +28,7 @@ First, check if auto-upgrade is enabled: ```bash _AUTO="" [ "${GSTACK_AUTO_UPGRADE:-}" = "1" ] && _AUTO="true" -[ -z "$_AUTO" ] && _AUTO=$(~/.claude/skills/gstack/bin/gstack-config get auto_upgrade 2>/dev/null || true) +[ -z "$_AUTO" ] && _AUTO=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get auto_upgrade 2>/dev/null || true) echo "AUTO_UPGRADE=$_AUTO" ``` @@ -42,7 +42,7 @@ echo "AUTO_UPGRADE=$_AUTO" **If "Always keep me up to date":** ```bash -~/.claude/skills/gstack/bin/gstack-config set auto_upgrade true +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set auto_upgrade true ``` Tell user: "Auto-upgrade enabled. Future updates will install automatically." Then proceed to Step 2. @@ -68,9 +68,9 @@ Tell user the snooze duration: "Next reminder in 24h" (or 48h or 1 week, dependi **If "Never ask again":** ```bash -~/.claude/skills/gstack/bin/gstack-config set update_check false +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set update_check false ``` -Tell user: "Update checks disabled. Run `~/.claude/skills/gstack/bin/gstack-config set update_check true` to re-enable." +Tell user: "Update checks disabled. Run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set update_check true` to re-enable." Continue with the current skill. ### Step 2: Detect install type @@ -207,7 +207,7 @@ When invoked directly as `/gstack-upgrade` (not from a preamble): 1. Force a fresh update check (bypass cache): ```bash -~/.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \ .claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || true ``` Use the output to determine if an upgrade is available. diff --git a/investigate/SKILL.md b/investigate/SKILL.md index e3055230f..4315c269b 100644 --- a/investigate/SKILL.md +++ b/investigate/SKILL.md @@ -36,23 +36,23 @@ hooks: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -60,13 +60,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"investigate","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -92,7 +92,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -103,8 +103,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -164,7 +164,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -262,7 +262,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -281,7 +281,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: diff --git a/land-and-deploy/SKILL.md b/land-and-deploy/SKILL.md index 25bc5e549..15dcad70d 100644 --- a/land-and-deploy/SKILL.md +++ b/land-and-deploy/SKILL.md @@ -19,23 +19,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -43,13 +43,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"land-and-deploy","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -75,7 +75,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -86,8 +86,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -147,7 +147,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -245,7 +245,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -264,7 +264,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -297,7 +297,7 @@ plan's living status. _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -436,7 +436,7 @@ Collect evidence for each check below. Track warnings (yellow) and blockers (red ### 3.5a: Review staleness check ```bash -~/.claude/skills/gstack/bin/gstack-review-read 2>/dev/null +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read 2>/dev/null ``` Parse the output. For each review skill (plan-eng-review, plan-ceo-review, @@ -673,7 +673,7 @@ If you want to persist deploy settings for future runs, suggest the user run `/s Then run `gstack-diff-scope` to classify the changes: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-diff-scope $(gh pr view --json baseRefName -q .baseRefName 2>/dev/null || echo main) 2>/dev/null) +eval $(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope $(gh pr view --json baseRefName -q .baseRefName 2>/dev/null || echo main) 2>/dev/null) echo "FRONTEND=$SCOPE_FRONTEND BACKEND=$SCOPE_BACKEND DOCS=$SCOPE_DOCS CONFIG=$SCOPE_CONFIG" ``` @@ -883,7 +883,7 @@ Save report to `.gstack/deploy-reports/{date}-pr{number}-deploy.md`. Log to the review dashboard: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG ``` diff --git a/office-hours/SKILL.md b/office-hours/SKILL.md index 47a841a70..6b7723aea 100644 --- a/office-hours/SKILL.md +++ b/office-hours/SKILL.md @@ -27,23 +27,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -51,13 +51,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"office-hours","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -83,7 +83,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -94,8 +94,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -155,7 +155,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -253,7 +253,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -272,7 +272,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -305,7 +305,7 @@ plan's living status. _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -331,7 +331,7 @@ You are a **YC office hours partner**. Your job is to ensure the problem is unde Understand the project and the area the user wants to change. ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) ``` 1. Read `CLAUDE.md`, `TODOS.md` (if they exist). @@ -755,7 +755,7 @@ Count the signals. You'll use this count in Phase 6 to determine which tier of c Write the design document to the project directory. ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) ``` diff --git a/plan-ceo-review/SKILL.md b/plan-ceo-review/SKILL.md index 1050ed4f5..067d1129f 100644 --- a/plan-ceo-review/SKILL.md +++ b/plan-ceo-review/SKILL.md @@ -25,23 +25,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -49,13 +49,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"plan-ceo-review","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -81,7 +81,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -92,8 +92,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -153,7 +153,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -251,7 +251,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -270,7 +270,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -396,7 +396,7 @@ Then read CLAUDE.md, TODOS.md, and any existing architecture docs. **Design doc check:** ```bash -SLUG=$(~/.claude/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") +SLUG=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-' || echo 'no-branch') DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-$BRANCH-design-*.md 2>/dev/null | head -1) [ -z "$DESIGN" ] && DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1) @@ -607,7 +607,7 @@ Rules: After the opt-in/cherry-pick ceremony, write the plan to disk so the vision and decisions survive beyond this conversation. Only run this step for EXPANSION and SELECTIVE EXPANSION modes. ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG/ceo-plans +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG/ceo-plans ``` Before writing, check for existing CEO plans in the ceo-plans/ directory. If any are >30 days old or their branch has been merged/deleted, offer to archive them: @@ -1101,7 +1101,7 @@ After producing the Completion Summary, clean up any handoff notes for this bran the review is complete and the context is no longer needed. ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) rm -f ~/.gstack/projects/$SLUG/*-$BRANCH-ceo-handoff-*.md 2>/dev/null || true ``` @@ -1116,7 +1116,7 @@ the same pattern. The review dashboard depends on this data. Skipping this command breaks the review readiness dashboard in /ship. ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","scope_proposed":N,"scope_accepted":N,"scope_deferred":N,"commit":"COMMIT"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","scope_proposed":N,"scope_accepted":N,"scope_deferred":N,"commit":"COMMIT"}' ``` Before running this command, substitute the placeholder values from the Completion Summary you just produced: @@ -1135,7 +1135,7 @@ Before running this command, substitute the placeholder values from the Completi After completing the review, read the review log and config to display the dashboard. ```bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read ``` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, adversarial-review, codex-review). Ignore entries with timestamps older than 7 days. For the Adversarial row, show whichever is more recent between `adversarial-review` (new auto-scaled) and `codex-review` (legacy). For Design Review, show whichever is more recent between `plan-design-review` (full visual audit) and `design-review-lite` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: diff --git a/plan-design-review/SKILL.md b/plan-design-review/SKILL.md index afd81ff09..d25434c8b 100644 --- a/plan-design-review/SKILL.md +++ b/plan-design-review/SKILL.md @@ -23,23 +23,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -47,13 +47,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"plan-design-review","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -79,7 +79,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -90,8 +90,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -151,7 +151,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -249,7 +249,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -268,7 +268,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -567,7 +567,7 @@ the same pattern. The review dashboard depends on this data. Skipping this command breaks the review readiness dashboard in /ship. ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","initial_score":N,"overall_score":N,"unresolved":N,"decisions_made":N,"commit":"COMMIT"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","initial_score":N,"overall_score":N,"unresolved":N,"decisions_made":N,"commit":"COMMIT"}' ``` Substitute values from the Completion Summary: @@ -584,7 +584,7 @@ Substitute values from the Completion Summary: After completing the review, read the review log and config to display the dashboard. ```bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read ``` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, adversarial-review, codex-review). Ignore entries with timestamps older than 7 days. For the Adversarial row, show whichever is more recent between `adversarial-review` (new auto-scaled) and `codex-review` (legacy). For Design Review, show whichever is more recent between `plan-design-review` (full visual audit) and `design-review-lite` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: diff --git a/plan-eng-review/SKILL.md b/plan-eng-review/SKILL.md index 435d4f09d..91c3be5f1 100644 --- a/plan-eng-review/SKILL.md +++ b/plan-eng-review/SKILL.md @@ -24,23 +24,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -48,13 +48,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"plan-eng-review","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -80,7 +80,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -91,8 +91,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -152,7 +152,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -250,7 +250,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -269,7 +269,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -342,7 +342,7 @@ When evaluating architecture, think "boring by default." When reviewing tests, t ### Design Doc Check ```bash -SLUG=$(~/.claude/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") +SLUG=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-' || echo 'no-branch') DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-$BRANCH-design-*.md 2>/dev/null | head -1) [ -z "$DESIGN" ] && DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1) @@ -611,7 +611,7 @@ The plan should be complete enough that when implementation begins, every test i After producing the coverage diagram, write a test plan artifact to the project directory so `/qa` and `/qa-only` can consume it as primary test input: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) ``` @@ -729,7 +729,7 @@ the same pattern. The review dashboard depends on this data. Skipping this command breaks the review readiness dashboard in /ship. ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"issues_found":N,"mode":"MODE","commit":"COMMIT"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"issues_found":N,"mode":"MODE","commit":"COMMIT"}' ``` Substitute values from the Completion Summary: @@ -746,7 +746,7 @@ Substitute values from the Completion Summary: After completing the review, read the review log and config to display the dashboard. ```bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read ``` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, adversarial-review, codex-review). Ignore entries with timestamps older than 7 days. For the Adversarial row, show whichever is more recent between `adversarial-review` (new auto-scaled) and `codex-review` (legacy). For Design Review, show whichever is more recent between `plan-design-review` (full visual audit) and `design-review-lite` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: diff --git a/qa-only/SKILL.md b/qa-only/SKILL.md index bd7146120..c0a4e0ee1 100644 --- a/qa-only/SKILL.md +++ b/qa-only/SKILL.md @@ -20,23 +20,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -44,13 +44,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"qa-only","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -76,7 +76,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -87,8 +87,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -148,7 +148,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -246,7 +246,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -265,7 +265,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -318,7 +318,7 @@ You are a QA engineer. Test web applications like a real user — click everythi _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -346,7 +346,7 @@ Before falling back to git diff heuristics, check for richer test plan sources: 1. **Project-scoped test plans:** Check `~/.gstack/projects/` for recent `*-test-plan-*.md` files for this repo ```bash - source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) ls -t ~/.gstack/projects/$SLUG/*-test-plan-*.md 2>/dev/null | head -1 ``` 2. **Conversation context:** Check if a prior `/plan-eng-review` or `/plan-ceo-review` produced test plan output in this conversation @@ -642,7 +642,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** Write test outcome artifact for cross-session context: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG ``` Write to `~/.gstack/projects/{slug}/{user}-{branch}-test-outcome-{datetime}.md` diff --git a/qa/SKILL.md b/qa/SKILL.md index d59ba122b..6b1b53450 100644 --- a/qa/SKILL.md +++ b/qa/SKILL.md @@ -26,23 +26,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -50,13 +50,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"qa","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -82,7 +82,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -93,8 +93,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -154,7 +154,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -252,7 +252,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -271,7 +271,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -367,7 +367,7 @@ After the user chooses, execute their choice (commit or stash), then continue wi _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -549,7 +549,7 @@ Before falling back to git diff heuristics, check for richer test plan sources: 1. **Project-scoped test plans:** Check `~/.gstack/projects/` for recent `*-test-plan-*.md` files for this repo ```bash - source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) ls -t ~/.gstack/projects/$SLUG/*-test-plan-*.md 2>/dev/null | head -1 ``` 2. **Conversation context:** Check if a prior `/plan-eng-review` or `/plan-ceo-review` produced test plan output in this conversation @@ -1013,7 +1013,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** Write test outcome artifact for cross-session context: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG ``` Write to `~/.gstack/projects/{slug}/{user}-{branch}-test-outcome-{datetime}.md` diff --git a/retro/SKILL.md b/retro/SKILL.md index 309d2ba10..687f40db3 100644 --- a/retro/SKILL.md +++ b/retro/SKILL.md @@ -20,23 +20,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -44,13 +44,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"retro","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -76,7 +76,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -87,8 +87,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -148,7 +148,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -246,7 +246,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -265,7 +265,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -799,7 +799,7 @@ Locate and run the discovery script using this fallback chain: ```bash DISCOVER_BIN="" -[ -x ~/.claude/skills/gstack/bin/gstack-global-discover ] && DISCOVER_BIN=~/.claude/skills/gstack/bin/gstack-global-discover +[ -x ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-global-discover ] && DISCOVER_BIN=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-global-discover [ -z "$DISCOVER_BIN" ] && [ -x .claude/skills/gstack/bin/gstack-global-discover ] && DISCOVER_BIN=.claude/skills/gstack/bin/gstack-global-discover [ -z "$DISCOVER_BIN" ] && which gstack-global-discover >/dev/null 2>&1 && DISCOVER_BIN=$(which gstack-global-discover) [ -z "$DISCOVER_BIN" ] && [ -f bin/gstack-global-discover.ts ] && DISCOVER_BIN="bun run bin/gstack-global-discover.ts" diff --git a/review/SKILL.md b/review/SKILL.md index 41207076d..d1a240f3a 100644 --- a/review/SKILL.md +++ b/review/SKILL.md @@ -23,23 +23,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -47,13 +47,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"review","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -79,7 +79,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -90,8 +90,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -151,7 +151,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -249,7 +249,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -268,7 +268,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -419,7 +419,7 @@ Follow the output format specified in the checklist. Respect the suppressions Check if the diff touches frontend files using `gstack-diff-scope`: ```bash -source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope 2>/dev/null) ``` **If `SCOPE_FRONTEND=false`:** Skip design review silently. No output. @@ -442,7 +442,7 @@ source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) 6. **Log the result** for the Review Readiness Dashboard: ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' ``` Substitute: TIMESTAMP = ISO 8601 datetime, STATUS = "clean" if 0 findings or "issues_found", N = total findings, M = auto-fixed count, COMMIT = output of `git rev-parse --short HEAD`. @@ -752,7 +752,7 @@ DIFF_DEL=$(git diff origin/ --stat | tail -1 | grep -oE '[0-9]+ deletion' DIFF_TOTAL=$((DIFF_INS + DIFF_DEL)) which codex 2>/dev/null && echo "CODEX_AVAILABLE" || echo "CODEX_NOT_AVAILABLE" # Respect old opt-out -OLD_CFG=$(~/.claude/skills/gstack/bin/gstack-config get codex_reviews 2>/dev/null || true) +OLD_CFG=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get codex_reviews 2>/dev/null || true) echo "DIFF_SIZE: $DIFF_TOTAL" echo "OLD_CFG: ${OLD_CFG:-not_set}" ``` @@ -808,7 +808,7 @@ If the subagent fails or times out: "Claude adversarial subagent unavailable. Co **Persist the review result:** ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"medium","commit":"'"$(git rev-parse --short HEAD)"'"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"medium","commit":"'"$(git rev-parse --short HEAD)"'"}' ``` Substitute STATUS: "clean" if no findings, "issues_found" if findings exist. SOURCE: "codex" if Codex ran, "claude" if subagent ran. If both failed, do NOT persist. @@ -851,7 +851,7 @@ If Codex is not available for steps 1 and 3, note to the user: "Codex CLI not fo **Persist the review result AFTER all passes complete** (not after each sub-step): ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"large","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"large","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}' ``` Substitute: STATUS = "clean" if no findings across ALL passes, "issues_found" if any pass found issues. SOURCE = "both" if Codex ran, "claude" if only Claude subagent ran. GATE = the Codex structured review gate result ("pass"/"fail"), or "informational" if Codex was unavailable. If all passes failed, do NOT persist. diff --git a/setup-browser-cookies/SKILL.md b/setup-browser-cookies/SKILL.md index 3f2986162..a9e135132 100644 --- a/setup-browser-cookies/SKILL.md +++ b/setup-browser-cookies/SKILL.md @@ -17,23 +17,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -41,13 +41,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"setup-browser-cookies","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -73,7 +73,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -84,8 +84,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -145,7 +145,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -243,7 +243,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -262,7 +262,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -310,7 +310,7 @@ Import logged-in sessions from your real Chromium browser into the headless brow _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else diff --git a/setup-deploy/SKILL.md b/setup-deploy/SKILL.md index 33da1addf..6f3deac8b 100644 --- a/setup-deploy/SKILL.md +++ b/setup-deploy/SKILL.md @@ -23,23 +23,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -47,13 +47,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"setup-deploy","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -79,7 +79,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -90,8 +90,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -151,7 +151,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -249,7 +249,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -268,7 +268,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: diff --git a/ship/SKILL.md b/ship/SKILL.md index 1cd1a6e6c..298b6b218 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -21,23 +21,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -45,13 +45,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"ship","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -77,7 +77,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` +If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -88,8 +88,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -149,7 +149,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -247,7 +247,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -~/.claude/skills/gstack/bin/gstack-telemetry-log \ +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -266,7 +266,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -353,7 +353,7 @@ You are running the `/ship` workflow. This is a **non-interactive, fully automat After completing the review, read the review log and config to display the dashboard. ```bash -~/.claude/skills/gstack/bin/gstack-review-read +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read ``` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, adversarial-review, codex-review). Ignore entries with timestamps older than 7 days. For the Adversarial row, show whichever is more recent between `adversarial-review` (new auto-scaled) and `codex-review` (legacy). For Design Review, show whichever is more recent between `plan-design-review` (full visual audit) and `design-review-lite` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: @@ -395,7 +395,7 @@ If the Eng Review is NOT "CLEAR": 1. **Check for a prior override on this branch:** ```bash - source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) grep '"skill":"ship-review-override"' ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_OVERRIDE" ``` If an override exists, display the dashboard and note "Review gate previously accepted — continuing." Do NOT ask again. @@ -405,11 +405,11 @@ If the Eng Review is NOT "CLEAR": - RECOMMENDATION: Choose C if the change is obviously trivial (< 20 lines, typo fix, config-only); Choose B for larger changes - Options: A) Ship anyway B) Abort — run /plan-eng-review first C) Change is too small to need eng review - If CEO Review is missing, mention as informational ("CEO Review not run — recommended for product changes") but do NOT block - - For Design Review: run `source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null)`. If `SCOPE_FRONTEND=true` and no design review (plan-design-review or design-review-lite) exists in the dashboard, mention: "Design Review not run — this PR changes frontend code. The lite design check will run automatically in Step 3.5, but consider running /design-review for a full visual audit post-implementation." Still never block. + - For Design Review: run `source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope 2>/dev/null)`. If `SCOPE_FRONTEND=true` and no design review (plan-design-review or design-review-lite) exists in the dashboard, mention: "Design Review not run — this PR changes frontend code. The lite design check will run automatically in Step 3.5, but consider running /design-review for a full visual audit post-implementation." Still never block. 3. **If the user chooses A or C,** persist the decision so future `/ship` runs on this branch skip the gate: ```bash - source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) echo '{"skill":"ship-review-override","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","decision":"USER_CHOICE"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` Substitute USER_CHOICE with "ship_anyway" or "not_relevant". @@ -969,7 +969,7 @@ Coverage line: `Test Coverage Audit: N new code paths. M covered (X%). K tests g After producing the coverage diagram, write a test plan artifact so `/qa` and `/qa-only` can consume it: ```bash -source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) ``` @@ -1014,7 +1014,7 @@ Review the diff for structural issues that tests don't catch. Check if the diff touches frontend files using `gstack-diff-scope`: ```bash -source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) +source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope 2>/dev/null) ``` **If `SCOPE_FRONTEND=false`:** Skip design review silently. No output. @@ -1037,7 +1037,7 @@ source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) 6. **Log the result** for the Review Readiness Dashboard: ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' ``` Substitute: TIMESTAMP = ISO 8601 datetime, STATUS = "clean" if 0 findings or "issues_found", N = total findings, M = auto-fixed count, COMMIT = output of `git rev-parse --short HEAD`. @@ -1119,7 +1119,7 @@ DIFF_DEL=$(git diff origin/ --stat | tail -1 | grep -oE '[0-9]+ deletion' DIFF_TOTAL=$((DIFF_INS + DIFF_DEL)) which codex 2>/dev/null && echo "CODEX_AVAILABLE" || echo "CODEX_NOT_AVAILABLE" # Respect old opt-out -OLD_CFG=$(~/.claude/skills/gstack/bin/gstack-config get codex_reviews 2>/dev/null || true) +OLD_CFG=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get codex_reviews 2>/dev/null || true) echo "DIFF_SIZE: $DIFF_TOTAL" echo "OLD_CFG: ${OLD_CFG:-not_set}" ``` @@ -1175,7 +1175,7 @@ If the subagent fails or times out: "Claude adversarial subagent unavailable. Co **Persist the review result:** ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"medium","commit":"'"$(git rev-parse --short HEAD)"'"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"medium","commit":"'"$(git rev-parse --short HEAD)"'"}' ``` Substitute STATUS: "clean" if no findings, "issues_found" if findings exist. SOURCE: "codex" if Codex ran, "claude" if subagent ran. If both failed, do NOT persist. @@ -1218,7 +1218,7 @@ If Codex is not available for steps 1 and 3, note to the user: "Codex CLI not fo **Persist the review result AFTER all passes complete** (not after each sub-step): ```bash -~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"large","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}' +${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"large","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}' ``` Substitute: STATUS = "clean" if no findings across ALL passes, "issues_found" if any pass found issues. SOURCE = "both" if Codex ran, "claude" if only Claude subagent ran. GATE = the Codex structured review gate result ("pass"/"fail"), or "informational" if Codex was unavailable. If all passes failed, do NOT persist. From 8af56acc25ecb45998d9df468e0b3d2c04784b71 Mon Sep 17 00:00:00 2001 From: Zehua Liu Date: Mon, 23 Mar 2026 15:23:12 +1100 Subject: [PATCH 3/8] fix: compute claudeDir from CLAUDE_CONFIG_DIR in find-browse globalDirs Instead of a separate early-exit block for CLAUDE_CONFIG_DIR, resolve the claude config directory once (falling back to ~/.claude) and include it as a pre-computed absolute path in the globalDirs array alongside ~/.codex and ~/.agents. Local vendored checks keep using relative markers joined with git root, since those are always at .claude/ inside the repo. Co-Authored-By: Claude Sonnet 4.6 --- browse/src/find-browse.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/browse/src/find-browse.ts b/browse/src/find-browse.ts index 3f7b2474c..d9f6dbbfb 100644 --- a/browse/src/find-browse.ts +++ b/browse/src/find-browse.ts @@ -27,24 +27,23 @@ function getGitRoot(): string | null { export function locateBinary(): string | null { const root = getGitRoot(); const home = homedir(); - const markers = ['.codex', '.agents', '.claude']; + const claudeDir = process.env.CLAUDE_CONFIG_DIR ?? join(home, '.claude'); + // Local vendored copies always live under a relative marker inside the git root. + const localMarkers = ['.codex', '.agents', '.claude']; + // Global dirs are absolute; claudeDir is pre-resolved from CLAUDE_CONFIG_DIR or home. + const globalDirs = [join(home, '.codex'), join(home, '.agents'), claudeDir]; // Workspace-local takes priority (for development) if (root) { - for (const m of markers) { + for (const m of localMarkers) { const local = join(root, m, 'skills', 'gstack', 'browse', 'dist', 'browse'); if (existsSync(local)) return local; } } - // Global fallback — check $CLAUDE_CONFIG_DIR first, then standard locations - const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR; - if (claudeConfigDir) { - const custom = join(claudeConfigDir, 'skills', 'gstack', 'browse', 'dist', 'browse'); - if (existsSync(custom)) return custom; - } - for (const m of markers) { - const global = join(home, m, 'skills', 'gstack', 'browse', 'dist', 'browse'); + // Global fallback + for (const d of globalDirs) { + const global = join(d, 'skills', 'gstack', 'browse', 'dist', 'browse'); if (existsSync(global)) return global; } From 0a5757d706141d62fbc3fb973a7d856cc92abf12 Mon Sep 17 00:00:00 2001 From: Zehua Liu Date: Mon, 23 Mar 2026 15:36:05 +1100 Subject: [PATCH 4/8] fix: use CLAUDE_CONFIG_DIR in gstack-upgrade install detection The global-git and vendored-global install type detection blocks were still using $HOME/.claude instead of ${CLAUDE_CONFIG_DIR:-$HOME/.claude}. Users with a custom CLAUDE_CONFIG_DIR would fail to detect their global gstack installation and get "ERROR: gstack not found" on upgrade. Co-Authored-By: Claude Sonnet 4.6 --- gstack-upgrade/SKILL.md | 8 ++++---- gstack-upgrade/SKILL.md.tmpl | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gstack-upgrade/SKILL.md b/gstack-upgrade/SKILL.md index 116593001..5e400f98e 100644 --- a/gstack-upgrade/SKILL.md +++ b/gstack-upgrade/SKILL.md @@ -76,9 +76,9 @@ Continue with the current skill. ### Step 2: Detect install type ```bash -if [ -d "$HOME/.claude/skills/gstack/.git" ]; then +if [ -d "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/.git" ]; then INSTALL_TYPE="global-git" - INSTALL_DIR="$HOME/.claude/skills/gstack" + INSTALL_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack" elif [ -d "$HOME/.gstack/repos/gstack/.git" ]; then INSTALL_TYPE="global-git" INSTALL_DIR="$HOME/.gstack/repos/gstack" @@ -91,9 +91,9 @@ elif [ -d ".agents/skills/gstack/.git" ]; then elif [ -d ".claude/skills/gstack" ]; then INSTALL_TYPE="vendored" INSTALL_DIR=".claude/skills/gstack" -elif [ -d "$HOME/.claude/skills/gstack" ]; then +elif [ -d "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack" ]; then INSTALL_TYPE="vendored-global" - INSTALL_DIR="$HOME/.claude/skills/gstack" + INSTALL_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack" else echo "ERROR: gstack not found" exit 1 diff --git a/gstack-upgrade/SKILL.md.tmpl b/gstack-upgrade/SKILL.md.tmpl index c31ba0e9e..df23de67a 100644 --- a/gstack-upgrade/SKILL.md.tmpl +++ b/gstack-upgrade/SKILL.md.tmpl @@ -74,9 +74,9 @@ Continue with the current skill. ### Step 2: Detect install type ```bash -if [ -d "$HOME/.claude/skills/gstack/.git" ]; then +if [ -d "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/.git" ]; then INSTALL_TYPE="global-git" - INSTALL_DIR="$HOME/.claude/skills/gstack" + INSTALL_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack" elif [ -d "$HOME/.gstack/repos/gstack/.git" ]; then INSTALL_TYPE="global-git" INSTALL_DIR="$HOME/.gstack/repos/gstack" @@ -89,9 +89,9 @@ elif [ -d ".agents/skills/gstack/.git" ]; then elif [ -d ".claude/skills/gstack" ]; then INSTALL_TYPE="vendored" INSTALL_DIR=".claude/skills/gstack" -elif [ -d "$HOME/.claude/skills/gstack" ]; then +elif [ -d "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack" ]; then INSTALL_TYPE="vendored-global" - INSTALL_DIR="$HOME/.claude/skills/gstack" + INSTALL_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack" else echo "ERROR: gstack not found" exit 1 From 99aab4ff5faef56cd7ba71dfd0d2be2fe6674c8a Mon Sep 17 00:00:00 2001 From: Zehua Liu Date: Mon, 23 Mar 2026 15:59:36 +1100 Subject: [PATCH 5/8] fix: support CLAUDE_CONFIG_DIR via setup-time path substitution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of baking ${CLAUDE_CONFIG_DIR:-$HOME/.claude} into every SKILL.md (producing a massive diff across dozens of files), resolve the path once at install time in setup — the same approach used for Kiro. Changes: - setup: link_claude_skill_dirs now copies SKILL.md with sed substitution (s|~/.claude|$CLAUDE_DIR|g and s|$HOME/.claude|$CLAUDE_DIR|g) and symlinks all other skill assets. Handles old whole-dir symlinks from prior installs. Also rewrites the root gstack SKILL.md when CLAUDE_CONFIG_DIR differs from the default. - browse/src/find-browse.ts: compute claudeDir from CLAUDE_CONFIG_DIR once, use it as a pre-resolved entry in globalDirs (local workspace check keeps relative .claude marker) - bin/gstack-global-discover.ts: resolve projectsDir from CLAUDE_CONFIG_DIR - SKILL.md source files: unchanged (all revert to plain ~/.claude) Co-Authored-By: Claude Sonnet 4.6 --- SKILL.md | 28 +++++++++---------- autoplan/SKILL.md | 40 +++++++++++++-------------- autoplan/SKILL.md.tmpl | 12 ++++----- benchmark/SKILL.md | 30 ++++++++++----------- benchmark/SKILL.md.tmpl | 2 +- browse/SKILL.md | 28 +++++++++---------- canary/SKILL.md | 32 +++++++++++----------- canary/SKILL.md.tmpl | 2 +- codex/SKILL.md | 36 ++++++++++++------------- codex/SKILL.md.tmpl | 10 +++---- cso/SKILL.md | 26 +++++++++--------- design-consultation/SKILL.md | 32 +++++++++++----------- design-review/SKILL.md | 34 +++++++++++------------ document-release/SKILL.md | 26 +++++++++--------- gstack-upgrade/SKILL.md | 18 ++++++------- gstack-upgrade/SKILL.md.tmpl | 18 ++++++------- investigate/SKILL.md | 26 +++++++++--------- land-and-deploy/SKILL.md | 34 +++++++++++------------ land-and-deploy/SKILL.md.tmpl | 4 +-- office-hours/SKILL.md | 32 +++++++++++----------- plan-ceo-review/SKILL.md | 36 ++++++++++++------------- plan-ceo-review/SKILL.md.tmpl | 6 ++--- plan-design-review/SKILL.md | 32 +++++++++++----------- plan-design-review/SKILL.md.tmpl | 2 +- plan-eng-review/SKILL.md | 34 +++++++++++------------ plan-eng-review/SKILL.md.tmpl | 4 +-- qa-only/SKILL.md | 32 +++++++++++----------- qa/SKILL.md | 32 +++++++++++----------- retro/SKILL.md | 28 +++++++++---------- retro/SKILL.md.tmpl | 2 +- review/SKILL.md | 36 ++++++++++++------------- setup | 39 ++++++++++++++++++++++----- setup-browser-cookies/SKILL.md | 28 +++++++++---------- setup-deploy/SKILL.md | 26 +++++++++--------- ship/SKILL.md | 46 ++++++++++++++++---------------- ship/SKILL.md.tmpl | 2 +- test/gen-skill-docs.test.ts | 22 +++++++-------- 37 files changed, 451 insertions(+), 426 deletions(-) diff --git a/SKILL.md b/SKILL.md index 165db5094..75ce5b8f2 100644 --- a/SKILL.md +++ b/SKILL.md @@ -26,23 +26,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -50,13 +50,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"gstack","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -82,7 +82,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -93,8 +93,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -154,7 +154,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -252,7 +252,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -271,7 +271,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -313,7 +313,7 @@ Auto-shuts down after 30 min idle. State persists between calls (cookies, tabs, _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else diff --git a/autoplan/SKILL.md b/autoplan/SKILL.md index 4379bce75..10ba35220 100644 --- a/autoplan/SKILL.md +++ b/autoplan/SKILL.md @@ -27,23 +27,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -51,13 +51,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"autoplan","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -83,7 +83,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -94,8 +94,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -155,7 +155,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -253,7 +253,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -272,7 +272,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -416,7 +416,7 @@ State what you examined and why nothing was flagged (1-2 sentences minimum). Before doing anything, save the plan file's current state to an external file: ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') DATETIME=$(date +%Y%m%d-%H%M%S) echo "RESTORE_PATH=$HOME/.gstack/projects/$SLUG/${BRANCH}-autoplan-restore-${DATETIME}.md" @@ -449,9 +449,9 @@ Then prepend a one-line HTML comment to the plan file: ### Step 3: Load skill files from disk Read each file using the Read tool: -- `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/plan-ceo-review/SKILL.md` -- `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/plan-design-review/SKILL.md` (only if UI scope detected) -- `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/plan-eng-review/SKILL.md` +- `~/.claude/skills/gstack/plan-ceo-review/SKILL.md` +- `~/.claude/skills/gstack/plan-design-review/SKILL.md` (only if UI scope detected) +- `~/.claude/skills/gstack/plan-eng-review/SKILL.md` **Section skip list — when following a loaded skill file, SKIP these sections (they are already handled by /autoplan):** @@ -699,14 +699,14 @@ On approval, write 3 separate review log entries so /ship's dashboard recognizes COMMIT=$(git rev-parse --short HEAD 2>/dev/null) TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"mode":"SELECTIVE_EXPANSION","via":"autoplan","commit":"'"$COMMIT"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"mode":"SELECTIVE_EXPANSION","via":"autoplan","commit":"'"$COMMIT"'"}' -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"issues_found":0,"mode":"FULL_REVIEW","via":"autoplan","commit":"'"$COMMIT"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"issues_found":0,"mode":"FULL_REVIEW","via":"autoplan","commit":"'"$COMMIT"'"}' ``` If Phase 2 ran (UI scope): ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"via":"autoplan","commit":"'"$COMMIT"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"via":"autoplan","commit":"'"$COMMIT"'"}' ``` Replace field values with actual counts from the review. diff --git a/autoplan/SKILL.md.tmpl b/autoplan/SKILL.md.tmpl index 20ee4948d..2213c8b9d 100644 --- a/autoplan/SKILL.md.tmpl +++ b/autoplan/SKILL.md.tmpl @@ -140,9 +140,9 @@ Then prepend a one-line HTML comment to the plan file: ### Step 3: Load skill files from disk Read each file using the Read tool: -- `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/plan-ceo-review/SKILL.md` -- `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/plan-design-review/SKILL.md` (only if UI scope detected) -- `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/plan-eng-review/SKILL.md` +- `~/.claude/skills/gstack/plan-ceo-review/SKILL.md` +- `~/.claude/skills/gstack/plan-design-review/SKILL.md` (only if UI scope detected) +- `~/.claude/skills/gstack/plan-eng-review/SKILL.md` **Section skip list — when following a loaded skill file, SKIP these sections (they are already handled by /autoplan):** @@ -390,14 +390,14 @@ On approval, write 3 separate review log entries so /ship's dashboard recognizes COMMIT=$(git rev-parse --short HEAD 2>/dev/null) TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"mode":"SELECTIVE_EXPANSION","via":"autoplan","commit":"'"$COMMIT"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"mode":"SELECTIVE_EXPANSION","via":"autoplan","commit":"'"$COMMIT"'"}' -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"issues_found":0,"mode":"FULL_REVIEW","via":"autoplan","commit":"'"$COMMIT"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"issues_found":0,"mode":"FULL_REVIEW","via":"autoplan","commit":"'"$COMMIT"'"}' ``` If Phase 2 ran (UI scope): ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"via":"autoplan","commit":"'"$COMMIT"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"via":"autoplan","commit":"'"$COMMIT"'"}' ``` Replace field values with actual counts from the review. diff --git a/benchmark/SKILL.md b/benchmark/SKILL.md index 56dd0a3c7..9e1a6bc34 100644 --- a/benchmark/SKILL.md +++ b/benchmark/SKILL.md @@ -20,23 +20,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -44,13 +44,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"benchmark","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -76,7 +76,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -87,8 +87,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -148,7 +148,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -246,7 +246,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -265,7 +265,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -298,7 +298,7 @@ plan's living status. _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -333,7 +333,7 @@ When the user types `/benchmark`, run this skill. ### Phase 1: Setup ```bash -eval "$({CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown")) +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown")" mkdir -p .gstack/benchmark-reports mkdir -p .gstack/benchmark-reports/baselines ``` diff --git a/benchmark/SKILL.md.tmpl b/benchmark/SKILL.md.tmpl index 0dfdb041a..f72b5a932 100644 --- a/benchmark/SKILL.md.tmpl +++ b/benchmark/SKILL.md.tmpl @@ -41,7 +41,7 @@ When the user types `/benchmark`, run this skill. ### Phase 1: Setup ```bash -eval "$({CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown")) +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown")" mkdir -p .gstack/benchmark-reports mkdir -p .gstack/benchmark-reports/baselines ``` diff --git a/browse/SKILL.md b/browse/SKILL.md index 2221c62e7..901135fa8 100644 --- a/browse/SKILL.md +++ b/browse/SKILL.md @@ -20,23 +20,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -44,13 +44,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"browse","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -76,7 +76,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -87,8 +87,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -148,7 +148,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -246,7 +246,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -265,7 +265,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -303,7 +303,7 @@ State persists between calls (cookies, tabs, login sessions). _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else diff --git a/canary/SKILL.md b/canary/SKILL.md index e118ebfe5..2b2bb4038 100644 --- a/canary/SKILL.md +++ b/canary/SKILL.md @@ -20,23 +20,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -44,13 +44,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"canary","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -76,7 +76,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -87,8 +87,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -148,7 +148,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -246,7 +246,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -265,7 +265,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -298,7 +298,7 @@ plan's living status. _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -351,7 +351,7 @@ When the user types `/canary`, run this skill. ### Phase 1: Setup ```bash -eval "$({CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown")) +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown")" mkdir -p .gstack/canary-reports mkdir -p .gstack/canary-reports/baselines mkdir -p .gstack/canary-reports/screenshots @@ -501,7 +501,7 @@ Save report to `.gstack/canary-reports/{date}-canary.md` and `.gstack/canary-rep Log the result for the review dashboard: ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" mkdir -p ~/.gstack/projects/$SLUG ``` diff --git a/canary/SKILL.md.tmpl b/canary/SKILL.md.tmpl index 1c313d653..eca0fd1f4 100644 --- a/canary/SKILL.md.tmpl +++ b/canary/SKILL.md.tmpl @@ -42,7 +42,7 @@ When the user types `/canary`, run this skill. ### Phase 1: Setup ```bash -eval "$({CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown")) +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null || echo "SLUG=unknown")" mkdir -p .gstack/canary-reports mkdir -p .gstack/canary-reports/baselines mkdir -p .gstack/canary-reports/screenshots diff --git a/codex/SKILL.md b/codex/SKILL.md index 91889b25d..5cad13f05 100644 --- a/codex/SKILL.md +++ b/codex/SKILL.md @@ -21,23 +21,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -45,13 +45,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"codex","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -77,7 +77,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -88,8 +88,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -149,7 +149,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -247,7 +247,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -266,7 +266,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -351,8 +351,8 @@ Parse the user's input to determine which mode to run: C) Something else — I'll provide a prompt ``` - If no diff, check for plan files scoped to the current project: - `ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1` - If no project-scoped match, fall back to: `ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | head -1` + `ls -t ~/.claude/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1` + If no project-scoped match, fall back to: `ls -t ~/.claude/plans/*.md 2>/dev/null | head -1` but warn the user: "Note: this plan may be from a different project." - If a plan file exists, offer to review it - Otherwise, ask: "What would you like to ask Codex?" @@ -418,7 +418,7 @@ CROSS-MODEL ANALYSIS: 7. Persist the review result: ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE","findings":N,"findings_fixed":N}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE","findings":N,"findings_fixed":N}' ``` Substitute: TIMESTAMP (ISO 8601), STATUS ("clean" if PASS, "issues_found" if FAIL), @@ -583,9 +583,9 @@ TMPERR=$(mktemp /tmp/codex-err-XXXXXX.txt) 3. **Plan review auto-detection:** If the user's prompt is about reviewing a plan, or if plan files exist and the user said `/codex` with no arguments: ```bash -ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1 +ls -t ~/.claude/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1 ``` -If no project-scoped match, fall back to `ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | head -1` +If no project-scoped match, fall back to `ls -t ~/.claude/plans/*.md 2>/dev/null | head -1` but warn: "Note: this plan may be from a different project — verify before sending to Codex." Read the plan file and prepend the persona to the user's prompt: "You are a brutally honest technical reviewer. Review this plan for: logical gaps and diff --git a/codex/SKILL.md.tmpl b/codex/SKILL.md.tmpl index 397e449b4..0aa7fec67 100644 --- a/codex/SKILL.md.tmpl +++ b/codex/SKILL.md.tmpl @@ -59,8 +59,8 @@ Parse the user's input to determine which mode to run: C) Something else — I'll provide a prompt ``` - If no diff, check for plan files scoped to the current project: - `ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1` - If no project-scoped match, fall back to: `ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | head -1` + `ls -t ~/.claude/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1` + If no project-scoped match, fall back to: `ls -t ~/.claude/plans/*.md 2>/dev/null | head -1` but warn the user: "Note: this plan may be from a different project." - If a plan file exists, offer to review it - Otherwise, ask: "What would you like to ask Codex?" @@ -126,7 +126,7 @@ CROSS-MODEL ANALYSIS: 7. Persist the review result: ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE","findings":N,"findings_fixed":N}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE","findings":N,"findings_fixed":N}' ``` Substitute: TIMESTAMP (ISO 8601), STATUS ("clean" if PASS, "issues_found" if FAIL), @@ -226,9 +226,9 @@ TMPERR=$(mktemp /tmp/codex-err-XXXXXX.txt) 3. **Plan review auto-detection:** If the user's prompt is about reviewing a plan, or if plan files exist and the user said `/codex` with no arguments: ```bash -ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1 +ls -t ~/.claude/plans/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1 ``` -If no project-scoped match, fall back to `ls -t ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plans/*.md 2>/dev/null | head -1` +If no project-scoped match, fall back to `ls -t ~/.claude/plans/*.md 2>/dev/null | head -1` but warn: "Note: this plan may be from a different project — verify before sending to Codex." Read the plan file and prepend the persona to the user's prompt: "You are a brutally honest technical reviewer. Review this plan for: logical gaps and diff --git a/cso/SKILL.md b/cso/SKILL.md index 36cb86fbb..741a8f8f2 100644 --- a/cso/SKILL.md +++ b/cso/SKILL.md @@ -20,23 +20,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -44,13 +44,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"cso","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -76,7 +76,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -87,8 +87,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -148,7 +148,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -246,7 +246,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -265,7 +265,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: diff --git a/design-consultation/SKILL.md b/design-consultation/SKILL.md index 00908b95f..3e5b18892 100644 --- a/design-consultation/SKILL.md +++ b/design-consultation/SKILL.md @@ -25,23 +25,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -49,13 +49,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"design-consultation","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -81,7 +81,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -92,8 +92,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -153,7 +153,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -251,7 +251,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -270,7 +270,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -327,7 +327,7 @@ ls src/ app/ pages/ components/ 2>/dev/null | head -30 Look for office-hours output: ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" ls ~/.gstack/projects/$SLUG/*office-hours* 2>/dev/null | head -5 ls .context/*office-hours* .context/attachments/*office-hours* 2>/dev/null | head -5 ``` @@ -344,7 +344,7 @@ If the codebase is empty and purpose is unclear, say: *"I don't have a clear pic _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -484,7 +484,7 @@ Present subagent output under a `CLAUDE SUBAGENT (design direction):` header. **Log the result:** ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"design-outside-voices","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","commit":"'"$(git rev-parse --short HEAD)"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"design-outside-voices","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","commit":"'"$(git rev-parse --short HEAD)"'"}' ``` Replace STATUS with "clean" or "issues_found", SOURCE with "codex+subagent", "codex-only", "subagent-only", or "unavailable". diff --git a/design-review/SKILL.md b/design-review/SKILL.md index 4e3d9feeb..a1abf723f 100644 --- a/design-review/SKILL.md +++ b/design-review/SKILL.md @@ -25,23 +25,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -49,13 +49,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"design-review","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -81,7 +81,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -92,8 +92,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -153,7 +153,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -251,7 +251,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -270,7 +270,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -346,7 +346,7 @@ After the user chooses, execute their choice (commit or stash), then continue wi _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -774,7 +774,7 @@ Compare screenshots and observations across pages for: **Project-scoped:** ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG" +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG ``` Write to: `~/.gstack/projects/{slug}/{user}-{branch}-design-audit-{datetime}.md` @@ -1025,7 +1025,7 @@ Merge findings into the triage with `[codex]` / `[subagent]` / `[cross-model]` t **Log the result:** ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"design-outside-voices","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","commit":"'"$(git rev-parse --short HEAD)"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"design-outside-voices","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","commit":"'"$(git rev-parse --short HEAD)"'"}' ``` Replace STATUS with "clean" or "issues_found", SOURCE with "codex+subagent", "codex-only", "subagent-only", or "unavailable". @@ -1142,7 +1142,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG ``` Write to `~/.gstack/projects/{slug}/{user}-{branch}-design-audit-{datetime}.md` diff --git a/document-release/SKILL.md b/document-release/SKILL.md index 966d2797c..125cfcdfb 100644 --- a/document-release/SKILL.md +++ b/document-release/SKILL.md @@ -22,23 +22,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -46,13 +46,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"document-release","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -78,7 +78,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -89,8 +89,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -150,7 +150,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -248,7 +248,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -267,7 +267,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: diff --git a/gstack-upgrade/SKILL.md b/gstack-upgrade/SKILL.md index 5e400f98e..f97f11fb7 100644 --- a/gstack-upgrade/SKILL.md +++ b/gstack-upgrade/SKILL.md @@ -28,7 +28,7 @@ First, check if auto-upgrade is enabled: ```bash _AUTO="" [ "${GSTACK_AUTO_UPGRADE:-}" = "1" ] && _AUTO="true" -[ -z "$_AUTO" ] && _AUTO=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get auto_upgrade 2>/dev/null || true) +[ -z "$_AUTO" ] && _AUTO=$(~/.claude/skills/gstack/bin/gstack-config get auto_upgrade 2>/dev/null || true) echo "AUTO_UPGRADE=$_AUTO" ``` @@ -42,7 +42,7 @@ echo "AUTO_UPGRADE=$_AUTO" **If "Always keep me up to date":** ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set auto_upgrade true +~/.claude/skills/gstack/bin/gstack-config set auto_upgrade true ``` Tell user: "Auto-upgrade enabled. Future updates will install automatically." Then proceed to Step 2. @@ -68,17 +68,17 @@ Tell user the snooze duration: "Next reminder in 24h" (or 48h or 1 week, dependi **If "Never ask again":** ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set update_check false +~/.claude/skills/gstack/bin/gstack-config set update_check false ``` -Tell user: "Update checks disabled. Run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set update_check true` to re-enable." +Tell user: "Update checks disabled. Run `~/.claude/skills/gstack/bin/gstack-config set update_check true` to re-enable." Continue with the current skill. ### Step 2: Detect install type ```bash -if [ -d "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/.git" ]; then +if [ -d "$HOME/.claude/skills/gstack/.git" ]; then INSTALL_TYPE="global-git" - INSTALL_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack" + INSTALL_DIR="$HOME/.claude/skills/gstack" elif [ -d "$HOME/.gstack/repos/gstack/.git" ]; then INSTALL_TYPE="global-git" INSTALL_DIR="$HOME/.gstack/repos/gstack" @@ -91,9 +91,9 @@ elif [ -d ".agents/skills/gstack/.git" ]; then elif [ -d ".claude/skills/gstack" ]; then INSTALL_TYPE="vendored" INSTALL_DIR=".claude/skills/gstack" -elif [ -d "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack" ]; then +elif [ -d "$HOME/.claude/skills/gstack" ]; then INSTALL_TYPE="vendored-global" - INSTALL_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack" + INSTALL_DIR="$HOME/.claude/skills/gstack" else echo "ERROR: gstack not found" exit 1 @@ -207,7 +207,7 @@ When invoked directly as `/gstack-upgrade` (not from a preamble): 1. Force a fresh update check (bypass cache): ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \ +~/.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \ .claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || true ``` Use the output to determine if an upgrade is available. diff --git a/gstack-upgrade/SKILL.md.tmpl b/gstack-upgrade/SKILL.md.tmpl index df23de67a..ac25894b3 100644 --- a/gstack-upgrade/SKILL.md.tmpl +++ b/gstack-upgrade/SKILL.md.tmpl @@ -26,7 +26,7 @@ First, check if auto-upgrade is enabled: ```bash _AUTO="" [ "${GSTACK_AUTO_UPGRADE:-}" = "1" ] && _AUTO="true" -[ -z "$_AUTO" ] && _AUTO=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get auto_upgrade 2>/dev/null || true) +[ -z "$_AUTO" ] && _AUTO=$(~/.claude/skills/gstack/bin/gstack-config get auto_upgrade 2>/dev/null || true) echo "AUTO_UPGRADE=$_AUTO" ``` @@ -40,7 +40,7 @@ echo "AUTO_UPGRADE=$_AUTO" **If "Always keep me up to date":** ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set auto_upgrade true +~/.claude/skills/gstack/bin/gstack-config set auto_upgrade true ``` Tell user: "Auto-upgrade enabled. Future updates will install automatically." Then proceed to Step 2. @@ -66,17 +66,17 @@ Tell user the snooze duration: "Next reminder in 24h" (or 48h or 1 week, dependi **If "Never ask again":** ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set update_check false +~/.claude/skills/gstack/bin/gstack-config set update_check false ``` -Tell user: "Update checks disabled. Run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set update_check true` to re-enable." +Tell user: "Update checks disabled. Run `~/.claude/skills/gstack/bin/gstack-config set update_check true` to re-enable." Continue with the current skill. ### Step 2: Detect install type ```bash -if [ -d "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/.git" ]; then +if [ -d "$HOME/.claude/skills/gstack/.git" ]; then INSTALL_TYPE="global-git" - INSTALL_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack" + INSTALL_DIR="$HOME/.claude/skills/gstack" elif [ -d "$HOME/.gstack/repos/gstack/.git" ]; then INSTALL_TYPE="global-git" INSTALL_DIR="$HOME/.gstack/repos/gstack" @@ -89,9 +89,9 @@ elif [ -d ".agents/skills/gstack/.git" ]; then elif [ -d ".claude/skills/gstack" ]; then INSTALL_TYPE="vendored" INSTALL_DIR=".claude/skills/gstack" -elif [ -d "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack" ]; then +elif [ -d "$HOME/.claude/skills/gstack" ]; then INSTALL_TYPE="vendored-global" - INSTALL_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack" + INSTALL_DIR="$HOME/.claude/skills/gstack" else echo "ERROR: gstack not found" exit 1 @@ -205,7 +205,7 @@ When invoked directly as `/gstack-upgrade` (not from a preamble): 1. Force a fresh update check (bypass cache): ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \ +~/.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \ .claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || true ``` Use the output to determine if an upgrade is available. diff --git a/investigate/SKILL.md b/investigate/SKILL.md index 4315c269b..e3055230f 100644 --- a/investigate/SKILL.md +++ b/investigate/SKILL.md @@ -36,23 +36,23 @@ hooks: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -60,13 +60,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"investigate","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -92,7 +92,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -103,8 +103,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -164,7 +164,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -262,7 +262,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -281,7 +281,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: diff --git a/land-and-deploy/SKILL.md b/land-and-deploy/SKILL.md index 40abf0593..c89e2de0c 100644 --- a/land-and-deploy/SKILL.md +++ b/land-and-deploy/SKILL.md @@ -19,23 +19,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -43,13 +43,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"land-and-deploy","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -75,7 +75,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -86,8 +86,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -147,7 +147,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -245,7 +245,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -264,7 +264,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -297,7 +297,7 @@ plan's living status. _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -436,7 +436,7 @@ Collect evidence for each check below. Track warnings (yellow) and blockers (red ### 3.5a: Review staleness check ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read 2>/dev/null +~/.claude/skills/gstack/bin/gstack-review-read 2>/dev/null ``` Parse the output. For each review skill (plan-eng-review, plan-ceo-review, @@ -673,7 +673,7 @@ If you want to persist deploy settings for future runs, suggest the user run `/s Then run `gstack-diff-scope` to classify the changes: ```bash -eval $(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope $(gh pr view --json baseRefName -q .baseRefName 2>/dev/null || echo main) 2>/dev/null) +eval $(~/.claude/skills/gstack/bin/gstack-diff-scope $(gh pr view --json baseRefName -q .baseRefName 2>/dev/null || echo main) 2>/dev/null) echo "FRONTEND=$SCOPE_FRONTEND BACKEND=$SCOPE_BACKEND DOCS=$SCOPE_DOCS CONFIG=$SCOPE_CONFIG" ``` @@ -883,7 +883,7 @@ Save report to `.gstack/deploy-reports/{date}-pr{number}-deploy.md`. Log to the review dashboard: ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" mkdir -p ~/.gstack/projects/$SLUG ``` diff --git a/land-and-deploy/SKILL.md.tmpl b/land-and-deploy/SKILL.md.tmpl index 1fbba5ccb..af902b9b0 100644 --- a/land-and-deploy/SKILL.md.tmpl +++ b/land-and-deploy/SKILL.md.tmpl @@ -127,7 +127,7 @@ Collect evidence for each check below. Track warnings (yellow) and blockers (red ### 3.5a: Review staleness check ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read 2>/dev/null +~/.claude/skills/gstack/bin/gstack-review-read 2>/dev/null ``` Parse the output. For each review skill (plan-eng-review, plan-ceo-review, @@ -332,7 +332,7 @@ First, run the deploy configuration bootstrap to detect or read persisted deploy Then run `gstack-diff-scope` to classify the changes: ```bash -eval $(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope $(gh pr view --json baseRefName -q .baseRefName 2>/dev/null || echo main) 2>/dev/null) +eval $(~/.claude/skills/gstack/bin/gstack-diff-scope $(gh pr view --json baseRefName -q .baseRefName 2>/dev/null || echo main) 2>/dev/null) echo "FRONTEND=$SCOPE_FRONTEND BACKEND=$SCOPE_BACKEND DOCS=$SCOPE_DOCS CONFIG=$SCOPE_CONFIG" ``` diff --git a/office-hours/SKILL.md b/office-hours/SKILL.md index 4fb15ca7d..417f6be41 100644 --- a/office-hours/SKILL.md +++ b/office-hours/SKILL.md @@ -27,23 +27,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -51,13 +51,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"office-hours","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -83,7 +83,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -94,8 +94,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -155,7 +155,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -253,7 +253,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -272,7 +272,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -305,7 +305,7 @@ plan's living status. _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -331,7 +331,7 @@ You are a **YC office hours partner**. Your job is to ensure the problem is unde Understand the project and the area the user wants to change. ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" ``` 1. Read `CLAUDE.md`, `TODOS.md` (if they exist). @@ -870,7 +870,7 @@ Count the signals. You'll use this count in Phase 6 to determine which tier of c Write the design document to the project directory. ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) ``` diff --git a/plan-ceo-review/SKILL.md b/plan-ceo-review/SKILL.md index 9df431a5c..a9f4f6710 100644 --- a/plan-ceo-review/SKILL.md +++ b/plan-ceo-review/SKILL.md @@ -25,23 +25,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -49,13 +49,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"plan-ceo-review","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -81,7 +81,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -92,8 +92,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -153,7 +153,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -251,7 +251,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -270,7 +270,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -396,7 +396,7 @@ Then read CLAUDE.md, TODOS.md, and any existing architecture docs. **Design doc check:** ```bash -SLUG=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") +SLUG=$(~/.claude/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-' || echo 'no-branch') DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-$BRANCH-design-*.md 2>/dev/null | head -1) [ -z "$DESIGN" ] && DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1) @@ -607,7 +607,7 @@ Rules: After the opt-in/cherry-pick ceremony, write the plan to disk so the vision and decisions survive beyond this conversation. Only run this step for EXPANSION and SELECTIVE EXPANSION modes. ```bash -eval "$({CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG/ceo-plans) +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG/ceo-plans ``` Before writing, check for existing CEO plans in the ceo-plans/ directory. If any are >30 days old or their branch has been merged/deleted, offer to archive them: @@ -1101,7 +1101,7 @@ After producing the Completion Summary, clean up any handoff notes for this bran the review is complete and the context is no longer needed. ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" rm -f ~/.gstack/projects/$SLUG/*-$BRANCH-ceo-handoff-*.md 2>/dev/null || true ``` @@ -1116,7 +1116,7 @@ the same pattern. The review dashboard depends on this data. Skipping this command breaks the review readiness dashboard in /ship. ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","scope_proposed":N,"scope_accepted":N,"scope_deferred":N,"commit":"COMMIT"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","scope_proposed":N,"scope_accepted":N,"scope_deferred":N,"commit":"COMMIT"}' ``` Before running this command, substitute the placeholder values from the Completion Summary you just produced: @@ -1135,7 +1135,7 @@ Before running this command, substitute the placeholder values from the Completi After completing the review, read the review log and config to display the dashboard. ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read ``` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, adversarial-review, codex-review). Ignore entries with timestamps older than 7 days. For the Adversarial row, show whichever is more recent between `adversarial-review` (new auto-scaled) and `codex-review` (legacy). For Design Review, show whichever is more recent between `plan-design-review` (full visual audit) and `design-review-lite` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: diff --git a/plan-ceo-review/SKILL.md.tmpl b/plan-ceo-review/SKILL.md.tmpl index 2868e60f4..a94c9ffe1 100644 --- a/plan-ceo-review/SKILL.md.tmpl +++ b/plan-ceo-review/SKILL.md.tmpl @@ -104,7 +104,7 @@ Then read CLAUDE.md, TODOS.md, and any existing architecture docs. **Design doc check:** ```bash -SLUG=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") +SLUG=$(~/.claude/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-' || echo 'no-branch') DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-$BRANCH-design-*.md 2>/dev/null | head -1) [ -z "$DESIGN" ] && DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1) @@ -298,7 +298,7 @@ Rules: After the opt-in/cherry-pick ceremony, write the plan to disk so the vision and decisions survive beyond this conversation. Only run this step for EXPANSION and SELECTIVE EXPANSION modes. ```bash -eval "$({CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG/ceo-plans) +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG/ceo-plans ``` Before writing, check for existing CEO plans in the ceo-plans/ directory. If any are >30 days old or their branch has been merged/deleted, offer to archive them: @@ -747,7 +747,7 @@ the same pattern. The review dashboard depends on this data. Skipping this command breaks the review readiness dashboard in /ship. ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","scope_proposed":N,"scope_accepted":N,"scope_deferred":N,"commit":"COMMIT"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","scope_proposed":N,"scope_accepted":N,"scope_deferred":N,"commit":"COMMIT"}' ``` Before running this command, substitute the placeholder values from the Completion Summary you just produced: diff --git a/plan-design-review/SKILL.md b/plan-design-review/SKILL.md index 0f262cf43..fb0bbfa2f 100644 --- a/plan-design-review/SKILL.md +++ b/plan-design-review/SKILL.md @@ -23,23 +23,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -47,13 +47,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"plan-design-review","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -79,7 +79,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -90,8 +90,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -151,7 +151,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -249,7 +249,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -268,7 +268,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -523,7 +523,7 @@ Fill in each cell from the Codex and subagent outputs. CONFIRMED = both agree. D **Log the result:** ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"design-outside-voices","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","commit":"'"$(git rev-parse --short HEAD)"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"design-outside-voices","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","commit":"'"$(git rev-parse --short HEAD)"'"}' ``` Replace STATUS with "clean" or "issues_found", SOURCE with "codex+subagent", "codex-only", "subagent-only", or "unavailable". @@ -743,7 +743,7 @@ the same pattern. The review dashboard depends on this data. Skipping this command breaks the review readiness dashboard in /ship. ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","initial_score":N,"overall_score":N,"unresolved":N,"decisions_made":N,"commit":"COMMIT"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","initial_score":N,"overall_score":N,"unresolved":N,"decisions_made":N,"commit":"COMMIT"}' ``` Substitute values from the Completion Summary: @@ -760,7 +760,7 @@ Substitute values from the Completion Summary: After completing the review, read the review log and config to display the dashboard. ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read ``` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, adversarial-review, codex-review). Ignore entries with timestamps older than 7 days. For the Adversarial row, show whichever is more recent between `adversarial-review` (new auto-scaled) and `codex-review` (legacy). For Design Review, show whichever is more recent between `plan-design-review` (full visual audit) and `design-review-lite` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: diff --git a/plan-design-review/SKILL.md.tmpl b/plan-design-review/SKILL.md.tmpl index e009b6c05..30e5b4141 100644 --- a/plan-design-review/SKILL.md.tmpl +++ b/plan-design-review/SKILL.md.tmpl @@ -279,7 +279,7 @@ the same pattern. The review dashboard depends on this data. Skipping this command breaks the review readiness dashboard in /ship. ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","initial_score":N,"overall_score":N,"unresolved":N,"decisions_made":N,"commit":"COMMIT"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","initial_score":N,"overall_score":N,"unresolved":N,"decisions_made":N,"commit":"COMMIT"}' ``` Substitute values from the Completion Summary: diff --git a/plan-eng-review/SKILL.md b/plan-eng-review/SKILL.md index dc18927c6..678d42a3b 100644 --- a/plan-eng-review/SKILL.md +++ b/plan-eng-review/SKILL.md @@ -24,23 +24,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -48,13 +48,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"plan-eng-review","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -80,7 +80,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -91,8 +91,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -152,7 +152,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -250,7 +250,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -269,7 +269,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -342,7 +342,7 @@ When evaluating architecture, think "boring by default." When reviewing tests, t ### Design Doc Check ```bash -SLUG=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") +SLUG=$(~/.claude/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-' || echo 'no-branch') DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-$BRANCH-design-*.md 2>/dev/null | head -1) [ -z "$DESIGN" ] && DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1) @@ -611,7 +611,7 @@ The plan should be complete enough that when implementation begins, every test i After producing the coverage diagram, write a test plan artifact to the project directory so `/qa` and `/qa-only` can consume it as primary test input: ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG" +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) ``` @@ -729,7 +729,7 @@ the same pattern. The review dashboard depends on this data. Skipping this command breaks the review readiness dashboard in /ship. ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"issues_found":N,"mode":"MODE","commit":"COMMIT"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"issues_found":N,"mode":"MODE","commit":"COMMIT"}' ``` Substitute values from the Completion Summary: @@ -746,7 +746,7 @@ Substitute values from the Completion Summary: After completing the review, read the review log and config to display the dashboard. ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read ``` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, adversarial-review, codex-review). Ignore entries with timestamps older than 7 days. For the Adversarial row, show whichever is more recent between `adversarial-review` (new auto-scaled) and `codex-review` (legacy). For Design Review, show whichever is more recent between `plan-design-review` (full visual audit) and `design-review-lite` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: diff --git a/plan-eng-review/SKILL.md.tmpl b/plan-eng-review/SKILL.md.tmpl index 3bf0c783c..c9ebde44d 100644 --- a/plan-eng-review/SKILL.md.tmpl +++ b/plan-eng-review/SKILL.md.tmpl @@ -67,7 +67,7 @@ When evaluating architecture, think "boring by default." When reviewing tests, t ### Design Doc Check ```bash -SLUG=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") +SLUG=$(~/.claude/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)") BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-' || echo 'no-branch') DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-$BRANCH-design-*.md 2>/dev/null | head -1) [ -z "$DESIGN" ] && DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1) @@ -242,7 +242,7 @@ the same pattern. The review dashboard depends on this data. Skipping this command breaks the review readiness dashboard in /ship. ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"issues_found":N,"mode":"MODE","commit":"COMMIT"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"issues_found":N,"mode":"MODE","commit":"COMMIT"}' ``` Substitute values from the Completion Summary: diff --git a/qa-only/SKILL.md b/qa-only/SKILL.md index 6b14ef73c..48a3983cf 100644 --- a/qa-only/SKILL.md +++ b/qa-only/SKILL.md @@ -20,23 +20,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -44,13 +44,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"qa-only","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -76,7 +76,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -87,8 +87,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -148,7 +148,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -246,7 +246,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -265,7 +265,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -318,7 +318,7 @@ You are a QA engineer. Test web applications like a real user — click everythi _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -346,7 +346,7 @@ Before falling back to git diff heuristics, check for richer test plan sources: 1. **Project-scoped test plans:** Check `~/.gstack/projects/` for recent `*-test-plan-*.md` files for this repo ```bash - eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" + eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" ls -t ~/.gstack/projects/$SLUG/*-test-plan-*.md 2>/dev/null | head -1 ``` 2. **Conversation context:** Check if a prior `/plan-eng-review` or `/plan-ceo-review` produced test plan output in this conversation @@ -642,7 +642,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** Write test outcome artifact for cross-session context: ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG ``` Write to `~/.gstack/projects/{slug}/{user}-{branch}-test-outcome-{datetime}.md` diff --git a/qa/SKILL.md b/qa/SKILL.md index d413cebe9..2bd5d305a 100644 --- a/qa/SKILL.md +++ b/qa/SKILL.md @@ -26,23 +26,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -50,13 +50,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"qa","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -82,7 +82,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -93,8 +93,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -154,7 +154,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -252,7 +252,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -271,7 +271,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -367,7 +367,7 @@ After the user chooses, execute their choice (commit or stash), then continue wi _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else @@ -549,7 +549,7 @@ Before falling back to git diff heuristics, check for richer test plan sources: 1. **Project-scoped test plans:** Check `~/.gstack/projects/` for recent `*-test-plan-*.md` files for this repo ```bash - eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" + eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" ls -t ~/.gstack/projects/$SLUG/*-test-plan-*.md 2>/dev/null | head -1 ``` 2. **Conversation context:** Check if a prior `/plan-eng-review` or `/plan-ceo-review` produced test plan output in this conversation @@ -1013,7 +1013,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** Write test outcome artifact for cross-session context: ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG ``` Write to `~/.gstack/projects/{slug}/{user}-{branch}-test-outcome-{datetime}.md` diff --git a/retro/SKILL.md b/retro/SKILL.md index 687f40db3..309d2ba10 100644 --- a/retro/SKILL.md +++ b/retro/SKILL.md @@ -20,23 +20,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -44,13 +44,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"retro","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -76,7 +76,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -87,8 +87,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -148,7 +148,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -246,7 +246,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -265,7 +265,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -799,7 +799,7 @@ Locate and run the discovery script using this fallback chain: ```bash DISCOVER_BIN="" -[ -x ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-global-discover ] && DISCOVER_BIN=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-global-discover +[ -x ~/.claude/skills/gstack/bin/gstack-global-discover ] && DISCOVER_BIN=~/.claude/skills/gstack/bin/gstack-global-discover [ -z "$DISCOVER_BIN" ] && [ -x .claude/skills/gstack/bin/gstack-global-discover ] && DISCOVER_BIN=.claude/skills/gstack/bin/gstack-global-discover [ -z "$DISCOVER_BIN" ] && which gstack-global-discover >/dev/null 2>&1 && DISCOVER_BIN=$(which gstack-global-discover) [ -z "$DISCOVER_BIN" ] && [ -f bin/gstack-global-discover.ts ] && DISCOVER_BIN="bun run bin/gstack-global-discover.ts" diff --git a/retro/SKILL.md.tmpl b/retro/SKILL.md.tmpl index 935240edc..082620465 100644 --- a/retro/SKILL.md.tmpl +++ b/retro/SKILL.md.tmpl @@ -524,7 +524,7 @@ Locate and run the discovery script using this fallback chain: ```bash DISCOVER_BIN="" -[ -x ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-global-discover ] && DISCOVER_BIN=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-global-discover +[ -x ~/.claude/skills/gstack/bin/gstack-global-discover ] && DISCOVER_BIN=~/.claude/skills/gstack/bin/gstack-global-discover [ -z "$DISCOVER_BIN" ] && [ -x .claude/skills/gstack/bin/gstack-global-discover ] && DISCOVER_BIN=.claude/skills/gstack/bin/gstack-global-discover [ -z "$DISCOVER_BIN" ] && which gstack-global-discover >/dev/null 2>&1 && DISCOVER_BIN=$(which gstack-global-discover) [ -z "$DISCOVER_BIN" ] && [ -f bin/gstack-global-discover.ts ] && DISCOVER_BIN="bun run bin/gstack-global-discover.ts" diff --git a/review/SKILL.md b/review/SKILL.md index d8eed77f8..862e78e1b 100644 --- a/review/SKILL.md +++ b/review/SKILL.md @@ -23,23 +23,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -47,13 +47,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"review","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -79,7 +79,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -90,8 +90,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -151,7 +151,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -249,7 +249,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -268,7 +268,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -419,7 +419,7 @@ Follow the output format specified in the checklist. Respect the suppressions Check if the diff touches frontend files using `gstack-diff-scope`: ```bash -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) ``` **If `SCOPE_FRONTEND=false`:** Skip design review silently. No output. @@ -442,7 +442,7 @@ source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope 6. **Log the result** for the Review Readiness Dashboard: ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' ``` Substitute: TIMESTAMP = ISO 8601 datetime, STATUS = "clean" if 0 findings or "issues_found", N = total findings, M = auto-fixed count, COMMIT = output of `git rev-parse --short HEAD`. @@ -774,7 +774,7 @@ DIFF_DEL=$(git diff origin/ --stat | tail -1 | grep -oE '[0-9]+ deletion' DIFF_TOTAL=$((DIFF_INS + DIFF_DEL)) which codex 2>/dev/null && echo "CODEX_AVAILABLE" || echo "CODEX_NOT_AVAILABLE" # Respect old opt-out -OLD_CFG=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get codex_reviews 2>/dev/null || true) +OLD_CFG=$(~/.claude/skills/gstack/bin/gstack-config get codex_reviews 2>/dev/null || true) echo "DIFF_SIZE: $DIFF_TOTAL" echo "OLD_CFG: ${OLD_CFG:-not_set}" ``` @@ -830,7 +830,7 @@ If the subagent fails or times out: "Claude adversarial subagent unavailable. Co **Persist the review result:** ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"medium","commit":"'"$(git rev-parse --short HEAD)"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"medium","commit":"'"$(git rev-parse --short HEAD)"'"}' ``` Substitute STATUS: "clean" if no findings, "issues_found" if findings exist. SOURCE: "codex" if Codex ran, "claude" if subagent ran. If both failed, do NOT persist. @@ -873,7 +873,7 @@ If Codex is not available for steps 1 and 3, note to the user: "Codex CLI not fo **Persist the review result AFTER all passes complete** (not after each sub-step): ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"large","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"large","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}' ``` Substitute: STATUS = "clean" if no findings across ALL passes, "issues_found" if any pass found issues. SOURCE = "both" if Codex ran, "claude" if only Claude subagent ran. GATE = the Codex structured review gate result ("pass"/"fail"), or "informational" if Codex was unavailable. If all passes failed, do NOT persist. diff --git a/setup b/setup index 63d71145b..bf5e22575 100755 --- a/setup +++ b/setup @@ -188,10 +188,13 @@ fi # 3. Ensure ~/.gstack global state directory exists mkdir -p "$HOME/.gstack/projects" -# ─── Helper: link Claude skill subdirectories into a skills parent directory ── +# ─── Helper: install Claude skill subdirectories into a skills parent directory ── +# Copies SKILL.md with ~/.claude path substitution (supports CLAUDE_CONFIG_DIR); +# symlinks all other files so changes to assets are immediately visible. link_claude_skill_dirs() { local gstack_dir="$1" local skills_dir="$2" + local claude_dir="${CLAUDE_CONFIG_DIR:-$HOME/.claude}" local linked=() for skill_dir in "$gstack_dir"/*/; do if [ -f "$skill_dir/SKILL.md" ]; then @@ -199,15 +202,27 @@ link_claude_skill_dirs() { # Skip node_modules [ "$skill_name" = "node_modules" ] && continue target="$skills_dir/$skill_name" - # Create or update symlink; skip if a real file/directory exists - if [ -L "$target" ] || [ ! -e "$target" ]; then - ln -snf "gstack/$skill_name" "$target" - linked+=("$skill_name") - fi + # Remove old whole-dir symlink from previous installs + [ -L "$target" ] && rm -f "$target" + mkdir -p "$target" + # Copy SKILL.md with path substitution (handles both ~/ and $HOME/ forms) + sed -e "s|~/.claude|$claude_dir|g" \ + -e "s|\$HOME/\.claude|$claude_dir|g" \ + "$skill_dir/SKILL.md" > "$target/SKILL.md" + # Symlink all other entries in the skill directory + for item in "$skill_dir"*; do + item_name="$(basename "$item")" + [ "$item_name" = "SKILL.md" ] && continue + dst="$target/$item_name" + if [ -L "$dst" ] || [ ! -e "$dst" ]; then + ln -snf "$item" "$dst" + fi + done + linked+=("$skill_name") fi done if [ ${#linked[@]} -gt 0 ]; then - echo " linked skills: ${linked[*]}" + echo " installed skills: ${linked[*]}" fi } @@ -339,6 +354,16 @@ fi if [ "$INSTALL_CLAUDE" -eq 1 ]; then if [ "$SKILLS_BASENAME" = "skills" ]; then link_claude_skill_dirs "$SOURCE_GSTACK_DIR" "$INSTALL_SKILLS_DIR" + # Also rewrite the root gstack SKILL.md (lives in the gstack dir itself). + # Only needed when CLAUDE_CONFIG_DIR differs from the default ~/.claude; + # writing the processed copy replaces the source file for this install. + _CLAUDE_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}" + if [ "$_CLAUDE_DIR" != "$HOME/.claude" ] && [ -f "$SOURCE_GSTACK_DIR/SKILL.md" ]; then + sed -e "s|~/.claude|$_CLAUDE_DIR|g" \ + -e "s|\$HOME/\.claude|$_CLAUDE_DIR|g" \ + "$SOURCE_GSTACK_DIR/SKILL.md" > "$SOURCE_GSTACK_DIR/SKILL.md.tmp" \ + && mv "$SOURCE_GSTACK_DIR/SKILL.md.tmp" "$SOURCE_GSTACK_DIR/SKILL.md" + fi echo "gstack ready (claude)." echo " browse: $BROWSE_BIN" else diff --git a/setup-browser-cookies/SKILL.md b/setup-browser-cookies/SKILL.md index a9e135132..3f2986162 100644 --- a/setup-browser-cookies/SKILL.md +++ b/setup-browser-cookies/SKILL.md @@ -17,23 +17,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -41,13 +41,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"setup-browser-cookies","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -73,7 +73,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -84,8 +84,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -145,7 +145,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -243,7 +243,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -262,7 +262,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -310,7 +310,7 @@ Import logged-in sessions from your real Chromium browser into the headless brow _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B=${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist/browse +[ -z "$B" ] && B=~/.claude/skills/gstack/browse/dist/browse if [ -x "$B" ]; then echo "READY: $B" else diff --git a/setup-deploy/SKILL.md b/setup-deploy/SKILL.md index 6f3deac8b..33da1addf 100644 --- a/setup-deploy/SKILL.md +++ b/setup-deploy/SKILL.md @@ -23,23 +23,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -47,13 +47,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"setup-deploy","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -79,7 +79,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -90,8 +90,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -151,7 +151,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -249,7 +249,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -268,7 +268,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: diff --git a/ship/SKILL.md b/ship/SKILL.md index 1756f685c..ce3196eaa 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -21,23 +21,23 @@ allowed-tools: ## Preamble (run first) ```bash -_UPD=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) [ -n "$_UPD" ] && echo "$_UPD" || true mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true -_CONTRIB=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) -_PROACTIVE=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" echo "PROACTIVE: $_PROACTIVE" -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true REPO_MODE=${REPO_MODE:-unknown} echo "REPO_MODE: $REPO_MODE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" -_TEL=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") _TEL_START=$(date +%s) _SESSION_ID="$$-$(date +%s)" @@ -45,13 +45,13 @@ echo "TELEMETRY: ${_TEL:-off}" echo "TEL_PROMPTED: $_TEL_PROMPTED" mkdir -p ~/.gstack/analytics echo '{"skill":"ship","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true -for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke them when the user explicitly asks. The user opted out of proactive suggestions. -If output shows `UPGRADE_AVAILABLE `: read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete @@ -77,7 +77,7 @@ Options: - A) Help gstack get better! (recommended) - B) No thanks -If A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry community` +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` If B: ask a follow-up AskUserQuestion: @@ -88,8 +88,8 @@ Options: - A) Sure, anonymous is fine - B) No thanks, fully off -If B→A: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry anonymous` -If B→B: run `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config set telemetry off` +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` Always run: ```bash @@ -149,7 +149,7 @@ Never let a noticed issue silently pass. The whole point is proactive communicat ## Search Before Building -Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/ETHOS.md` for the full philosophy. +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. **Three layers of knowledge:** - **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. @@ -247,7 +247,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \ +~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & ``` @@ -266,7 +266,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \`\`\`bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Then write a `## GSTACK REVIEW REPORT` section to the end of the plan file: @@ -353,7 +353,7 @@ You are running the `/ship` workflow. This is a **non-interactive, fully automat After completing the review, read the review log and config to display the dashboard. ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read ``` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, adversarial-review, codex-review). Ignore entries with timestamps older than 7 days. For the Adversarial row, show whichever is more recent between `adversarial-review` (new auto-scaled) and `codex-review` (legacy). For Design Review, show whichever is more recent between `plan-design-review` (full visual audit) and `design-review-lite` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: @@ -395,7 +395,7 @@ If the Eng Review is NOT "CLEAR": 1. **Check for a prior override on this branch:** ```bash - eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" + eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" grep '"skill":"ship-review-override"' ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_OVERRIDE" ``` If an override exists, display the dashboard and note "Review gate previously accepted — continuing." Do NOT ask again. @@ -405,11 +405,11 @@ If the Eng Review is NOT "CLEAR": - RECOMMENDATION: Choose C if the change is obviously trivial (< 20 lines, typo fix, config-only); Choose B for larger changes - Options: A) Ship anyway B) Abort — run /plan-eng-review first C) Change is too small to need eng review - If CEO Review is missing, mention as informational ("CEO Review not run — recommended for product changes") but do NOT block - - For Design Review: run `source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope 2>/dev/null)`. If `SCOPE_FRONTEND=true` and no design review (plan-design-review or design-review-lite) exists in the dashboard, mention: "Design Review not run — this PR changes frontend code. The lite design check will run automatically in Step 3.5, but consider running /design-review for a full visual audit post-implementation." Still never block. + - For Design Review: run `source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null)`. If `SCOPE_FRONTEND=true` and no design review (plan-design-review or design-review-lite) exists in the dashboard, mention: "Design Review not run — this PR changes frontend code. The lite design check will run automatically in Step 3.5, but consider running /design-review for a full visual audit post-implementation." Still never block. 3. **If the user chooses A or C,** persist the decision so future `/ship` runs on this branch skip the gate: ```bash - eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null)" + eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" echo '{"skill":"ship-review-override","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","decision":"USER_CHOICE"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` Substitute USER_CHOICE with "ship_anyway" or "not_relevant". @@ -969,7 +969,7 @@ Coverage line: `Test Coverage Audit: N new code paths. M covered (X%). K tests g After producing the coverage diagram, write a test plan artifact so `/qa` and `/qa-only` can consume it: ```bash -eval "$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG" +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) ``` @@ -1014,7 +1014,7 @@ Review the diff for structural issues that tests don't catch. Check if the diff touches frontend files using `gstack-diff-scope`: ```bash -source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) ``` **If `SCOPE_FRONTEND=false`:** Skip design review silently. No output. @@ -1037,7 +1037,7 @@ source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope 6. **Log the result** for the Review Readiness Dashboard: ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' ``` Substitute: TIMESTAMP = ISO 8601 datetime, STATUS = "clean" if 0 findings or "issues_found", N = total findings, M = auto-fixed count, COMMIT = output of `git rev-parse --short HEAD`. @@ -1141,7 +1141,7 @@ DIFF_DEL=$(git diff origin/ --stat | tail -1 | grep -oE '[0-9]+ deletion' DIFF_TOTAL=$((DIFF_INS + DIFF_DEL)) which codex 2>/dev/null && echo "CODEX_AVAILABLE" || echo "CODEX_NOT_AVAILABLE" # Respect old opt-out -OLD_CFG=$(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get codex_reviews 2>/dev/null || true) +OLD_CFG=$(~/.claude/skills/gstack/bin/gstack-config get codex_reviews 2>/dev/null || true) echo "DIFF_SIZE: $DIFF_TOTAL" echo "OLD_CFG: ${OLD_CFG:-not_set}" ``` @@ -1197,7 +1197,7 @@ If the subagent fails or times out: "Claude adversarial subagent unavailable. Co **Persist the review result:** ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"medium","commit":"'"$(git rev-parse --short HEAD)"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"medium","commit":"'"$(git rev-parse --short HEAD)"'"}' ``` Substitute STATUS: "clean" if no findings, "issues_found" if findings exist. SOURCE: "codex" if Codex ran, "claude" if subagent ran. If both failed, do NOT persist. @@ -1240,7 +1240,7 @@ If Codex is not available for steps 1 and 3, note to the user: "Codex CLI not fo **Persist the review result AFTER all passes complete** (not after each sub-step): ```bash -${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"large","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"large","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}' ``` Substitute: STATUS = "clean" if no findings across ALL passes, "issues_found" if any pass found issues. SOURCE = "both" if Codex ran, "claude" if only Claude subagent ran. GATE = the Codex structured review gate result ("pass"/"fail"), or "informational" if Codex was unavailable. If all passes failed, do NOT persist. diff --git a/ship/SKILL.md.tmpl b/ship/SKILL.md.tmpl index b268020bc..0308dd8be 100644 --- a/ship/SKILL.md.tmpl +++ b/ship/SKILL.md.tmpl @@ -72,7 +72,7 @@ If the Eng Review is NOT "CLEAR": - RECOMMENDATION: Choose C if the change is obviously trivial (< 20 lines, typo fix, config-only); Choose B for larger changes - Options: A) Ship anyway B) Abort — run /plan-eng-review first C) Change is too small to need eng review - If CEO Review is missing, mention as informational ("CEO Review not run — recommended for product changes") but do NOT block - - For Design Review: run `source <(${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-diff-scope 2>/dev/null)`. If `SCOPE_FRONTEND=true` and no design review (plan-design-review or design-review-lite) exists in the dashboard, mention: "Design Review not run — this PR changes frontend code. The lite design check will run automatically in Step 3.5, but consider running /design-review for a full visual audit post-implementation." Still never block. + - For Design Review: run `source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null)`. If `SCOPE_FRONTEND=true` and no design review (plan-design-review or design-review-lite) exists in the dashboard, mention: "Design Review not run — this PR changes frontend code. The lite design check will run automatically in Step 3.5, but consider running /design-review for a full visual audit post-implementation." Still never block. 3. **If the user chooses A or C,** persist the decision so future `/ship` runs on this branch skip the gate: ```bash diff --git a/test/gen-skill-docs.test.ts b/test/gen-skill-docs.test.ts index f69d7e44c..c8a52b8b9 100644 --- a/test/gen-skill-docs.test.ts +++ b/test/gen-skill-docs.test.ts @@ -1119,23 +1119,19 @@ describe('Codex generation (--host codex)', () => { // ─── Claude output regression guard ───────────────────────── - test('Claude output unchanged: review skill uses CLAUDE_CONFIG_DIR-aware paths', () => { + test('Claude output unchanged: review skill uses ~/.claude paths', () => { // Codex changes must NOT affect Claude output const content = fs.readFileSync(path.join(ROOT, 'review', 'SKILL.md'), 'utf-8'); expect(content).toContain('.claude/skills/review/checklist.md'); - // Claude output now uses ${CLAUDE_CONFIG_DIR:-$HOME/.claude} instead of hardcoded ~/.claude - expect(content).toContain('${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack'); - expect(content).not.toContain('~/.claude/skills/gstack'); + expect(content).toContain('~/.claude/skills/gstack'); // Must NOT contain Codex paths expect(content).not.toContain('.agents/skills'); expect(content).not.toContain('~/.codex/'); }); - test('Claude output unchanged: ship skill uses CLAUDE_CONFIG_DIR-aware paths', () => { + test('Claude output unchanged: ship skill uses ~/.claude paths', () => { const content = fs.readFileSync(path.join(ROOT, 'ship', 'SKILL.md'), 'utf-8'); - // Claude output now uses ${CLAUDE_CONFIG_DIR:-$HOME/.claude} instead of hardcoded ~/.claude - expect(content).toContain('${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack'); - expect(content).not.toContain('~/.claude/skills/gstack'); + expect(content).toContain('~/.claude/skills/gstack'); expect(content).not.toContain('.agents/skills'); expect(content).not.toContain('~/.codex/'); }); @@ -1231,12 +1227,16 @@ describe('setup script validation', () => { expect(fnBody).toContain('gstack*'); }); - test('link_claude_skill_dirs creates relative symlinks', () => { - // Claude links should be relative: ln -snf "gstack/skill_name" + test('link_claude_skill_dirs copies SKILL.md with path substitution', () => { const fnStart = setupContent.indexOf('link_claude_skill_dirs()'); const fnEnd = setupContent.indexOf('}', setupContent.indexOf('linked[@]}', fnStart)); const fnBody = setupContent.slice(fnStart, fnEnd); - expect(fnBody).toContain('ln -snf "gstack/$skill_name"'); + // Copies SKILL.md with sed substitution for CLAUDE_CONFIG_DIR support + expect(fnBody).toContain('sed -e'); + expect(fnBody).toContain('~/.claude'); + expect(fnBody).toContain('SKILL.md'); + // Symlinks non-SKILL.md entries + expect(fnBody).toContain('ln -snf'); }); test('setup supports --host auto|claude|codex|kiro', () => { From bc1541acd56c6836ec21865d4c68146daf5aa5ad Mon Sep 17 00:00:00 2001 From: Zehua Liu Date: Mon, 23 Mar 2026 16:25:00 +1100 Subject: [PATCH 6/8] test: add CLAUDE_CONFIG_DIR coverage for setup substitution and binary discovery - link_claude_skill_dirs functional test: runs the actual bash function in a temp dir with CLAUDE_CONFIG_DIR set to a custom path, verifies the installed SKILL.md contains the custom path and not ~/.claude - locateBinary unit tests: verifies find-browse respects CLAUDE_CONFIG_DIR for global binary lookup (plants a fake binary under custom dir), and falls back to homedir when CLAUDE_CONFIG_DIR is unset Co-Authored-By: Claude Sonnet 4.6 --- test/gen-skill-docs.test.ts | 35 +++++++++++++++++++++++++ test/global-discover.test.ts | 50 +++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/test/gen-skill-docs.test.ts b/test/gen-skill-docs.test.ts index c8a52b8b9..e84dea47c 100644 --- a/test/gen-skill-docs.test.ts +++ b/test/gen-skill-docs.test.ts @@ -1239,6 +1239,41 @@ describe('setup script validation', () => { expect(fnBody).toContain('ln -snf'); }); + test('link_claude_skill_dirs substitutes CLAUDE_CONFIG_DIR into installed SKILL.md', () => { + // Functional test: run the actual bash function in a temp dir and verify the + // SKILL.md written to the skills dir contains the custom path, not ~/.claude. + const tmp = fs.mkdtempSync(path.join(require('os').tmpdir(), 'gstack-test-')); + try { + // Create a fake skill dir with a SKILL.md that references ~/.claude + const fakeSkill = path.join(tmp, 'gstack', 'fake-skill'); + const fakeSkillsDir = path.join(tmp, 'skills'); + fs.mkdirSync(fakeSkill, { recursive: true }); + fs.mkdirSync(fakeSkillsDir, { recursive: true }); + fs.writeFileSync(path.join(fakeSkill, 'SKILL.md'), + 'run ~/.claude/skills/gstack/bin/gstack-config\n'); + + // Extract and run link_claude_skill_dirs from setup with CLAUDE_CONFIG_DIR set + const fnStart = setupContent.indexOf('link_claude_skill_dirs()'); + const fnEnd = setupContent.indexOf('\n}', setupContent.indexOf('linked[@]}', fnStart)) + 2; + const fnBody = setupContent.slice(fnStart, fnEnd); + + const customDir = path.join(tmp, 'custom-claude'); + const script = `${fnBody}\nlink_claude_skill_dirs "${path.join(tmp, 'gstack')}" "${fakeSkillsDir}"`; + const result = Bun.spawnSync(['bash', '-c', script], { + env: { ...process.env, CLAUDE_CONFIG_DIR: customDir, HOME: process.env.HOME ?? '/tmp' }, + stdout: 'pipe', stderr: 'pipe', + }); + + const installed = path.join(fakeSkillsDir, 'fake-skill', 'SKILL.md'); + expect(fs.existsSync(installed)).toBe(true); + const content = fs.readFileSync(installed, 'utf-8'); + expect(content).toContain(customDir); + expect(content).not.toContain('~/.claude'); + } finally { + fs.rmSync(tmp, { recursive: true, force: true }); + } + }); + test('setup supports --host auto|claude|codex|kiro', () => { expect(setupContent).toContain('--host'); expect(setupContent).toContain('claude|codex|kiro|auto'); diff --git a/test/global-discover.test.ts b/test/global-discover.test.ts index c8d489f4a..81bedfa2b 100644 --- a/test/global-discover.test.ts +++ b/test/global-discover.test.ts @@ -1,7 +1,7 @@ import { describe, test, expect, beforeEach, afterEach } from "bun:test"; import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync } from "fs"; import { join } from "path"; -import { tmpdir } from "os"; +import { tmpdir, homedir } from "os"; import { spawnSync } from "child_process"; // Import normalizeRemoteUrl for unit testing @@ -185,3 +185,51 @@ describe("gstack-global-discover", () => { }); }); }); + +describe("find-browse locateBinary", () => { + let locateBinary: () => string | null; + + beforeEach(async () => { + const mod = await import("../browse/src/find-browse.ts"); + locateBinary = mod.locateBinary; + }); + + test("respects CLAUDE_CONFIG_DIR for global binary lookup", () => { + const tmp = mkdtempSync(join(tmpdir(), "gstack-find-browse-")); + try { + // Plant a fake browse binary under a custom CLAUDE_CONFIG_DIR + const customDir = join(tmp, "custom-claude"); + const binPath = join(customDir, "skills", "gstack", "browse", "dist", "browse"); + mkdirSync(join(customDir, "skills", "gstack", "browse", "dist"), { recursive: true }); + writeFileSync(binPath, "#!/bin/sh\necho browse", { mode: 0o755 }); + + const originalEnv = process.env.CLAUDE_CONFIG_DIR; + process.env.CLAUDE_CONFIG_DIR = customDir; + try { + const result = locateBinary(); + expect(result).toBe(binPath); + } finally { + if (originalEnv === undefined) delete process.env.CLAUDE_CONFIG_DIR; + else process.env.CLAUDE_CONFIG_DIR = originalEnv; + } + } finally { + rmSync(tmp, { recursive: true, force: true }); + } + }); + + test("falls back to ~/.claude when CLAUDE_CONFIG_DIR is unset", () => { + // When CLAUDE_CONFIG_DIR is not set, the default ~/.claude path is used. + // We can't plant a binary there in tests, so just verify no crash and + // the result (if any) is under homedir(). + const originalEnv = process.env.CLAUDE_CONFIG_DIR; + delete process.env.CLAUDE_CONFIG_DIR; + try { + const result = locateBinary(); + if (result !== null) { + expect(result).toContain(homedir()); + } + } finally { + if (originalEnv !== undefined) process.env.CLAUDE_CONFIG_DIR = originalEnv; + } + }); +}); From 4830631fcc76ab35b60fcd0f858af9b3c000c06f Mon Sep 17 00:00:00 2001 From: Zehua Liu Date: Mon, 23 Mar 2026 16:55:14 +1100 Subject: [PATCH 7/8] =?UTF-8?q?fix:=20revert=20gen-skill-docs=20to=20~/.cl?= =?UTF-8?q?aude=20paths=20=E2=80=94=20setup=20substitutes=20at=20install?= =?UTF-8?q?=20time?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous approach baked \${CLAUDE_CONFIG_DIR:-\$HOME/.claude} into gen-skill-docs.ts HOST_PATHS, causing SKILL.md templates to emit that bash variable. But SKILL.md files are prose docs, not bash scripts, so they should not contain bash-only syntax. The correct architecture: source files and templates keep \`~/.claude\`; the setup script substitutes the literal resolved path at install time when CLAUDE_CONFIG_DIR is set. This also fixes the CI skill-docs freshness check, which failed because the committed SKILL.md files had \`~/.claude\` but gen-skill-docs was generating \${CLAUDE_CONFIG_DIR...}. Co-Authored-By: Claude Sonnet 4.6 --- scripts/gen-skill-docs.ts | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/scripts/gen-skill-docs.ts b/scripts/gen-skill-docs.ts index 0e2f99a2a..c728dfae8 100644 --- a/scripts/gen-skill-docs.ts +++ b/scripts/gen-skill-docs.ts @@ -39,10 +39,10 @@ interface HostPaths { const HOST_PATHS: Record = { claude: { - skillRoot: '${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack', + skillRoot: '~/.claude/skills/gstack', localSkillRoot: '.claude/skills/gstack', - binDir: '${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin', - browseDir: '${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/browse/dist', + binDir: '~/.claude/skills/gstack/bin', + browseDir: '~/.claude/skills/gstack/browse/dist', }, codex: { skillRoot: '$GSTACK_ROOT', @@ -530,7 +530,7 @@ Run this bash: _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true -\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-telemetry-log \\ +~/.claude/skills/gstack/bin/gstack-telemetry-log \\ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \\ --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & \`\`\` @@ -549,7 +549,7 @@ When you are in plan mode and about to call ExitPlanMode: 3. If it does NOT — run this command: \\\`\\\`\\\`bash -\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \\\`\\\`\\\` Then write a \`## GSTACK REVIEW REPORT\` section to the end of the plan file: @@ -1219,7 +1219,7 @@ Compare screenshots and observations across pages for: **Project-scoped:** \`\`\`bash -eval "$(\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG" +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG \`\`\` Write to: \`~/.gstack/projects/{slug}/{user}-{branch}-design-audit-{datetime}.md\` @@ -1308,7 +1308,7 @@ function generateReviewDashboard(_ctx: TemplateContext): string { After completing the review, read the review log and config to display the dashboard. \`\`\`bash -\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-read +~/.claude/skills/gstack/bin/gstack-review-read \`\`\` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, adversarial-review, codex-review). Ignore entries with timestamps older than 7 days. For the Adversarial row, show whichever is more recent between \`adversarial-review\` (new auto-scaled) and \`codex-review\` (legacy). For Design Review, show whichever is more recent between \`plan-design-review\` (full visual audit) and \`design-review-lite\` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: @@ -1815,7 +1815,7 @@ The plan should be complete enough that when implementation begins, every test i After producing the coverage diagram, write a test plan artifact to the project directory so \`/qa\` and \`/qa-only\` can consume it as primary test input: \`\`\`bash -eval "$(\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG" +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) \`\`\` @@ -1879,7 +1879,7 @@ Coverage line: \`Test Coverage Audit: N new code paths. M covered (X%). K tests After producing the coverage diagram, write a test plan artifact so \`/qa\` and \`/qa-only\` can consume it: \`\`\`bash -eval "$(\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG" +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) \`\`\` @@ -2223,7 +2223,7 @@ DIFF_DEL=$(git diff origin/ --stat | tail -1 | grep -oE '[0-9]+ deletion' DIFF_TOTAL=$((DIFF_INS + DIFF_DEL)) which codex 2>/dev/null && echo "CODEX_AVAILABLE" || echo "CODEX_NOT_AVAILABLE" # Respect old opt-out -OLD_CFG=$(\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-config get codex_reviews 2>/dev/null || true) +OLD_CFG=$(~/.claude/skills/gstack/bin/gstack-config get codex_reviews 2>/dev/null || true) echo "DIFF_SIZE: $DIFF_TOTAL" echo "OLD_CFG: \${OLD_CFG:-not_set}" \`\`\` @@ -2279,7 +2279,7 @@ If the subagent fails or times out: "Claude adversarial subagent unavailable. Co **Persist the review result:** \`\`\`bash -\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"medium","commit":"'"$(git rev-parse --short HEAD)"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"medium","commit":"'"$(git rev-parse --short HEAD)"'"}' \`\`\` Substitute STATUS: "clean" if no findings, "issues_found" if findings exist. SOURCE: "codex" if Codex ran, "claude" if subagent ran. If both failed, do NOT persist. @@ -2322,7 +2322,7 @@ If Codex is not available for steps 1 and 3, note to the user: "Codex CLI not fo **Persist the review result AFTER all passes complete** (not after each sub-step): \`\`\`bash -\${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"large","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}' +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","tier":"large","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}' \`\`\` Substitute: STATUS = "clean" if no findings across ALL passes, "issues_found" if any pass found issues. SOURCE = "both" if Codex ran, "claude" if only Claude subagent ran. GATE = the Codex structured review gate result ("pass"/"fail"), or "informational" if Codex was unavailable. If all passes failed, do NOT persist. @@ -2823,8 +2823,6 @@ function processTemplate(tmplPath: string, host: Host = 'claude'): { outputPath: } // Replace remaining hardcoded Claude paths with host-appropriate paths - // Handle both the legacy ~/ form and the new ${CLAUDE_CONFIG_DIR:-$HOME/.claude} form - content = content.replace(/\$\{CLAUDE_CONFIG_DIR:-\$HOME\/\.claude\}\/skills\/gstack/g, ctx.paths.skillRoot); content = content.replace(/~\/\.claude\/skills\/gstack/g, ctx.paths.skillRoot); content = content.replace(/\.claude\/skills\/gstack/g, ctx.paths.localSkillRoot); content = content.replace(/\.claude\/skills\/review/g, '.agents/skills/gstack/review'); From b39412818e7830afa5defb9c2479567b79de2a10 Mon Sep 17 00:00:00 2001 From: Zehua Liu Date: Mon, 23 Mar 2026 16:56:00 +1100 Subject: [PATCH 8/8] fix: only substitute CLAUDE_CONFIG_DIR in setup when actually set Co-Authored-By: Claude Sonnet 4.6 --- setup | 19 +++++++++++++------ test/gen-skill-docs.test.ts | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/setup b/setup index bf5e22575..779d89644 100755 --- a/setup +++ b/setup @@ -189,8 +189,9 @@ fi mkdir -p "$HOME/.gstack/projects" # ─── Helper: install Claude skill subdirectories into a skills parent directory ── -# Copies SKILL.md with ~/.claude path substitution (supports CLAUDE_CONFIG_DIR); -# symlinks all other files so changes to assets are immediately visible. +# Copies SKILL.md with ~/.claude path substitution when CLAUDE_CONFIG_DIR is set; +# otherwise copies as-is (keeps ~/.claude, portable for default users). +# Symlinks all other files so changes to assets are immediately visible. link_claude_skill_dirs() { local gstack_dir="$1" local skills_dir="$2" @@ -205,10 +206,16 @@ link_claude_skill_dirs() { # Remove old whole-dir symlink from previous installs [ -L "$target" ] && rm -f "$target" mkdir -p "$target" - # Copy SKILL.md with path substitution (handles both ~/ and $HOME/ forms) - sed -e "s|~/.claude|$claude_dir|g" \ - -e "s|\$HOME/\.claude|$claude_dir|g" \ - "$skill_dir/SKILL.md" > "$target/SKILL.md" + # Copy SKILL.md, substituting ~/.claude only when CLAUDE_CONFIG_DIR is set. + # Default users keep ~/.claude as-is (portable); custom-path users get the + # literal resolved path baked in (no runtime bash dependency). + if [ -n "${CLAUDE_CONFIG_DIR:-}" ]; then + sed -e "s|~/.claude|$claude_dir|g" \ + -e "s|\$HOME/\.claude|$claude_dir|g" \ + "$skill_dir/SKILL.md" > "$target/SKILL.md" + else + cp "$skill_dir/SKILL.md" "$target/SKILL.md" + fi # Symlink all other entries in the skill directory for item in "$skill_dir"*; do item_name="$(basename "$item")" diff --git a/test/gen-skill-docs.test.ts b/test/gen-skill-docs.test.ts index e84dea47c..6dde046fa 100644 --- a/test/gen-skill-docs.test.ts +++ b/test/gen-skill-docs.test.ts @@ -1239,6 +1239,38 @@ describe('setup script validation', () => { expect(fnBody).toContain('ln -snf'); }); + test('link_claude_skill_dirs copies SKILL.md as-is when CLAUDE_CONFIG_DIR is unset', () => { + // When CLAUDE_CONFIG_DIR is not set, ~/.claude should be preserved in the installed SKILL.md + const tmp = fs.mkdtempSync(path.join(require('os').tmpdir(), 'gstack-test-')); + try { + const fakeSkill = path.join(tmp, 'gstack', 'fake-skill'); + const fakeSkillsDir = path.join(tmp, 'skills'); + fs.mkdirSync(fakeSkill, { recursive: true }); + fs.mkdirSync(fakeSkillsDir, { recursive: true }); + fs.writeFileSync(path.join(fakeSkill, 'SKILL.md'), + 'run ~/.claude/skills/gstack/bin/gstack-config\n'); + + const fnStart = setupContent.indexOf('link_claude_skill_dirs()'); + const fnEnd = setupContent.indexOf('\n}', setupContent.indexOf('linked[@]}', fnStart)) + 2; + const fnBody = setupContent.slice(fnStart, fnEnd); + + const env = { ...process.env }; + delete env.CLAUDE_CONFIG_DIR; + const script = `${fnBody}\nlink_claude_skill_dirs "${path.join(tmp, 'gstack')}" "${fakeSkillsDir}"`; + Bun.spawnSync(['bash', '-c', script], { + env: { ...env, HOME: process.env.HOME ?? '/tmp' }, + stdout: 'pipe', stderr: 'pipe', + }); + + const installed = path.join(fakeSkillsDir, 'fake-skill', 'SKILL.md'); + expect(fs.existsSync(installed)).toBe(true); + const content = fs.readFileSync(installed, 'utf-8'); + expect(content).toContain('~/.claude'); + } finally { + fs.rmSync(tmp, { recursive: true, force: true }); + } + }); + test('link_claude_skill_dirs substitutes CLAUDE_CONFIG_DIR into installed SKILL.md', () => { // Functional test: run the actual bash function in a temp dir and verify the // SKILL.md written to the skills dir contains the custom path, not ~/.claude.