From 8e476be1cf52e70b5f8fe26cc1afb1ac5d8b3828 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Wed, 18 Mar 2026 23:27:32 -0700 Subject: [PATCH] fix: replace eval $(gstack-slug) with source <(...) (#133) Eliminates unnecessary use of eval across all skill templates and generated files. source <(...) has identical behavior without the shell injection surface. Also hardens gstack-diff-scope usage. Closes #133 Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 4 ++-- SKILL.md | 2 +- bin/gstack-diff-scope | 2 +- bin/gstack-slug | 2 +- codex/SKILL.md | 2 +- codex/SKILL.md.tmpl | 2 +- design-consultation/SKILL.md | 2 +- design-consultation/SKILL.md.tmpl | 2 +- design-review/SKILL.md | 4 ++-- design-review/SKILL.md.tmpl | 2 +- office-hours/SKILL.md | 4 ++-- office-hours/SKILL.md.tmpl | 4 ++-- plan-ceo-review/SKILL.md | 6 +++--- plan-ceo-review/SKILL.md.tmpl | 4 ++-- plan-design-review/SKILL.md | 4 ++-- plan-design-review/SKILL.md.tmpl | 2 +- plan-eng-review/SKILL.md | 6 +++--- plan-eng-review/SKILL.md.tmpl | 4 ++-- qa-only/SKILL.md | 4 ++-- qa-only/SKILL.md.tmpl | 4 ++-- qa/SKILL.md | 4 ++-- qa/SKILL.md.tmpl | 4 ++-- review/SKILL.md | 6 +++--- review/SKILL.md.tmpl | 2 +- review/design-checklist.md | 2 +- scripts/gen-skill-docs.ts | 10 +++++----- ship/SKILL.md | 14 +++++++------- ship/SKILL.md.tmpl | 8 ++++---- 28 files changed, 58 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20735e5d..688b2231 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -106,7 +106,7 @@ When something is broken and you don't know why, `/debug` is your systematic deb ### Added - **Every PR touching frontend code now gets a design review automatically.** `/review` and `/ship` apply a 20-item design checklist against changed CSS, HTML, JSX, and view files. Catches AI slop patterns (purple gradients, 3-column icon grids, generic hero copy), typography issues (body text < 16px, blacklisted fonts), accessibility gaps (`outline: none`), and `!important` abuse. Mechanical CSS fixes are auto-applied; design judgment calls ask you first. -- **`gstack-diff-scope` categorizes what changed in your branch.** Run `eval $(gstack-diff-scope main)` and get `SCOPE_FRONTEND=true/false`, `SCOPE_BACKEND`, `SCOPE_PROMPTS`, `SCOPE_TESTS`, `SCOPE_DOCS`, `SCOPE_CONFIG`. Design review uses it to skip silently on backend-only PRs. Ship pre-flight uses it to recommend design review when frontend files are touched. +- **`gstack-diff-scope` categorizes what changed in your branch.** Run `source <(gstack-diff-scope main)` and get `SCOPE_FRONTEND=true/false`, `SCOPE_BACKEND`, `SCOPE_PROMPTS`, `SCOPE_TESTS`, `SCOPE_DOCS`, `SCOPE_CONFIG`. Design review uses it to skip silently on backend-only PRs. Ship pre-flight uses it to recommend design review when frontend files are touched. - **Design review shows up in the Review Readiness Dashboard.** The dashboard now distinguishes between "LITE" (code-level, runs automatically in /review and /ship) and "FULL" (visual audit via /plan-design-review with browse binary). Both show up as Design Review entries. - **E2E eval for design review detection.** Planted CSS/HTML fixtures with 7 known anti-patterns (Papyrus font, 14px body text, `outline: none`, `!important`, purple gradient, generic hero copy, 3-column feature grid). The eval verifies `/review` catches at least 4 of 7. @@ -222,7 +222,7 @@ Read the philosophy: https://garryslist.org/posts/boil-the-ocean ## 0.5.1 — 2026-03-17 - **Know where you stand before you ship.** Every `/plan-ceo-review`, `/plan-eng-review`, and `/plan-design-review` now logs its result to a review tracker. At the end of each review, you see a **Review Readiness Dashboard** showing which reviews are done, when they ran, and whether they're clean — with a clear CLEARED TO SHIP or NOT READY verdict. - **`/ship` checks your reviews before creating the PR.** Pre-flight now reads the dashboard and asks if you want to continue when reviews are missing. Informational only — it won't block you, but you'll know what you skipped. -- **One less thing to copy-paste.** The SLUG computation (that opaque sed pipeline for computing `owner-repo` from git remote) is now a shared `bin/gstack-slug` helper. All 14 inline copies across templates replaced with `eval $(gstack-slug)`. If the format ever changes, fix it once. +- **One less thing to copy-paste.** The SLUG computation (that opaque sed pipeline for computing `owner-repo` from git remote) is now a shared `bin/gstack-slug` helper. All 14 inline copies across templates replaced with `source <(gstack-slug)`. If the format ever changes, fix it once. - **Screenshots are now visible during QA and browse sessions.** When gstack takes screenshots, they now show up as clickable image elements in your output — no more invisible `/tmp/browse-screenshot.png` paths you can't see. Works in `/qa`, `/qa-only`, `/plan-design-review`, `/qa-design-review`, `/browse`, and `/gstack`. ### For contributors diff --git a/SKILL.md b/SKILL.md index afd90d1c..39564276 100644 --- a/SKILL.md +++ b/SKILL.md @@ -15,7 +15,7 @@ description: | - Reviewing a plan (architecture) → suggest /plan-eng-review - Reviewing a plan (design) → suggest /plan-design-review - Creating a design system → suggest /design-consultation - - Debugging errors → suggest /debug + - Debugging errors → suggest /investigate - Testing the app → suggest /qa - Code review before merge → suggest /review - Visual design audit → suggest /design-review diff --git a/bin/gstack-diff-scope b/bin/gstack-diff-scope index ada66c0a..f656732d 100755 --- a/bin/gstack-diff-scope +++ b/bin/gstack-diff-scope @@ -1,6 +1,6 @@ #!/usr/bin/env bash # gstack-diff-scope — categorize what changed in the diff against a base branch -# Usage: eval $(gstack-diff-scope main) → sets SCOPE_FRONTEND=true SCOPE_BACKEND=false ... +# Usage: source <(gstack-diff-scope main) → sets SCOPE_FRONTEND=true SCOPE_BACKEND=false ... # Or: gstack-diff-scope main → prints SCOPE_*=... lines set -euo pipefail diff --git a/bin/gstack-slug b/bin/gstack-slug index 7336b7b4..6c0e80ef 100755 --- a/bin/gstack-slug +++ b/bin/gstack-slug @@ -1,6 +1,6 @@ #!/usr/bin/env bash # gstack-slug — output project slug and sanitized branch name -# Usage: eval $(gstack-slug) → sets SLUG and BRANCH variables +# Usage: source <(gstack-slug) → sets SLUG and BRANCH variables # Or: gstack-slug → prints SLUG=... and BRANCH=... lines set -euo pipefail SLUG=$(git remote get-url origin 2>/dev/null | sed 's|.*[:/]\([^/]*/[^/]*\)\.git$|\1|;s|.*[:/]\([^/]*/[^/]*\)$|\1|' | tr '/' '-') diff --git a/codex/SKILL.md b/codex/SKILL.md index f03f0c53..7d25061b 100644 --- a/codex/SKILL.md +++ b/codex/SKILL.md @@ -279,7 +279,7 @@ CROSS-MODEL ANALYSIS: 7. Persist the review result: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) BRANCH_SLUG=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') mkdir -p ~/.gstack/projects/"$SLUG" echo '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE","findings":N}' >> ~/.gstack/projects/"$SLUG"/"$BRANCH_SLUG"-reviews.jsonl diff --git a/codex/SKILL.md.tmpl b/codex/SKILL.md.tmpl index 6dd54902..6b09d204 100644 --- a/codex/SKILL.md.tmpl +++ b/codex/SKILL.md.tmpl @@ -126,7 +126,7 @@ CROSS-MODEL ANALYSIS: 7. Persist the review result: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) BRANCH_SLUG=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') mkdir -p ~/.gstack/projects/"$SLUG" echo '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE","findings":N}' >> ~/.gstack/projects/"$SLUG"/"$BRANCH_SLUG"-reviews.jsonl diff --git a/design-consultation/SKILL.md b/design-consultation/SKILL.md index 7e23d470..3fc231e5 100644 --- a/design-consultation/SKILL.md +++ b/design-consultation/SKILL.md @@ -188,7 +188,7 @@ ls src/ app/ pages/ components/ 2>/dev/null | head -30 Look for office-hours output: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.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-consultation/SKILL.md.tmpl b/design-consultation/SKILL.md.tmpl index 2532126c..1e8b0bff 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 -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.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 b/design-review/SKILL.md index c4d102c3..ff0549ae 100644 --- a/design-review/SKILL.md +++ b/design-review/SKILL.md @@ -635,7 +635,7 @@ Compare screenshots and observations across pages for: **Project-scoped:** ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.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` @@ -854,7 +854,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.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/design-review/SKILL.md.tmpl b/design-review/SKILL.md.tmpl index 7e157287..13a27beb 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 -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.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/office-hours/SKILL.md b/office-hours/SKILL.md index b21afd85..2e204dd2 100644 --- a/office-hours/SKILL.md +++ b/office-hours/SKILL.md @@ -172,7 +172,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/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) ``` 1. Read `CLAUDE.md`, `TODOS.md` (if they exist). @@ -445,7 +445,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/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) mkdir -p ~/.gstack/projects/$SLUG diff --git a/office-hours/SKILL.md.tmpl b/office-hours/SKILL.md.tmpl index 03a8302c..39636a28 100644 --- a/office-hours/SKILL.md.tmpl +++ b/office-hours/SKILL.md.tmpl @@ -36,7 +36,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/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) ``` 1. Read `CLAUDE.md`, `TODOS.md` (if they exist). @@ -309,7 +309,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/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) mkdir -p ~/.gstack/projects/$SLUG diff --git a/plan-ceo-review/SKILL.md b/plan-ceo-review/SKILL.md index 5101ea76..5aa20d61 100644 --- a/plan-ceo-review/SKILL.md +++ b/plan-ceo-review/SKILL.md @@ -362,7 +362,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/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG/ceo-plans ``` @@ -792,7 +792,7 @@ If any AskUserQuestion goes unanswered, note it here. Never silently default. After producing the Completion Summary above, persist the review result: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG echo '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` @@ -809,7 +809,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 -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) cat ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_REVIEWS" echo "---CONFIG---" ~/.claude/skills/gstack/bin/gstack-config get skip_eng_review 2>/dev/null || echo "false" diff --git a/plan-ceo-review/SKILL.md.tmpl b/plan-ceo-review/SKILL.md.tmpl index 09189af5..6184de07 100644 --- a/plan-ceo-review/SKILL.md.tmpl +++ b/plan-ceo-review/SKILL.md.tmpl @@ -209,7 +209,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/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG/ceo-plans ``` @@ -639,7 +639,7 @@ If any AskUserQuestion goes unanswered, note it here. Never silently default. After producing the Completion Summary above, persist the review result: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG echo '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` diff --git a/plan-design-review/SKILL.md b/plan-design-review/SKILL.md index e0e3a839..f08b7032 100644 --- a/plan-design-review/SKILL.md +++ b/plan-design-review/SKILL.md @@ -422,7 +422,7 @@ If any AskUserQuestion goes unanswered, note it here. Never silently default to After producing the Completion Summary above, persist the review result: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG echo '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","overall_score":N,"unresolved":N,"decisions_made":N}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` @@ -439,7 +439,7 @@ Substitute values from the Completion Summary: After completing the review, read the review log and config to display the dashboard. ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) cat ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_REVIEWS" echo "---CONFIG---" ~/.claude/skills/gstack/bin/gstack-config get skip_eng_review 2>/dev/null || echo "false" diff --git a/plan-design-review/SKILL.md.tmpl b/plan-design-review/SKILL.md.tmpl index 73e383b6..a43914ca 100644 --- a/plan-design-review/SKILL.md.tmpl +++ b/plan-design-review/SKILL.md.tmpl @@ -269,7 +269,7 @@ If any AskUserQuestion goes unanswered, note it here. Never silently default to After producing the Completion Summary above, persist the review result: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG echo '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","overall_score":N,"unresolved":N,"decisions_made":N}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` diff --git a/plan-eng-review/SKILL.md b/plan-eng-review/SKILL.md index a98fa4f2..27040105 100644 --- a/plan-eng-review/SKILL.md +++ b/plan-eng-review/SKILL.md @@ -284,7 +284,7 @@ For LLM/prompt changes: check the "Prompt/LLM changes" file patterns listed in C After producing the test diagram, write a test plan artifact to the project directory so `/qa` and `/qa-only` can consume it as primary test input (replacing the lossy git-diff heuristic): ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) mkdir -p ~/.gstack/projects/$SLUG @@ -393,7 +393,7 @@ Check the git log for this branch. If there are prior commits suggesting a previ After producing the Completion Summary above, persist the review result: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG echo '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` @@ -410,7 +410,7 @@ Substitute values from the Completion Summary: After completing the review, read the review log and config to display the dashboard. ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) cat ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_REVIEWS" echo "---CONFIG---" ~/.claude/skills/gstack/bin/gstack-config get skip_eng_review 2>/dev/null || echo "false" diff --git a/plan-eng-review/SKILL.md.tmpl b/plan-eng-review/SKILL.md.tmpl index e7120f60..479d0d98 100644 --- a/plan-eng-review/SKILL.md.tmpl +++ b/plan-eng-review/SKILL.md.tmpl @@ -148,7 +148,7 @@ For LLM/prompt changes: check the "Prompt/LLM changes" file patterns listed in C After producing the test diagram, write a test plan artifact to the project directory so `/qa` and `/qa-only` can consume it as primary test input (replacing the lossy git-diff heuristic): ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) USER=$(whoami) DATETIME=$(date +%Y%m%d-%H%M%S) mkdir -p ~/.gstack/projects/$SLUG @@ -257,7 +257,7 @@ Check the git log for this branch. If there are prior commits suggesting a previ After producing the Completion Summary above, persist the review result: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG echo '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` diff --git a/qa-only/SKILL.md b/qa-only/SKILL.md index 45b5a46b..310fd2d1 100644 --- a/qa-only/SKILL.md +++ b/qa-only/SKILL.md @@ -206,7 +206,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/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(~/.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 @@ -502,7 +502,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** Write test outcome artifact for cross-session context: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.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-only/SKILL.md.tmpl b/qa-only/SKILL.md.tmpl index 2e2bc4f7..af3822fa 100644 --- a/qa-only/SKILL.md.tmpl +++ b/qa-only/SKILL.md.tmpl @@ -53,7 +53,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/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(~/.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 @@ -73,7 +73,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** Write test outcome artifact for cross-session context: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.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 590c18d2..002e03ec 100644 --- a/qa/SKILL.md +++ b/qa/SKILL.md @@ -410,7 +410,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/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(~/.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 @@ -874,7 +874,7 @@ Write the report to both local and project-scoped locations: **Project-scoped:** Write test outcome artifact for cross-session context: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.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 eae79605..824c7c9a 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 - eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(~/.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 -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.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/review/SKILL.md b/review/SKILL.md index 557259f1..71ead70a 100644 --- a/review/SKILL.md +++ b/review/SKILL.md @@ -271,7 +271,7 @@ Follow the output format specified in the checklist. Respect the suppressions Check if the diff touches frontend files using `gstack-diff-scope`: ```bash -eval $(~/.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. @@ -294,7 +294,7 @@ eval $(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) 6. **Log the result** for the Review Readiness Dashboard: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG echo '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` @@ -453,7 +453,7 @@ Present the full output verbatim under a `CODEX SAYS (adversarial challenge):` h **Only if a code review ran (user chose A or C):** Persist the Codex review result to the review log: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) BRANCH_SLUG=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') mkdir -p ~/.gstack/projects/"$SLUG" echo '{"skill":"codex-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","gate":"GATE"}' >> ~/.gstack/projects/"$SLUG"/"$BRANCH_SLUG"-reviews.jsonl diff --git a/review/SKILL.md.tmpl b/review/SKILL.md.tmpl index a481754a..56c44601 100644 --- a/review/SKILL.md.tmpl +++ b/review/SKILL.md.tmpl @@ -267,7 +267,7 @@ Present the full output verbatim under a `CODEX SAYS (adversarial challenge):` h **Only if a code review ran (user chose A or C):** Persist the Codex review result to the review log: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) BRANCH_SLUG=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') mkdir -p ~/.gstack/projects/"$SLUG" echo '{"skill":"codex-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","gate":"GATE"}' >> ~/.gstack/projects/"$SLUG"/"$BRANCH_SLUG"-reviews.jsonl diff --git a/review/design-checklist.md b/review/design-checklist.md index 90075165..99f9dc52 100644 --- a/review/design-checklist.md +++ b/review/design-checklist.md @@ -9,7 +9,7 @@ This checklist applies to **source code in the diff** — not rendered output. R **Trigger:** Only run this checklist if the diff touches frontend files. Use `gstack-diff-scope` to detect: ```bash -eval $(~/.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 the entire design review silently. diff --git a/scripts/gen-skill-docs.ts b/scripts/gen-skill-docs.ts index 9f5460a3..4625f800 100644 --- a/scripts/gen-skill-docs.ts +++ b/scripts/gen-skill-docs.ts @@ -567,7 +567,7 @@ function generateDesignReviewLite(_ctx: TemplateContext): string { Check if the diff touches frontend files using \`gstack-diff-scope\`: \`\`\`bash -eval $(~/.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. @@ -590,7 +590,7 @@ eval $(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) 6. **Log the result** for the Review Readiness Dashboard: \`\`\`bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG echo '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl \`\`\` @@ -850,7 +850,7 @@ Compare screenshots and observations across pages for: **Project-scoped:** \`\`\`bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.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\` @@ -940,7 +940,7 @@ function generateReviewDashboard(_ctx: TemplateContext): string { After completing the review, read the review log and config to display the dashboard. \`\`\`bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) cat ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_REVIEWS" echo "---CONFIG---" ~/.claude/skills/gstack/bin/gstack-config get skip_eng_review 2>/dev/null || echo "false" @@ -1200,7 +1200,7 @@ function findTemplates(): string[] { path.join(ROOT, 'plan-eng-review', 'SKILL.md.tmpl'), path.join(ROOT, 'retro', 'SKILL.md.tmpl'), path.join(ROOT, 'office-hours', 'SKILL.md.tmpl'), - path.join(ROOT, 'debug', 'SKILL.md.tmpl'), + path.join(ROOT, 'investigate', 'SKILL.md.tmpl'), path.join(ROOT, 'gstack-upgrade', 'SKILL.md.tmpl'), path.join(ROOT, 'plan-design-review', 'SKILL.md.tmpl'), path.join(ROOT, 'design-review', 'SKILL.md.tmpl'), diff --git a/ship/SKILL.md b/ship/SKILL.md index 97c8e79e..4499c37f 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -213,7 +213,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 -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) cat ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_REVIEWS" echo "---CONFIG---" ~/.claude/skills/gstack/bin/gstack-config get skip_eng_review 2>/dev/null || echo "false" @@ -252,7 +252,7 @@ If the Eng Review is NOT "CLEAR": 1. **Check for a prior override on this branch:** ```bash - eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(~/.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. @@ -262,11 +262,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 `eval $(~/.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/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(~/.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". @@ -683,7 +683,7 @@ Review the diff for structural issues that tests don't catch. Check if the diff touches frontend files using `gstack-diff-scope`: ```bash -eval $(~/.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. @@ -706,7 +706,7 @@ eval $(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) 6. **Log the result** for the Review Readiness Dashboard: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG echo '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` @@ -803,7 +803,7 @@ Present the full output verbatim under a `CODEX SAYS:` header. Check for `[P1]` to determine pass/fail gate. Persist the result: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) BRANCH_SLUG=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') mkdir -p ~/.gstack/projects/$SLUG echo '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE"}' >> ~/.gstack/projects/$SLUG/$BRANCH_SLUG-reviews.jsonl diff --git a/ship/SKILL.md.tmpl b/ship/SKILL.md.tmpl index bbc03fa6..bd969f0f 100644 --- a/ship/SKILL.md.tmpl +++ b/ship/SKILL.md.tmpl @@ -61,7 +61,7 @@ If the Eng Review is NOT "CLEAR": 1. **Check for a prior override on this branch:** ```bash - eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(~/.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. @@ -71,11 +71,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 `eval $(~/.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/skills/gstack/bin/gstack-slug 2>/dev/null) + source <(~/.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". @@ -428,7 +428,7 @@ Present the full output verbatim under a `CODEX SAYS:` header. Check for `[P1]` to determine pass/fail gate. Persist the result: ```bash -eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) BRANCH_SLUG=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') mkdir -p ~/.gstack/projects/$SLUG echo '{"skill":"codex-review","timestamp":"TIMESTAMP","status":"STATUS","gate":"GATE"}' >> ~/.gstack/projects/$SLUG/$BRANCH_SLUG-reviews.jsonl