bash -lc 'input=$(cat); for root in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME/.claude/plugins/everything-claude-code" "$HOME/.claude/plugins/everything-claude-code@everything-claude-code" "$HOME/.claude/plugins/marketplace/everything-claude-code"; do if [ -n "$root" ] && [ -f "$root/scripts/hooks/run-with-flags.js" ]; then printf "%s" "$input" | node "$root/scripts/hooks/run-with-flags.js" "session:start" "scripts/hooks/session-start.js" "minimal,standard,strict"; exit $?; fi; done; for parent in "$HOME/.claude/plugins" "$HOME/.claude/plugins/marketplace"; do if [ -d "$parent" ]; then candidate=$(find "$parent" -maxdepth 2 -type f -path "*/scripts/hooks/run-with-flags.js" 2>/dev/null | head -n 1); if [ -n "$candidate" ]; then root=$(dirname "$(dirname "$(dirname "$candidate")")"); printf "%s" "$input" | node "$root/scripts/hooks/run-with-flags.js" "session:start" "scripts/hooks/session-start.js" "minimal,standard,strict"; exit $?; fi; fi; done; echo "[SessionStart] WARNING: could not resolve ECC plugin root; skipping session-start hook" >&2; printf "%s" "$input"; exit 0'


请帮忙看下这个项目是做什么的，用中文写一个文档，详细阐明这个项目的目标、工作原理和使用方法，尤其是对其ai使用方面的能力做出详细和清晰的阐述


The user wants me to understand what this project (gstack) does and write a detailed Chinese document explaining its goals, how it works, and how to use it, especially its AI capabilities. Let me explore the codebase first.


Let me先深入探索这个项目的代码库。


Agent

Explore gstack project structure

Prompt:
Thoroughly explore the gstack project at /root/projects/gits/gstack. I need to understand:

1. What is gstack? Read the README.md, package.json, CHANGELOG.md to understand the project's purpose and features
2. Read the main SKILL.md.tmpl template to understand what skills/commands it provides to users
3. Read the browse/ directory - understand what the headless browser CLI does (browse/src/commands.ts, browse/src/snapshot.ts, browse/src/index.ts or main entry)
4. Look at the setup script to understand installation
5. Read any skill directories (ship/, review/, qa-only/, plan-design-review/, retro/, etc.) - read their SKILL.md.tmpl files to understand each skill

Be very thorough - read actual file contents, not just list files. I need detailed understanding of every major feature.


bash "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/run-with-flags-shell.sh" "pre:observe" "skills/continuous-learning-v2/hooks/observe.sh" "standard,strict"


Thoroughly explore the gstack project at /root/projects/gits/gstack. I need to understand:

1. What is gstack? Read the README.md, package.json, CHANGELOG.md to understand the project's purpose and features
2. Read the main SKILL.md.tmpl template to understand what skills/commands it provides to users
3. Read the browse/ directory - understand what the headless browser CLI does (browse/src/commands.ts, browse/src/snapshot.ts, browse/src/index.ts or main entry)
4. Look at the setup script to understand installation
5. Read any skill directories (ship/, review/, qa-only/, plan-design-review/, retro/, etc.) - read their SKILL.md.tmpl files to understand each skill

Be very thorough - read actual file contents, not just list files. I need detailed understanding of every major feature.

Prompt:
Thoroughly explore the gstack project at /root/projects/gits/gstack. I need to understand:

1. What is gstack? Read the README.md, package.json, CHANGELOG.md to understand the project's purpose and features
2. Read the main SKILL.md.tmpl template to understand what skills/commands it provides to users
3. Read the browse/ directory - understand what the headless browser CLI does (browse/src/commands.ts, browse/src/snapshot.ts, browse/src/index.ts or main entry)
4. Look at the setup script to understand installation
5. Read any skill directories (ship/, review/, qa-only/, plan-design-review/, retro/, etc.) - read their SKILL.md.tmpl files to understand each skill

Be very thorough - read actual file contents, not just list files. I need detailed understanding of every major feature.


Explore gstack AI and eval system

Prompt:
Explore the gstack project at /root/projects/gits/gstack focusing on the AI/eval system and testing infrastructure:

1. Read test/helpers/ - especially session-runner.ts, llm-judge.ts, eval-store.ts, skill-parser.ts, touchfiles.ts
2. Read test/skill-e2e.test.ts and test/skill-llm-eval.test.ts to understand how AI evals work
3. Read test/skill-validation.test.ts to understand skill validation
4. Read scripts/gen-skill-docs.ts to understand the template system
5. Read scripts/skill-check.ts for the health dashboard
6. Look at the browse/src/ directory more carefully - how does the browser automation work? Read server.ts, snapshot.ts, commands.ts fully

I need to understand the AI-powered evaluation pipeline, how skills are validated, and how the browser tool works with AI agents.


Explore the gstack project at /root/projects/gits/gstack focusing on the AI/eval system and testing infrastructure:

1. Read test/helpers/ - especially session-runner.ts, llm-judge.ts, eval-store.ts, skill-parser.ts, touchfiles.ts
2. Read test/skill-e2e.test.ts and test/skill-llm-eval.test.ts to understand how AI evals work
3. Read test/skill-validation.test.ts to understand skill validation
4. Read scripts/gen-skill-docs.ts to understand the template system
5. Read scripts/skill-check.ts for the health dashboard
6. Look at the browse/src/ directory more carefully - how does the browser automation work? Read server.ts, snapshot.ts, commands.ts fully

I need to understand the AI-powered evaluation pipeline, how skills are validated, and how the browser tool works with AI agents.

Prompt:
Explore the gstack project at /root/projects/gits/gstack focusing on the AI/eval system and testing infrastructure:

1. Read test/helpers/ - especially session-runner.ts, llm-judge.ts, eval-store.ts, skill-parser.ts, touchfiles.ts
2. Read test/skill-e2e.test.ts and test/skill-llm-eval.test.ts to understand how AI evals work
3. Read test/skill-validation.test.ts to understand skill validation
4. Read scripts/gen-skill-docs.ts to understand the template system
5. Read scripts/skill-check.ts for the health dashboard
6. Look at the browse/src/ directory more carefully - how does the browser automation work? Read server.ts, snapshot.ts, commands.ts fully

I need to understand the AI-powered evaluation pipeline, how skills are validated, and how the browser tool works with AI agents.


Explore gstack skill templates

Prompt:
Explore the gstack project at /root/projects/gits/gstack focusing on all the skill template files and how they work together:

1. Read every SKILL.md.tmpl file in the project root and subdirectories (ship/, review/, qa-only/, plan-design-review/, design-review/, plan-ceo-review/, plan-eng-review/, retro/, document-release/)
2. Read the generated SKILL.md files to see what the final output looks like
3. Read the scripts/gen-skill-docs.ts to understand template variables and how they're resolved
4. Look for any preamble or shared template fragments
5. Read browse/SKILL.md.tmpl if it exists

I need to understand exactly what each skill does and how they compose together.


Explore the gstack project at /root/projects/gits/gstack focusing on all the skill template files and how they work together:

1. Read every SKILL.md.tmpl file in the project root and subdirectories (ship/, review/, qa-only/, plan-design-review/, design-review/, plan-ceo-review/, plan-eng-review/, retro/, document-release/)
2. Read the generated SKILL.md files to see what the final output looks like
3. Read the scripts/gen-skill-docs.ts to understand template variables and how they're resolved
4. Look for any preamble or shared template fragments
5. Read browse/SKILL.md.tmpl if it exists

I need to understand exactly what each skill does and how they compose together.

Prompt:
Explore the gstack project at /root/projects/gits/gstack focusing on all the skill template files and how they work together:

1. Read every SKILL.md.tmpl file in the project root and subdirectories (ship/, review/, qa-only/, plan-design-review/, design-review/, plan-ceo-review/, plan-eng-review/, retro/, document-release/)
2. Read the generated SKILL.md files to see what the final output looks like
3. Read the scripts/gen-skill-docs.ts to understand template variables and how they're resolved
4. Look for any preamble or shared template fragments
5. Read browse/SKILL.md.tmpl if it exists

I need to understand exactly what each skill does and how they compose together.


     1→# gstack
     2→
     3→Hi, I'm [Garry Tan](https://x.com/garrytan). I'm President & CEO of [Y Combinator](https://www.ycombinator.com/), where I've worked with thousands of startups including Coinbase, Instacart, and Rippling when the founders were just one or two people in a garage — companies now worth tens of billions of dollars. Before YC, I designed the Palantir logo and was one of the first eng manager/PM/designers there. I cofounded Posterous, a blog platform we sold to Twitter. I built Bookface, YC's internal social network, back in 2013. I've been building products as a designer, PM, and eng manager for a long time.
     4→
     5→And right now I am in the middle of something that feels like a new era entirely.
     6→
     7→In the last 60 days I have written **over 600,000 lines of production code** — 35% tests — and I am doing **10,000 to 20,000 usable lines of code per day** as a part-time part of my day while doing all my duties as CEO of YC. That is not a typo. My last `/retro` (developer stats from the last 7 days) across 3 projects: **140,751 lines added, 362 commits, ~115k net LOC**. The models are getting dramatically better every week. We are at the dawn of something real — one person shipping at a scale that used to require a team of twenty.
     8→
     9→**2026 — 1,237 contributions and counting:**
    10→
    11→![GitHub contributions 2026 — 1,237 contributions, massive acceleration in Jan-Mar](docs/images/github-2026.png)
    12→
    13→**2013 — when I built Bookface at YC (772 contributions):**
    14→
    15→![GitHub contributions 2013 — 772 contributions building Bookface at YC](docs/images/github-2013.png)
    16→
    17→Same person. Different era. The difference is the tooling.
    18→
    19→**gstack is how I do it.** It is my open source software factory. It turns Claude Code into a virtual engineering team you actually manage — a CEO who rethinks the product, an eng manager who locks the architecture, a designer who catches AI slop, a paranoid reviewer who finds production bugs, a QA lead who opens a real browser and clicks through your app, and a release engineer who ships the PR. Thirteen specialists, all as slash commands, all Markdown, **all free, MIT license, available right now.**
    20→
    21→I am learning how to get to the edge of what agentic systems can do as of March 2026, and this is my live experiment. I am sharing it because I want the whole world on this journey with me.
    22→
    23→Fork it. Improve it. Make it yours. Don't player hate, appreciate.
    24→
    25→**Who this is for:**
    26→- **Founders and CEOs** — especially technical ones who still want to ship. This is how you build like a team of twenty.
    27→- **First-time Claude Code users** — gstack is the best way to start. Structured roles instead of a blank prompt.
    28→- **Tech leads and staff engineers** — bring rigorous review, QA, and release automation to every PR
    29→
    30→## Quick start: your first 10 minutes
    31→
    32→1. Install gstack (30 seconds — see below)
    33→2. Run `/plan-ceo-review` on any feature idea
    34→3. Run `/review` on any branch with changes
    35→4. Run `/qa` on your staging URL
    36→5. Stop there. You'll know if this is for you.
    37→
    38→Expect first useful run in under 5 minutes on any repo with tests already set up.
    39→
    40→**If you only read one more section, read this one.**
    41→
    42→## Install — takes 30 seconds
    43→
    44→**Requirements:** [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Git](https://git-scm.com/), [Bun](https://bun.sh/) v1.0+
    45→
    46→### Step 1: Install on your machine
    47→
    48→Open Claude Code and paste this. Claude does the rest.
    49→
    50→> Install gstack: run **`git clone https://github.com/garrytan/gstack.git ~/.claude/skills/gstack && cd ~/.claude/skills/gstack && ./setup`** then add a "gstack" section to CLAUDE.md that says to use the /browse skill from gstack for all web browsing, never use mcp\_\_claude-in-chrome\_\_\* tools, and lists the available skills: /plan-ceo-review, /plan-eng-review, /plan-design-review, /design-consultation, /review, /ship, /browse, /qa, /qa-only, /qa-design-review, /setup-browser-cookies, /retro, /document-release. Then ask the user if they also want to add gstack to the current project so teammates get it.
    51→
    52→### Step 2: Add to your repo so teammates get it (optional)
    53→
    54→> Add gstack to this project: run **`cp -Rf ~/.claude/skills/gstack .claude/skills/gstack && rm -rf .claude/skills/gstack/.git && cd .claude/skills/gstack && ./setup`** then add a "gstack" section to this project's CLAUDE.md that says to use the /browse skill from gstack for all web browsing, never use mcp\_\_claude-in-chrome\_\_\* tools, lists the available skills: /plan-ceo-review, /plan-eng-review, /plan-design-review, /design-consultation, /review, /ship, /browse, /qa, /qa-only, /qa-design-review, /setup-browser-cookies, /retro, /document-release, and tells Claude that if gstack skills aren't working, run `cd .claude/skills/gstack && ./setup` to build the binary and register skills.
    55→
    56→Real files get committed to your repo (not a submodule), so `git clone` just works. Everything lives inside `.claude/`. Nothing touches your PATH or runs in the background.
    57→
    58→## See it work
    59→
    60→```
    61→You:    I want to add photo upload for sellers.
    62→You:    /plan-ceo-review
    63→Claude: "Photo upload" is not the feature. The real job is helping
    64→        sellers create listings that actually sell. What if we
    65→        auto-identify the product, pull specs and comps from the
    66→        web, and draft the listing automatically? That's 10 stars.
    67→        "Upload a photo" is 3 stars. Which are we building?
    68→        [8 expansion proposals, you cherry-pick 5, defer 3 to backlog]
    69→
    70→You:    /plan-design-review
    71→Claude: Design Score: B  |  AI Slop Score: C
    72→        "Upload flow looks like a default Bootstrap form."
    73→        [80-item audit, infers your design system, exports DESIGN.md]
    74→        [flags 3 AI slop patterns: gradient hero, icon grid, uniform radius]
    75→
    76→You:    /plan-eng-review
    77→Claude: ┌─────────┐    ┌──────────┐    ┌──────────┐    ┌─────────┐
    78→        │ Upload  │───▶│ Classify │───▶│ Enrich   │───▶│ Draft   │
    79→        │ (sync)  │    │ (async)  │    │ (async)  │    │ (async) │
    80→        └─────────┘    └──────────┘    └──────────┘    └─────────┘
    81→        [ASCII diagrams for every data flow, state machine, error path]
    82→        [14-case test matrix, 6 failure modes mapped, 3 security concerns]
    83→
    84→You:    Approve plan. Exit plan mode.
    85→        [Claude writes 2,400 lines across 11 files — models, services,
    86→         controllers, views, migrations, and tests. ~8 minutes.]
    87→
    88→You:    /review
    89→Claude: [AUTO-FIXED] Orphan S3 cleanup on failed upload
    90→        [AUTO-FIXED] Missing index on listings.status
    91→        [ASK] Race condition on hero image selection → You: yes
    92→        [traces every new enum value through all switch statements]
    93→        3 issues — 2 auto-fixed, 1 fixed.
    94→
    95→You:    /qa https://staging.myapp.com
    96→Claude: [opens real browser, logs in, uploads photos, clicks through flows]
    97→        Upload → classify → enrich → draft: end to end ✓
    98→        Mobile: ✓  |  Slow connection: ✓  |  Bad image: ✓
    99→        [finds bug: preview doesn't clear on second upload — fixes it]
   100→        Regression test generated.
   101→
   102→You:    /ship
   103→Claude: Tests: 42 → 51 (+9 new)
   104→        Coverage: 14/14 code paths (100%)
   105→        PR: github.com/you/app/pull/42
   106→```
   107→
   108→One feature. Seven commands. The agent reframed the product, ran an 80-item design audit, drew the architecture, wrote 2,400 lines of code, found a race condition I would have missed, auto-fixed two issues, opened a real browser to QA test, found and fixed a bug I didn't know about, wrote 9 tests, and generated a regression test. That is not a copilot. That is a team.
   109→
   110→## The team
   111→
   112→| Skill | Your specialist | What they do |
   113→|-------|----------------|--------------|
   114→| `/plan-ceo-review` | **CEO / Founder** | Rethink the problem. Find the 10-star product hiding inside the request. Four modes: Expansion, Selective Expansion, Hold Scope, Reduction. |
   115→| `/plan-eng-review` | **Eng Manager** | Lock in architecture, data flow, diagrams, edge cases, and tests. Forces hidden assumptions into the open. |
   116→| `/plan-design-review` | **Senior Designer** | 80-item design audit with letter grades. AI Slop detection. Infers your design system. Report only — never touches code. |
   117→| `/design-consultation` | **Design Partner** | Build a complete design system from scratch. Knows the landscape, proposes creative risks, generates realistic product mockups. Design at the heart of all other phases. |
   118→| `/review` | **Staff Engineer** | Find the bugs that pass CI but blow up in production. Auto-fixes the obvious ones. Flags completeness gaps. |
   119→| `/ship` | **Release Engineer** | Sync main, run tests, audit coverage, push, open PR. Bootstraps test frameworks if you don't have one. One command. |
   120→| `/browse` | **QA Engineer** | Give the agent eyes. Real Chromium browser, real clicks, real screenshots. ~100ms per command. |
   121→| `/qa` | **QA Lead** | Test your app, find bugs, fix them with atomic commits, re-verify. Auto-generates regression tests for every fix. |
   122→| `/qa-only` | **QA Reporter** | Same methodology as /qa but report only. Use when you want a pure bug report without code changes. |
   123→| `/design-review` | **Designer Who Codes** | Same audit as /plan-design-review, then fixes what it finds. Atomic commits, before/after screenshots. |
   124→| `/setup-browser-cookies` | **Session Manager** | Import cookies from your real browser (Chrome, Arc, Brave, Edge) into the headless session. Test authenticated pages. |
   125→| `/retro` | **Eng Manager** | Team-aware weekly retro. Per-person breakdowns, shipping streaks, test health trends, growth opportunities. |
   126→| `/document-release` | **Technical Writer** | Update all project docs to match what you just shipped. Catches stale READMEs automatically. |
   127→
   128→**[Deep dives with examples and philosophy for every skill →](docs/skills.md)**
   129→
   130→## What's new and why it matters
   131→
   132→**Design is at the heart.** `/design-consultation` doesn't just pick fonts. It researches what's out there in your space, proposes safe choices AND creative risks, generates realistic mockups of your actual product, and writes `DESIGN.md` — and then `/design-review` and `/plan-eng-review` read what you chose. Design decisions flow through the whole system.
   133→
   134→**`/qa` was a massive unlock.** It let me go from 6 to 12 parallel workers. Claude Code saying *"I SEE THE ISSUE"* and then actually fixing it, generating a regression test, and verifying the fix — that changed how I work. The agent has eyes now.
   135→
   136→**Smart review routing.** Just like at a well-run startup: CEO doesn't have to look at infra bug fixes, design review isn't needed for backend changes. gstack tracks what reviews are run, figures out what's appropriate, and just does the smart thing. The Review Readiness Dashboard tells you where you stand before you ship.
   137→
   138→**Test everything.** `/ship` bootstraps test frameworks from scratch if your project doesn't have one. Every `/ship` run produces a coverage audit. Every `/qa` bug fix generates a regression test. 100% test coverage is the goal — tests make vibe coding safe instead of yolo coding.
   139→
   140→**`/document-release` is the engineer you never had.** It reads every doc file in your project, cross-references the diff, and updates everything that drifted. README, ARCHITECTURE, CONTRIBUTING, CLAUDE.md, TODOS — all kept current automatically.
   141→
   142→## 10 sessions at once
   143→
   144→gstack is powerful with one session. It is transformative with ten.
   145→
   146→[Conductor](https://conductor.build) runs multiple Claude Code sessions in parallel — each in its own isolated workspace. One session running `/qa` on staging, another doing `/review` on a PR, a third implementing a feature, and seven more on other branches. All at the same time.
   147→
   148→One person, ten parallel agents, each with the right cognitive mode. That is a different way of building software.
   149→
   150→## Come ride the wave
   151→
   152→This is **free, MIT licensed, open source, available now.** No premium tier. No waitlist. No strings.
   153→
   154→I open sourced how I do development and I am actively upgrading my own software factory here. You can fork it and make it your own. That's the whole point. I want everyone on this journey.
   155→
   156→Same tools, different outcome — because gstack gives you structured roles and review gates, not generic agent chaos. That governance is the difference between shipping fast and shipping reckless.
   157→
   158→The models are getting better fast. The people who figure out how to work with them now — really work with them, not just dabble — are going to have a massive advantage. This is that window. Let's go.
   159→
   160→Thirteen specialists. All slash commands. All Markdown. All free. **[github.com/garrytan/gstack](https://github.com/garrytan/gstack)** — MIT License
   161→
   162→> **We're hiring.** Want to ship 10K+ LOC/day and help harden gstack?
   163→> Come work at YC — [ycombinator.com/software](https://ycombinator.com/software)
   164→> Extremely competitive salary and equity. San Francisco, Dogpatch District.
   165→
   166→## Docs
   167→
   168→| Doc | What it covers |
   169→|-----|---------------|
   170→| [Skill Deep Dives](docs/skills.md) | Philosophy, examples, and workflow for every skill (includes Greptile integration) |
   171→| [Architecture](ARCHITECTURE.md) | Design decisions and system internals |
   172→| [Browser Reference](BROWSER.md) | Full command reference for `/browse` |
   173→| [Contributing](CONTRIBUTING.md) | Dev setup, testing, contributor mode, and dev mode |
   174→| [Changelog](CHANGELOG.md) | What's new in every version |
   175→
   176→## Troubleshooting
   177→
   178→**Skill not showing up?** `cd ~/.claude/skills/gstack && ./setup`
   179→
   180→**`/browse` fails?** `cd ~/.claude/skills/gstack && bun install && bun run build`
   181→
   182→**Stale install?** Run `/gstack-upgrade` — or set `auto_upgrade: true` in `~/.gstack/config.yaml`
   183→
   184→**Claude says it can't see the skills?** Make sure your project's `CLAUDE.md` has a gstack section. Add this:
   185→
   186→```
   187→## gstack
   188→Use /browse from gstack for all web browsing. Never use mcp__claude-in-chrome__* tools.
   189→Available skills: /plan-ceo-review, /plan-eng-review, /plan-design-review,
   190→/design-consultation, /review, /ship, /browse, /qa, /qa-only, /qa-design-review,
   191→/setup-browser-cookies, /retro, /document-release.
   192→```
   193→
   194→## License
   195→
   196→MIT. Free forever. Go build something.
   197→


Bash

find /root/projects/gits/gstack -type f -name "*.tmpl" | head -20

Find all skill template files


     1→{
     2→  "name": "gstack",
     3→  "version": "0.3.3",
     4→  "description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.",
     5→  "license": "MIT",
     6→  "type": "module",
     7→  "bin": {
     8→    "browse": "./browse/dist/browse"
     9→  },
    10→  "scripts": {
    11→    "build": "bun run gen:skill-docs && bun build --compile browse/src/cli.ts --outfile browse/dist/browse && bun build --compile browse/src/find-browse.ts --outfile browse/dist/find-browse && git rev-parse HEAD > browse/dist/.version && rm -f .*.bun-build || true",
    12→    "gen:skill-docs": "bun run scripts/gen-skill-docs.ts",
    13→    "dev": "bun run browse/src/cli.ts",
    14→    "server": "bun run browse/src/server.ts",
    15→    "test": "bun test browse/test/ test/ --ignore test/skill-e2e.test.ts --ignore test/skill-llm-eval.test.ts",
    16→    "test:evals": "EVALS=1 bun test test/skill-llm-eval.test.ts test/skill-e2e.test.ts",
    17→    "test:evals:all": "EVALS=1 EVALS_ALL=1 bun test test/skill-llm-eval.test.ts test/skill-e2e.test.ts",
    18→    "test:e2e": "EVALS=1 bun test test/skill-e2e.test.ts",
    19→    "test:e2e:all": "EVALS=1 EVALS_ALL=1 bun test test/skill-e2e.test.ts",
    20→    "skill:check": "bun run scripts/skill-check.ts",
    21→    "dev:skill": "bun run scripts/dev-skill.ts",
    22→    "start": "bun run browse/src/server.ts",
    23→    "eval:list": "bun run scripts/eval-list.ts",
    24→    "eval:compare": "bun run scripts/eval-compare.ts",
    25→    "eval:summary": "bun run scripts/eval-summary.ts",
    26→    "eval:watch": "bun run scripts/eval-watch.ts",
    27→    "eval:select": "bun run scripts/eval-select.ts"
    28→  },
    29→  "dependencies": {
    30→    "playwright": "^1.58.2",
    31→    "diff": "^7.0.0"
    32→  },
    33→  "engines": {
    34→    "bun": ">=1.0.0"
    35→  },
    36→  "keywords": [
    37→    "browser",
    38→    "automation",
    39→    "playwright",
    40→    "headless",
    41→    "cli",
    42→    "claude",
    43→    "ai-agent",
    44→    "devtools"
    45→  ],
    46→  "devDependencies": {
    47→    "@anthropic-ai/sdk": "^0.78.0"
    48→  }
    49→}
    50→


     1→# Changelog
     2→
     3→## [0.6.4.0] - 2026-03-17
     4→
     5→### Added
     6→
     7→- **`/plan-design-review` is now interactive — rates 0-10, fixes the plan.** Instead of producing a report with letter grades, the designer now works like CEO and Eng review: rates each design dimension 0-10, explains what a 10 looks like, then edits the plan to get there. One AskUserQuestion per design choice. The output is a better plan, not a document about the plan.
     8→- **CEO review now calls in the designer.** When `/plan-ceo-review` detects UI scope in a plan, it activates a Design & UX section (Section 11) covering information architecture, interaction state coverage, AI slop risk, and responsive intention. For deep design work, it recommends `/plan-design-review`.
     9→- **14 of 15 skills now have full test coverage (E2E + LLM-judge + validation).** Added LLM-judge quality evals for 10 skills that were missing them: ship, retro, qa-only, plan-ceo-review, plan-eng-review, plan-design-review, design-review, design-consultation, document-release, gstack-upgrade. Added real E2E test for gstack-upgrade (was a `.todo`). Added design-consultation to command validation.
    10→- **Bisect commit style.** CLAUDE.md now requires every commit to be a single logical change — renames separate from rewrites, test infrastructure separate from test implementations.
    11→
    12→### Changed
    13→
    14→- `/qa-design-review` renamed to `/design-review` — the "qa-" prefix was confusing now that `/plan-design-review` is plan-mode. Updated across all 22 files.
    15→
    16→## [0.6.3.0] - 2026-03-17
    17→
    18→### Added
    19→
    20→- **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.
    21→- **`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.
    22→- **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.
    23→- **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.
    24→
    25→## [0.6.2.0] - 2026-03-17
    26→
    27→### Added
    28→
    29→- **Plan reviews now think like the best in the world.** `/plan-ceo-review` applies 14 cognitive patterns from Bezos (one-way doors, Day 1 proxy skepticism), Grove (paranoid scanning), Munger (inversion), Horowitz (wartime awareness), Chesky/Graham (founder mode), and Altman (leverage obsession). `/plan-eng-review` applies 15 patterns from Larson (team state diagnosis), McKinley (boring by default), Brooks (essential vs accidental complexity), Beck (make the change easy), Majors (own your code in production), and Google SRE (error budgets). `/plan-design-review` applies 12 patterns from Rams (subtraction default), Norman (time-horizon design), Zhuo (principled taste), Gebbia (design for trust, storyboard the journey), and Ive (care is visible).
    30→- **Latent space activation, not checklists.** The cognitive patterns name-drop frameworks and people so the LLM draws on its deep knowledge of how they actually think. The instruction is "internalize these, don't enumerate them" — making each review a genuine perspective shift, not a longer checklist.
    31→
    32→## [0.6.1.0] - 2026-03-17
    33→
    34→### Added
    35→
    36→- **E2E and LLM-judge tests now only run what you changed.** Each test declares which source files it depends on. When you run `bun run test:e2e`, it checks your diff and skips tests whose dependencies weren't touched. A branch that only changes `/retro` now runs 2 tests instead of 31. Use `bun run test:e2e:all` to force everything.
    37→- **`bun run eval:select` previews which tests would run.** See exactly which tests your diff triggers before spending API credits. Supports `--json` for scripting and `--base <branch>` to override the base branch.
    38→- **Completeness guardrail catches forgotten test entries.** A free unit test validates that every `testName` in the E2E and LLM-judge test files has a corresponding entry in the TOUCHFILES map. New tests without entries fail `bun test` immediately — no silent always-run degradation.
    39→
    40→### Changed
    41→
    42→- `test:evals` and `test:e2e` now auto-select based on diff (was: all-or-nothing)
    43→- New `test:evals:all` and `test:e2e:all` scripts for explicit full runs
    44→
    45→## 0.6.1 — 2026-03-17 — Boil the Lake
    46→
    47→Every gstack skill now follows the **Completeness Principle**: always recommend the
    48→full implementation when AI makes the marginal cost near-zero. No more "Choose B
    49→because it's 90% of the value" when option A is 70 lines more code.
    50→
    51→Read the philosophy: https://garryslist.org/posts/boil-the-ocean
    52→
    53→- **Completeness scoring**: every AskUserQuestion option now shows a completeness
    54→  score (1-10), biasing toward the complete solution
    55→- **Dual time estimates**: effort estimates show both human-team and CC+gstack time
    56→  (e.g., "human: ~2 weeks / CC: ~1 hour") with a task-type compression reference table
    57→- **Anti-pattern examples**: concrete "don't do this" gallery in the preamble so the
    58→  principle isn't abstract
    59→- **First-time onboarding**: new users see a one-time introduction linking to the
    60→  essay, with option to open in browser
    61→- **Review completeness gaps**: `/review` now flags shortcut implementations where the
    62→  complete version costs <30 min CC time
    63→- **Lake Score**: CEO and Eng review completion summaries show how many recommendations
    64→  chose the complete option vs shortcuts
    65→- **CEO + Eng review dual-time**: temporal interrogation, effort estimates, and delight
    66→  opportunities all show both human and CC time scales
    67→
    68→## 0.6.0.1 — 2026-03-17
    69→
    70→- **`/gstack-upgrade` now catches stale vendored copies automatically.** If your global gstack is up to date but the vendored copy in your project is behind, `/gstack-upgrade` detects the mismatch and syncs it. No more manually asking "did we vendor it?" — it just tells you and offers to update.
    71→- **Upgrade sync is safer.** If `./setup` fails while syncing a vendored copy, gstack restores the previous version from backup instead of leaving a broken install.
    72→
    73→### For contributors
    74→
    75→- Standalone usage section in `gstack-upgrade/SKILL.md.tmpl` now references Steps 2 and 4.5 (DRY) instead of duplicating detection/sync bash blocks. Added one new version-comparison bash block.
    76→- Update check fallback in standalone mode now matches the preamble pattern (global path → local path → `|| true`).
    77→
    78→## 0.6.0 — 2026-03-17
    79→
    80→- **100% test coverage is the key to great vibe coding.** gstack now bootstraps test frameworks from scratch when your project doesn't have one. Detects your runtime, researches the best framework, asks you to pick, installs it, writes 3-5 real tests for your actual code, sets up CI/CD (GitHub Actions), creates TESTING.md, and adds test culture instructions to CLAUDE.md. Every Claude Code session after that writes tests naturally.
    81→- **Every bug fix now gets a regression test.** When `/qa` fixes a bug and verifies it, Phase 8e.5 automatically generates a regression test that catches the exact scenario that broke. Tests include full attribution tracing back to the QA report. Auto-incrementing filenames prevent collisions across sessions.
    82→- **Ship with confidence — coverage audit shows what's tested and what's not.** `/ship` Step 3.4 builds a code path map from your diff, searches for corresponding tests, and produces an ASCII coverage diagram with quality stars (★★★ = edge cases + errors, ★★ = happy path, ★ = smoke test). Gaps get tests auto-generated. PR body shows "Tests: 42 → 47 (+5 new)".
    83→- **Your retro tracks test health.** `/retro` now shows total test files, tests added this period, regression test commits, and trend deltas. If test ratio drops below 20%, it flags it as a growth area.
    84→- **Design reviews generate regression tests too.** `/qa-design-review` Phase 8e.5 skips CSS-only fixes (those are caught by re-running the design audit) but writes tests for JavaScript behavior changes like broken dropdowns or animation failures.
    85→
    86→### For contributors
    87→
    88→- Added `generateTestBootstrap()` resolver to `gen-skill-docs.ts` (~155 lines). Registered as `{{TEST_BOOTSTRAP}}` in the RESOLVERS map. Inserted into qa, ship (Step 2.5), and qa-design-review templates.
    89→- Phase 8e.5 regression test generation added to `qa/SKILL.md.tmpl` (46 lines) and CSS-aware variant to `qa-design-review/SKILL.md.tmpl` (12 lines). Rule 13 amended to allow creating new test files.
    90→- Step 3.4 test coverage audit added to `ship/SKILL.md.tmpl` (88 lines) with quality scoring rubric and ASCII diagram format.
    91→- Test health tracking added to `retro/SKILL.md.tmpl`: 3 new data gathering commands, metrics row, narrative section, JSON schema field.
    92→- `qa-only/SKILL.md.tmpl` gets recommendation note when no test framework detected.
    93→- `qa-report-template.md` gains Regression Tests section with deferred test specs.
    94→- ARCHITECTURE.md placeholder table updated with `{{TEST_BOOTSTRAP}}` and `{{REVIEW_DASHBOARD}}`.
    95→- WebSearch added to allowed-tools for qa, ship, qa-design-review.
    96→- 26 new validation tests, 2 new E2E evals (bootstrap + coverage audit).
    97→- 2 new P3 TODOs: CI/CD for non-GitHub providers, auto-upgrade weak tests.
    98→
    99→## 0.5.4 — 2026-03-17
   100→
   101→- **Engineering review is always the full review now.** `/plan-eng-review` no longer asks you to choose between "big change" and "small change" modes. Every plan gets the full interactive walkthrough (architecture, code quality, tests, performance). Scope reduction is only suggested when the complexity check actually triggers — not as a standing menu option.
   102→- **Ship stops asking about reviews once you've answered.** When `/ship` asks about missing reviews and you say "ship anyway" or "not relevant," that decision is saved for the branch. No more getting re-asked every time you re-run `/ship` after a pre-landing fix.
   103→
   104→### For contributors
   105→
   106→- Removed SMALL_CHANGE / BIG_CHANGE / SCOPE_REDUCTION menu from `plan-eng-review/SKILL.md.tmpl`. Scope reduction is now proactive (triggered by complexity check) rather than a menu item.
   107→- Added review gate override persistence to `ship/SKILL.md.tmpl` — writes `ship-review-override` entries to `$BRANCH-reviews.jsonl` so subsequent `/ship` runs skip the gate.
   108→- Updated 2 E2E test prompts to match new flow.
   109→
   110→## 0.5.3 — 2026-03-17
   111→
   112→- **You're always in control — even when dreaming big.** `/plan-ceo-review` now presents every scope expansion as an individual decision you opt into. EXPANSION mode recommends enthusiastically, but you say yes or no to each idea. No more "the agent went wild and added 5 features I didn't ask for."
   113→- **New mode: SELECTIVE EXPANSION.** Hold your current scope as the baseline, but see what else is possible. The agent surfaces expansion opportunities one by one with neutral recommendations — you cherry-pick the ones worth doing. Perfect for iterating on existing features where you want rigor but also want to be tempted by adjacent improvements.
   114→- **Your CEO review visions are saved, not lost.** Expansion ideas, cherry-pick decisions, and 10x visions are now persisted to `~/.gstack/projects/{repo}/ceo-plans/` as structured design documents. Stale plans get archived automatically. If a vision is exceptional, you can promote it to `docs/designs/` in your repo for the team.
   115→
   116→- **Smarter ship gates.** `/ship` no longer nags you about CEO and Design reviews when they're not relevant. Eng Review is the only required gate (and you can disable even that with `gstack-config set skip_eng_review true`). CEO Review is recommended for big product changes; Design Review for UI work. The dashboard still shows all three — it just won't block you for the optional ones.
   117→
   118→### For contributors
   119→
   120→- Added SELECTIVE EXPANSION mode to `plan-ceo-review/SKILL.md.tmpl` with cherry-pick ceremony, neutral recommendation posture, and HOLD SCOPE baseline.
   121→- Rewrote EXPANSION mode's Step 0D to include opt-in ceremony — distill vision into discrete proposals, present each as AskUserQuestion.
   122→- Added CEO plan persistence (0D-POST step): structured markdown with YAML frontmatter (`status: ACTIVE/ARCHIVED/PROMOTED`), scope decisions table, archival flow.
   123→- Added `docs/designs` promotion step after Review Log.
   124→- Mode Quick Reference table expanded to 4 columns.
   125→- Review Readiness Dashboard: Eng Review required (overridable via `skip_eng_review` config), CEO/Design optional with agent judgment.
   126→- New tests: CEO review mode validation (4 modes, persistence, promotion), SELECTIVE EXPANSION E2E test.
   127→
   128→## 0.5.2 — 2026-03-17
   129→
   130→- **Your design consultant now takes creative risks.** `/design-consultation` doesn't just propose a safe, coherent system — it explicitly breaks down SAFE CHOICES (category baseline) vs. RISKS (where your product stands out). You pick which rules to break. Every risk comes with a rationale for why it works and what it costs.
   131→- **See the landscape before you choose.** When you opt into research, the agent browses real sites in your space with screenshots and accessibility tree analysis — not just web search results. You see what's out there before making design decisions.
   132→- **Preview pages that look like your product.** The preview page now renders realistic product mockups — dashboards with sidebar nav and data tables, marketing pages with hero sections, settings pages with forms — not just font swatches and color palettes.
   133→
   134→## 0.5.1 — 2026-03-17
   135→- **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.
   136→- **`/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.
   137→- **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.
   138→- **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`.
   139→
   140→### For contributors
   141→
   142→- Added `{{REVIEW_DASHBOARD}}` resolver to `gen-skill-docs.ts` — shared dashboard reader injected into 4 templates (3 review skills + ship).
   143→- Added `bin/gstack-slug` helper (5-line bash) with unit tests. Outputs `SLUG=` and `BRANCH=` lines, sanitizes `/` to `-`.
   144→- New TODOs: smart review relevance detection (P3), `/merge` skill for review-gated PR merge (P2).
   145→
   146→## 0.5.0 — 2026-03-16
   147→
   148→- **Your site just got a design review.** `/plan-design-review` opens your site and reviews it like a senior product designer — typography, spacing, hierarchy, color, responsive, interactions, and AI slop detection. Get letter grades (A-F) per category, a dual headline "Design Score" + "AI Slop Score", and a structured first impression that doesn't pull punches.
   149→- **It can fix what it finds, too.** `/qa-design-review` runs the same designer's eye audit, then iteratively fixes design issues in your source code with atomic `style(design):` commits and before/after screenshots. CSS-safe by default, with a stricter self-regulation heuristic tuned for styling changes.
   150→- **Know your actual design system.** Both skills extract your live site's fonts, colors, heading scale, and spacing patterns via JS — then offer to save the inferred system as a `DESIGN.md` baseline. Finally know how many fonts you're actually using.
   151→- **AI Slop detection is a headline metric.** Every report opens with two scores: Design Score and AI Slop Score. The AI slop checklist catches the 10 most recognizable AI-generated patterns — the 3-column feature grid, purple gradients, decorative blobs, emoji bullets, generic hero copy.
   152→- **Design regression tracking.** Reports write a `design-baseline.json`. Next run auto-compares: per-category grade deltas, new findings, resolved findings. Watch your design score improve over time.
   153→- **80-item design audit checklist** across 10 categories: visual hierarchy, typography, color/contrast, spacing/layout, interaction states, responsive, motion, content/microcopy, AI slop, and performance-as-design. Distilled from Vercel's 100+ rules, Anthropic's frontend design skill, and 6 other design frameworks.
   154→
   155→### For contributors
   156→
   157→- Added `{{DESIGN_METHODOLOGY}}` resolver to `gen-skill-docs.ts` — shared design audit methodology injected into both `/plan-design-review` and `/qa-design-review` templates, following the `{{QA_METHODOLOGY}}` pattern.
   158→- Added `~/.gstack-dev/plans/` as a local plans directory for long-range vision docs (not checked in). CLAUDE.md and TODOS.md updated.
   159→- Added `/setup-design-md` to TODOS.md (P2) for interactive DESIGN.md creation from scratch.
   160→
   161→## 0.4.5 — 2026-03-16
   162→
   163→- **Review findings now actually get fixed, not just listed.** `/review` and `/ship` used to print informational findings (dead code, test gaps, N+1 queries) and then ignore them. Now every finding gets action: obvious mechanical fixes are applied automatically, and genuinely ambiguous issues are batched into a single question instead of 8 separate prompts. You see `[AUTO-FIXED] file:line Problem → what was done` for each auto-fix.
   164→- **You control the line between "just fix it" and "ask me first."** Dead code, stale comments, N+1 queries get auto-fixed. Security issues, race conditions, design decisions get surfaced for your call. The classification lives in one place (`review/checklist.md`) so both `/review` and `/ship` stay in sync.
   165→
   166→### Fixed
   167→
   168→- **`$B js "const x = await fetch(...); return x.status"` now works.** The `js` command used to wrap everything as an expression — so `const`, semicolons, and multi-line code all broke. It now detects statements and uses a block wrapper, just like `eval` already did.
   169→- **Clicking a dropdown option no longer hangs forever.** If an agent sees `@e3 [option] "Admin"` in a snapshot and runs `click @e3`, gstack now auto-selects that option instead of hanging on an impossible Playwright click. The right thing just happens.
   170→- **When click is the wrong tool, gstack tells you.** Clicking an `<option>` via CSS selector used to time out with a cryptic Playwright error. Now you get: `"Use 'browse select' instead of 'click' for dropdown options."`
   171→
   172→### For contributors
   173→
   174→- Gate Classification → Severity Classification rename (severity determines presentation order, not whether you see a prompt).
   175→- Fix-First Heuristic section added to `review/checklist.md` — the canonical AUTO-FIX vs ASK classification.
   176→- New validation test: `Fix-First Heuristic exists in checklist and is referenced by review + ship`.
   177→- Extracted `needsBlockWrapper()` and `wrapForEvaluate()` helpers in `read-commands.ts` — shared by both `js` and `eval` commands (DRY).
   178→- Added `getRefRole()` to `BrowserManager` — exposes ARIA role for ref selectors without changing `resolveRef` return type.
   179→- Click handler auto-routes `[role=option]` refs to `selectOption()` via parent `<select>`, with DOM `tagName` check to avoid blocking custom listbox components.
   180→- 6 new tests: multi-line js, semicolons, statement keywords, simple expressions, option auto-routing, CSS option error guidance.
   181→
   182→## 0.4.4 — 2026-03-16
   183→
   184→- **New releases detected in under an hour, not half a day.** The update check cache was set to 12 hours, which meant you could be stuck on an old version all day while new releases dropped. Now "you're up to date" expires after 60 minutes, so you'll see upgrades within the hour. "Upgrade available" still nags for 12 hours (that's the point).
   185→- **`/gstack-upgrade` always checks for real.** Running `/gstack-upgrade` directly now bypasses the cache and does a fresh check against GitHub. No more "you're already on the latest" when you're not.
   186→
   187→### For contributors
   188→
   189→- Split `last-update-check` cache TTL: 60 min for `UP_TO_DATE`, 720 min for `UPGRADE_AVAILABLE`.
   190→- Added `--force` flag to `bin/gstack-update-check` (deletes cache file before checking).
   191→- 3 new tests: `--force` busts UP_TO_DATE cache, `--force` busts UPGRADE_AVAILABLE cache, 60-min TTL boundary test with `utimesSync`.
   192→
   193→## 0.4.3 — 2026-03-16
   194→
   195→- **New `/document-release` skill.** Run it after `/ship` but before merging — it reads every doc file in your project, cross-references the diff, and updates README, ARCHITECTURE, CONTRIBUTING, CHANGELOG, and TODOS to match what you actually shipped. Risky changes get surfaced as questions; everything else is automatic.
   196→- **Every question is now crystal clear, every time.** You used to need 3+ sessions running before gstack would give you full context and plain English explanations. Now every question — even in a single session — tells you the project, branch, and what's happening, explained simply enough to understand mid-context-switch. No more "sorry, explain it to me more simply."
   197→- **Branch name is always correct.** gstack now detects your current branch at runtime instead of relying on the snapshot from when the conversation started. Switch branches mid-session? gstack keeps up.
   198→
   199→### For contributors
   200→
   201→- Merged ELI16 rules into base AskUserQuestion format — one format instead of two, no `_SESSIONS >= 3` conditional.
   202→- Added `_BRANCH` detection to preamble bash block (`git branch --show-current` with fallback).
   203→- Added regression guard tests for branch detection and simplification rules.
   204→
   205→## 0.4.2 — 2026-03-16
   206→
   207→- **`$B js "await fetch(...)"` now just works.** Any `await` expression in `$B js` or `$B eval` is automatically wrapped in an async context. No more `SyntaxError: await is only valid in async functions`. Single-line eval files return values directly; multi-line files use explicit `return`.
   208→- **Contributor mode now reflects, not just reacts.** Instead of only filing reports when something breaks, contributor mode now prompts periodic reflection: "Rate your gstack experience 0-10. Not a 10? Think about why." Catches quality-of-life issues and friction that passive detection misses. Reports now include a 0-10 rating and "What would make this a 10" to focus on actionable improvements.
   209→- **Skills now respect your branch target.** `/ship`, `/review`, `/qa`, and `/plan-ceo-review` detect which branch your PR actually targets instead of assuming `main`. Stacked branches, Conductor workspaces targeting feature branches, and repos using `master` all just work now.
   210→- **`/retro` works on any default branch.** Repos using `master`, `develop`, or other default branch names are detected automatically — no more empty retros because the branch name was wrong.
   211→- **New `{{BASE_BRANCH_DETECT}}` placeholder** for skill authors — drop it into any template and get 3-step branch detection (PR base → repo default → fallback) for free.
   212→- **3 new E2E smoke tests** validate base branch detection works end-to-end across ship, review, and retro skills.
   213→
   214→### For contributors
   215→
   216→- Added `hasAwait()` helper with comment-stripping to avoid false positives on `// await` in eval files.
   217→- Smart eval wrapping: single-line → expression `(...)`, multi-line → block `{...}` with explicit `return`.
   218→- 6 new async wrapping unit tests, 40 new contributor mode preamble validation tests.
   219→- Calibration example framed as historical ("used to fail") to avoid implying a live bug post-fix.
   220→- Added "Writing SKILL templates" section to CLAUDE.md — rules for natural language over bash-isms, dynamic branch detection, self-contained code blocks.
   221→- Hardcoded-main regression test scans all `.tmpl` files for git commands with hardcoded `main`.
   222→- QA template cleaned up: removed `REPORT_DIR` shell variable, simplified port detection to prose.
   223→- gstack-upgrade template: explicit cross-step prose for variable references between bash blocks.
   224→
   225→## 0.4.1 — 2026-03-16
   226→
   227→- **gstack now notices when it screws up.** Turn on contributor mode (`gstack-config set gstack_contributor true`) and gstack automatically writes up what went wrong — what you were doing, what broke, repro steps. Next time something annoys you, the bug report is already written. Fork gstack and fix it yourself.
   228→- **Juggling multiple sessions? gstack keeps up.** When you have 3+ gstack windows open, every question now tells you which project, which branch, and what you were working on. No more staring at a question thinking "wait, which window is this?"
   229→- **Every question now comes with a recommendation.** Instead of dumping options on you and making you think, gstack tells you what it would pick and why. Same clear format across every skill.
   230→- **/review now catches forgotten enum handlers.** Add a new status, tier, or type constant? /review traces it through every switch statement, allowlist, and filter in your codebase — not just the files you changed. Catches the "added the value but forgot to handle it" class of bugs before they ship.
   231→
   232→### For contributors
   233→
   234→- Renamed `{{UPDATE_CHECK}}` to `{{PREAMBLE}}` across all 11 skill templates — one startup block now handles update check, session tracking, contributor mode, and question formatting.
   235→- DRY'd plan-ceo-review and plan-eng-review question formatting to reference the preamble baseline instead of duplicating rules.
   236→- Added CHANGELOG style guide and vendored symlink awareness docs to CLAUDE.md.
   237→
   238→## 0.4.0 — 2026-03-16
   239→
   240→### Added
   241→- **QA-only skill** (`/qa-only`) — report-only QA mode that finds and documents bugs without making fixes. Hand off a clean bug report to your team without the agent touching your code.
   242→- **QA fix loop** — `/qa` now runs a find-fix-verify cycle: discover bugs, fix them, commit, re-navigate to confirm the fix took. One command to go from broken to shipped.
   243→- **Plan-to-QA artifact flow** — `/plan-eng-review` writes test-plan artifacts that `/qa` picks up automatically. Your engineering review now feeds directly into QA testing with no manual copy-paste.
   244→- **`{{QA_METHODOLOGY}}` DRY placeholder** — shared QA methodology block injected into both `/qa` and `/qa-only` templates. Keeps both skills in sync when you update testing standards.
   245→- **Eval efficiency metrics** — turns, duration, and cost now displayed across all eval surfaces with natural-language **Takeaway** commentary. See at a glance whether your prompt changes made the agent faster or slower.
   246→- **`generateCommentary()` engine** — interprets comparison deltas so you don't have to: flags regressions, notes improvements, and produces an overall efficiency summary.
   247→- **Eval list columns** — `bun run eval:list` now shows Turns and Duration per run. Spot expensive or slow runs instantly.
   248→- **Eval summary per-test efficiency** — `bun run eval:summary` shows average turns/duration/cost per test across runs. Identify which tests are costing you the most over time.
   249→- **`judgePassed()` unit tests** — extracted and tested the pass/fail judgment logic.
   250→- **3 new E2E tests** — qa-only no-fix guardrail, qa fix loop with commit verification, plan-eng-review test-plan artifact.
   251→- **Browser ref staleness detection** — `resolveRef()` now checks element count to detect stale refs after page mutations. SPA navigation no longer causes 30-second timeouts on missing elements.
   252→- 3 new snapshot tests for ref staleness.
   253→
   254→### Changed
   255→- QA skill prompt restructured with explicit two-cycle workflow (find → fix → verify).
   256→- `formatComparison()` now shows per-test turns and duration deltas alongside cost.
   257→- `printSummary()` shows turns and duration columns.
   258→- `eval-store.test.ts` fixed pre-existing `_partial` file assertion bug.
   259→
   260→### Fixed
   261→- Browser ref staleness — refs collected before page mutation (e.g. SPA navigation) are now detected and re-collected. Eliminates a class of flaky QA failures on dynamic sites.
   262→
   263→## 0.3.9 — 2026-03-15
   264→
   265→### Added
   266→- **`bin/gstack-config` CLI** — simple get/set/list interface for `~/.gstack/config.yaml`. Used by update-check and upgrade skill for persistent settings (auto_upgrade, update_check).
   267→- **Smart update check** — 12h cache TTL (was 24h), exponential snooze backoff (24h → 48h → 1 week) when user declines upgrades, `update_check: false` config option to disable checks entirely. Snooze resets when a new version is released.
   268→- **Auto-upgrade mode** — set `auto_upgrade: true` in config or `GSTACK_AUTO_UPGRADE=1` env var to skip the upgrade prompt and update automatically.
   269→- **4-option upgrade prompt** — "Yes, upgrade now", "Always keep me up to date", "Not now" (snooze), "Never ask again" (disable).
   270→- **Vendored copy sync** — `/gstack-upgrade` now detects and updates local vendored copies in the current project after upgrading the primary install.
   271→- 25 new tests: 11 for gstack-config CLI, 14 for snooze/config paths in update-check.
   272→
   273→### Changed
   274→- README upgrade/troubleshooting sections simplified to reference `/gstack-upgrade` instead of long paste commands.
   275→- Upgrade skill template bumped to v1.1.0 with `Write` tool permission for config editing.
   276→- All SKILL.md preambles updated with new upgrade flow description.
   277→
   278→## 0.3.8 — 2026-03-14
   279→
   280→### Added
   281→- **TODOS.md as single source of truth** — merged `TODO.md` (roadmap) and `TODOS.md` (near-term) into one file organized by skill/component with P0-P4 priority ordering and a Completed section.
   282→- **`/ship` Step 5.5: TODOS.md management** — auto-detects completed items from the diff, marks them done with version annotations, offers to create/reorganize TODOS.md if missing or unstructured.
   283→- **Cross-skill TODOS awareness** — `/plan-ceo-review`, `/plan-eng-review`, `/retro`, `/review`, and `/qa` now read TODOS.md for project context. `/retro` adds Backlog Health metric (open counts, P0/P1 items, churn).
   284→- **Shared `review/TODOS-format.md`** — canonical TODO item format referenced by `/ship` and `/plan-ceo-review` to prevent format drift (DRY).
   285→- **Greptile 2-tier reply system** — Tier 1 (friendly, inline diff + explanation) for first responses; Tier 2 (firm, full evidence chain + re-rank request) when Greptile re-flags after a prior reply.
   286→- **Greptile reply templates** — structured templates in `greptile-triage.md` for fixes (inline diff), already-fixed (what was done), and false positives (evidence + suggested re-rank). Replaces vague one-line replies.
   287→- **Greptile escalation detection** — explicit algorithm to detect prior GStack replies on comment threads and auto-escalate to Tier 2.
   288→- **Greptile severity re-ranking** — replies now include `**Suggested re-rank:**` when Greptile miscategorizes issue severity.
   289→- Static validation tests for `TODOS-format.md` references across skills.
   290→
   291→### Fixed
   292→- **`.gitignore` append failures silently swallowed** — `ensureStateDir()` bare `catch {}` replaced with ENOENT-only silence; non-ENOENT errors (EACCES, ENOSPC) logged to `.gstack/browse-server.log`.
   293→
   294→### Changed
   295→- `TODO.md` deleted — all items merged into `TODOS.md`.
   296→- `/ship` Step 3.75 and `/review` Step 5 now reference reply templates and escalation detection from `greptile-triage.md`.
   297→- `/ship` Step 6 commit ordering includes TODOS.md in the final commit alongside VERSION + CHANGELOG.
   298→- `/ship` Step 8 PR body includes TODOS section.
   299→
   300→## 0.3.7 — 2026-03-14
   301→
   302→### Added
   303→- **Screenshot element/region clipping** — `screenshot` command now supports element crop via CSS selector or @ref (`screenshot "#hero" out.png`, `screenshot @e3 out.png`), region clip (`screenshot --clip x,y,w,h out.png`), and viewport-only mode (`screenshot --viewport out.png`). Uses Playwright's native `locator.screenshot()` and `page.screenshot({ clip })`. Full page remains the default.
   304→- 10 new tests covering all screenshot modes (viewport, CSS, @ref, clip) and error paths (unknown flag, mutual exclusion, invalid coords, path validation, nonexistent selector).
   305→
   306→## 0.3.6 — 2026-03-14
   307→
   308→### Added
   309→- **E2E observability** — heartbeat file (`~/.gstack-dev/e2e-live.json`), per-run log directory (`~/.gstack-dev/e2e-runs/{runId}/`), progress.log, per-test NDJSON transcripts, persistent failure transcripts. All I/O non-fatal.
   310→- **`bun run eval:watch`** — live terminal dashboard reads heartbeat + partial eval file every 1s. Shows completed tests, current test with turn/tool info, stale detection (>10min), `--tail` for progress.log.
   311→- **Incremental eval saves** — `savePartial()` writes `_partial-e2e.json` after each test completes. Crash-resilient: partial results survive killed runs. Never cleaned up.
   312→- **Machine-readable diagnostics** — `exit_reason`, `timeout_at_turn`, `last_tool_call` fields in eval JSON. Enables `jq` queries for automated fix loops.
   313→- **API connectivity pre-check** — E2E suite throws immediately on ConnectionRefused before burning test budget.
   314→- **`is_error` detection** — `claude -p` can return `subtype: "success"` with `is_error: true` on API failures. Now correctly classified as `error_api`.
   315→- **Stream-json NDJSON parser** — `parseNDJSON()` pure function for real-time E2E progress from `claude -p --output-format stream-json --verbose`.
   316→- **Eval persistence** — results saved to `~/.gstack-dev/evals/` with auto-comparison against previous run.
   317→- **Eval CLI tools** — `eval:list`, `eval:compare`, `eval:summary` for inspecting eval history.
   318→- **All 9 skills converted to `.tmpl` templates** — plan-ceo-review, plan-eng-review, retro, review, ship now use `{{UPDATE_CHECK}}` placeholder. Single source of truth for update check preamble.
   319→- **3-tier eval suite** — Tier 1: static validation (free), Tier 2: E2E via `claude -p` (~$3.85/run), Tier 3: LLM-as-judge (~$0.15/run). Gated by `EVALS=1`.
   320→- **Planted-bug outcome testing** — eval fixtures with known bugs, LLM judge scores detection.
   321→- 15 observability unit tests covering heartbeat schema, progress.log format, NDJSON naming, savePartial, finalize, watcher rendering, stale detection, non-fatal I/O.
   322→- E2E tests for plan-ceo-review, plan-eng-review, retro skills.
   323→- Update-check exit code regression tests.
   324→- `test/helpers/skill-parser.ts` — `getRemoteSlug()` for git remote detection.
   325→
   326→### Fixed
   327→- **Browse binary discovery broken for agents** — replaced `find-browse` indirection with explicit `browse/dist/browse` path in SKILL.md setup blocks.
   328→- **Update check exit code 1 misleading agents** — added `|| true` to prevent non-zero exit when no update available.
   329→- **browse/SKILL.md missing setup block** — added `{{BROWSE_SETUP}}` placeholder.
   330→- **plan-ceo-review timeout** — init git repo in test dir, skip codebase exploration, bump timeout to 420s.
   331→- Planted-bug eval reliability — simplified prompts, lowered detection baselines, resilient to max_turns flakes.
   332→
   333→### Changed
   334→- **Template system expanded** — `{{UPDATE_CHECK}}` and `{{BROWSE_SETUP}}` placeholders in `gen-skill-docs.ts`. All browse-using skills generate from single source of truth.
   335→- Enriched 14 command descriptions with specific arg formats, valid values, error behavior, and return types.
   336→- Setup block checks workspace-local path first (for development), falls back to global install.
   337→- LLM eval judge upgraded from Haiku to Sonnet 4.6.
   338→- `generateHelpText()` auto-generated from COMMAND_DESCRIPTIONS (replaces hand-maintained help text).
   339→
   340→## 0.3.3 — 2026-03-13
   341→
   342→### Added
   343→- **SKILL.md template system** — `.tmpl` files with `{{COMMAND_REFERENCE}}` and `{{SNAPSHOT_FLAGS}}` placeholders, auto-generated from source code at build time. Structurally prevents command drift between docs and code.
   344→- **Command registry** (`browse/src/commands.ts`) — single source of truth for all browse commands with categories and enriched descriptions. Zero side effects, safe to import from build scripts and tests.
   345→- **Snapshot flags metadata** (`SNAPSHOT_FLAGS` array in `browse/src/snapshot.ts`) — metadata-driven parser replaces hand-coded switch/case. Adding a flag in one place updates the parser, docs, and tests.
   346→- **Tier 1 static validation** — 43 tests: parses `$B` commands from SKILL.md code blocks, validates against command registry and snapshot flag metadata
   347→- **Tier 2 E2E tests** via Agent SDK — spawns real Claude sessions, runs skills, scans for browse errors. Gated by `SKILL_E2E=1` env var (~$0.50/run)
   348→- **Tier 3 LLM-as-judge evals** — Haiku scores generated docs on clarity/completeness/actionability (threshold ≥4/5), plus regression test vs hand-maintained baseline. Gated by `ANTHROPIC_API_KEY`
   349→- **`bun run skill:check`** — health dashboard showing all skills, command counts, validation status, template freshness
   350→- **`bun run dev:skill`** — watch mode that regenerates and validates SKILL.md on every template or source file change
   351→- **CI workflow** (`.github/workflows/skill-docs.yml`) — runs `gen:skill-docs` on push/PR, fails if generated output differs from committed files
   352→- `bun run gen:skill-docs` script for manual regeneration
   353→- `bun run test:eval` for LLM-as-judge evals
   354→- `test/helpers/skill-parser.ts` — extracts and validates `$B` commands from Markdown
   355→- `test/helpers/session-runner.ts` — Agent SDK wrapper with error pattern scanning and transcript saving
   356→- **ARCHITECTURE.md** — design decisions document covering daemon model, security, ref system, logging, crash recovery
   357→- **Conductor integration** (`conductor.json`) — lifecycle hooks for workspace setup/teardown
   358→- **`.env` propagation** — `bin/dev-setup` copies `.env` from main worktree into Conductor workspaces automatically
   359→- `.env.example` template for API key configuration
   360→
   361→### Changed
   362→- Build now runs `gen:skill-docs` before compiling binaries
   363→- `parseSnapshotArgs` is metadata-driven (iterates `SNAPSHOT_FLAGS` instead of switch/case)
   364→- `server.ts` imports command sets from `commands.ts` instead of declaring inline
   365→- SKILL.md and browse/SKILL.md are now generated files (edit the `.tmpl` instead)
   366→
   367→## 0.3.2 — 2026-03-13
   368→
   369→### Fixed
   370→- Cookie import picker now returns JSON instead of HTML — `jsonResponse()` referenced `url` out of scope, crashing every API call
   371→- `help` command routed correctly (was unreachable due to META_COMMANDS dispatch ordering)
   372→- Stale servers from global install no longer shadow local changes — removed legacy `~/.claude/skills/gstack` fallback from `resolveServerScript()`
   373→- Crash log path references updated from `/tmp/` to `.gstack/`
   374→
   375→### Added
   376→- **Diff-aware QA mode** — `/qa` on a feature branch auto-analyzes `git diff`, identifies affected pages/routes, detects the running app on localhost, and tests only what changed. No URL needed.
   377→- **Project-local browse state** — state file, logs, and all server state now live in `.gstack/` inside the project root (detected via `git rev-parse --show-toplevel`). No more `/tmp` state files.
   378→- **Shared config module** (`browse/src/config.ts`) — centralizes path resolution for CLI and server, eliminates duplicated port/state logic
   379→- **Random port selection** — server picks a random port 10000-60000 instead of scanning 9400-9409. No more CONDUCTOR_PORT magic offset. No more port collisions across workspaces.
   380→- **Binary version tracking** — state file includes `binaryVersion` SHA; CLI auto-restarts the server when the binary is rebuilt
   381→- **Legacy /tmp cleanup** — CLI scans for and removes old `/tmp/browse-server*.json` files, verifying PID ownership before sending signals
   382→- **Greptile integration** — `/review` and `/ship` fetch and triage Greptile bot comments; `/retro` tracks Greptile batting average across weeks
   383→- **Local dev mode** — `bin/dev-setup` symlinks skills from the repo for in-place development; `bin/dev-teardown` restores global install
   384→- `help` command — agents can self-discover all commands and snapshot flags
   385→- Version-aware `find-browse` with META signal protocol — detects stale binaries and prompts agents to update
   386→- `browse/dist/find-browse` compiled binary with git SHA comparison against origin/main (4hr cached)
   387→- `.version` file written at build time for binary version tracking
   388→- Route-level tests for cookie picker (13 tests) and find-browse version check (10 tests)
   389→- Config resolution tests (14 tests) covering git root detection, BROWSE_STATE_FILE override, ensureStateDir, readVersionHash, resolveServerScript, and version mismatch detection
   390→- Browser interaction guidance in CLAUDE.md — prevents Claude from using mcp\_\_claude-in-chrome\_\_\* tools
   391→- CONTRIBUTING.md with quick start, dev mode explanation, and instructions for testing branches in other repos
   392→
   393→### Changed
   394→- State file location: `.gstack/browse.json` (was `/tmp/browse-server.json`)
   395→- Log files location: `.gstack/browse-{console,network,dialog}.log` (was `/tmp/browse-*.log`)
   396→- Atomic state file writes: `.json.tmp` → rename (prevents partial reads)
   397→- CLI passes `BROWSE_STATE_FILE` to spawned server (server derives all paths from it)
   398→- SKILL.md setup checks parse META signals and handle `META:UPDATE_AVAILABLE`
   399→- `/qa` SKILL.md now describes four modes (diff-aware, full, quick, regression) with diff-aware as the default on feature branches
   400→- `jsonResponse`/`errorResponse` use options objects to prevent positional parameter confusion
   401→- Build script compiles both `browse` and `find-browse` binaries, cleans up `.bun-build` temp files
   402→- README updated with Greptile setup instructions, diff-aware QA examples, and revised demo transcript
   403→
   404→### Removed
   405→- `CONDUCTOR_PORT` magic offset (`browse_port = CONDUCTOR_PORT - 45600`)
   406→- Port scan range 9400-9409
   407→- Legacy fallback to `~/.claude/skills/gstack/browse/src/server.ts`
   408→- `DEVELOPING_GSTACK.md` (renamed to CONTRIBUTING.md)
   409→
   410→## 0.3.1 — 2026-03-12
   411→
   412→### Phase 3.5: Browser cookie import
   413→
   414→- `cookie-import-browser` command — decrypt and import cookies from real Chromium browsers (Comet, Chrome, Arc, Brave, Edge)
   415→- Interactive cookie picker web UI served from the browse server (dark theme, two-panel layout, domain search, import/remove)
   416→- Direct CLI import with `--domain` flag for non-interactive use
   417→- `/setup-browser-cookies` skill for Claude Code integration
   418→- macOS Keychain access with async 10s timeout (no event loop blocking)
   419→- Per-browser AES key caching (one Keychain prompt per browser per session)
   420→- DB lock fallback: copies locked cookie DB to /tmp for safe reads
   421→- 18 unit tests with encrypted cookie fixtures
   422→
   423→## 0.3.0 — 2026-03-12
   424→
   425→### Phase 3: /qa skill — systematic QA testing
   426→
   427→- New `/qa` skill with 6-phase workflow (Initialize, Authenticate, Orient, Explore, Document, Wrap up)
   428→- Three modes: full (systematic, 5-10 issues), quick (30-second smoke test), regression (compare against baseline)
   429→- Issue taxonomy: 7 categories, 4 severity levels, per-page exploration checklist
   430→- Structured report template with health score (0-100, weighted across 7 categories)
   431→- Framework detection guidance for Next.js, Rails, WordPress, and SPAs
   432→- `browse/bin/find-browse` — DRY binary discovery using `git rev-parse --show-toplevel`
   433→
   434→### Phase 2: Enhanced browser
   435→
   436→- Dialog handling: auto-accept/dismiss, dialog buffer, prompt text support
   437→- File upload: `upload <sel> <file1> [file2...]`
   438→- Element state checks: `is visible|hidden|enabled|disabled|checked|editable|focused <sel>`
   439→- Annotated screenshots with ref labels overlaid (`snapshot -a`)
   440→- Snapshot diffing against previous snapshot (`snapshot -D`)
   441→- Cursor-interactive element scan for non-ARIA clickables (`snapshot -C`)
   442→- `wait --networkidle` / `--load` / `--domcontentloaded` flags
   443→- `console --errors` filter (error + warning only)
   444→- `cookie-import <json-file>` with auto-fill domain from page URL
   445→- CircularBuffer O(1) ring buffer for console/network/dialog buffers
   446→- Async buffer flush with Bun.write()
   447→- Health check with page.evaluate + 2s timeout
   448→- Playwright error wrapping — actionable messages for AI agents
   449→- Context recreation preserves cookies/storage/URLs (useragent fix)
   450→- SKILL.md rewritten as QA-oriented playbook with 10 workflow patterns
   451→- 166 integration tests (was ~63)
   452→
   453→## 0.0.2 — 2026-03-12
   454→
   455→- Fix project-local `/browse` installs — compiled binary now resolves `server.ts` from its own directory instead of assuming a global install exists
   456→- `setup` rebuilds stale binaries (not just missing ones) and exits non-zero if the build fails
   457→- Fix `chain` command swallowing real errors from write commands (e.g. navigation timeout reported as "Unknown meta command")
   458→- Fix unbounded restart loop in CLI when server crashes repeatedly on the same command
   459→- Cap console/network buffers at 50k entries (ring buffer) instead of growing without bound
   460→- Fix disk flush stopping silently after buffer hits the 50k cap
   461→- Fix `ln -snf` in setup to avoid creating nested symlinks on upgrade
   462→- Use `git fetch && git reset --hard` instead of `git pull` for upgrades (handles force-pushes)
   463→- Simplify install: global-first with optional project copy (replaces submodule approach)
   464→- Restructured README: hero, before/after, demo transcript, troubleshooting section
   465→- Six skills (added `/retro`)
   466→
   467→## 0.0.1 — 2026-03-11
   468→
   469→Initial release.
   470→
   471→- Five skills: `/plan-ceo-review`, `/plan-eng-review`, `/review`, `/ship`, `/browse`
   472→- Headless browser CLI with 40+ commands, ref-based interaction, persistent Chromium daemon
   473→- One-command install as Claude Code skills (submodule or global clone)
   474→- `setup` script for binary compilation and skill symlinking
   475→


/root/projects/gits/gstack/SKILL.md.tmpl
/root/projects/gits/gstack/browse/SKILL.md.tmpl
/root/projects/gits/gstack/design-consultation/SKILL.md.tmpl
/root/projects/gits/gstack/design-review/SKILL.md.tmpl
/root/projects/gits/gstack/document-release/SKILL.md.tmpl
/root/projects/gits/gstack/gstack-upgrade/SKILL.md.tmpl
/root/projects/gits/gstack/plan-ceo-review/SKILL.md.tmpl
/root/projects/gits/gstack/plan-design-review/SKILL.md.tmpl
/root/projects/gits/gstack/plan-eng-review/SKILL.md.tmpl
/root/projects/gits/gstack/qa-only/SKILL.md.tmpl
/root/projects/gits/gstack/qa/SKILL.md.tmpl
/root/projects/gits/gstack/retro/SKILL.md.tmpl
/root/projects/gits/gstack/review/SKILL.md.tmpl
/root/projects/gits/gstack/setup-browser-cookies/SKILL.md.tmpl
/root/projects/gits/gstack/ship/SKILL.md.tmpl


Error: EISDIR: illegal operation on a directory, read '/root/projects/gits/gstack/test/helpers'


/root/projects/gits/gstack/SKILL.md
/root/projects/gits/gstack/browse/SKILL.md
/root/projects/gits/gstack/design-consultation/SKILL.md
/root/projects/gits/gstack/design-review/SKILL.md
/root/projects/gits/gstack/document-release/SKILL.md
/root/projects/gits/gstack/gstack-upgrade/SKILL.md
/root/projects/gits/gstack/plan-ceo-review/SKILL.md
/root/projects/gits/gstack/plan-design-review/SKILL.md
/root/projects/gits/gstack/plan-eng-review/SKILL.md
/root/projects/gits/gstack/qa-only/SKILL.md
/root/projects/gits/gstack/qa/SKILL.md
/root/projects/gits/gstack/retro/SKILL.md
/root/projects/gits/gstack/review/SKILL.md
/root/projects/gits/gstack/setup-browser-cookies/SKILL.md
/root/projects/gits/gstack/ship/SKILL.md


<persisted-output>
Output too large (61.2KB). Full output saved to: /root/.claude/projects/-root-projects-gits-gstack/a8cf046e-8466-4591-a0a4-a6ca509bc321/tool-results/toolu_017UBcWzHAKSBpre5LaZi15y.txt

Preview (first 2KB):
     1→#!/usr/bin/env bun
     2→/**
     3→ * Generate SKILL.md files from .tmpl templates.
     4→ *
     5→ * Pipeline:
     6→ *   read .tmpl → find {{PLACEHOLDERS}} → resolve from source → format → write .md
     7→ *
     8→ * Supports --dry-run: generate to memory, exit 1 if different from committed file.
     9→ * Used by skill:check and CI freshness checks.
    10→ */
    11→
    12→import { COMMAND_DESCRIPTIONS } from '../browse/src/commands';
    13→import { SNAPSHOT_FLAGS } from '../browse/src/snapshot';
    14→import * as fs from 'fs';
    15→import * as path from 'path';
    16→
    17→const ROOT = path.resolve(import.meta.dir, '..');
    18→const DRY_RUN = process.argv.includes('--dry-run');
    19→
    20→// ─── Placeholder Resolvers ──────────────────────────────────
    21→
    22→function generateCommandReference(): string {
    23→  // Group commands by category
    24→  const groups = new Map<string, Array<{ command: string; description: string; usage?: string }>>();
    25→  for (const [cmd, meta] of Object.entries(COMMAND_DESCRIPTIONS)) {
    26→    const list = groups.get(meta.category) || [];
    27→    list.push({ command: cmd, description: meta.description, usage: meta.usage });
    28→    groups.set(meta.category, list);
    29→  }
    30→
    31→  // Category display order
    32→  const categoryOrder = [
    33→    'Navigation', 'Reading', 'Interaction', 'Inspection',
    34→    'Visual', 'Snapshot', 'Meta', 'Tabs', 'Server',
    35→  ];
    36→
    37→  const sections: string[] = [];
    38→  for (const category of categoryOrder) {
    39→    const commands = groups.get(category);
    40→    if (!commands || commands.length === 0) continue;
    41→
    42→    // Sort alphabetically within category
    43→    commands.sort((a, b) => a.command.localeCompare(b.command));
    44→
    45→    sections.push(`### ${category}`);
    46→    sections.push('| Command | Description |');
    47→    sections.push('|---------|-------------|');
...
</persisted-output>


     1→/**
     2→ * Diff-based test selection for E2E and LLM-judge evals.
     3→ *
     4→ * Each test declares which source files it depends on ("touchfiles").
     5→ * The test runner checks `git diff` and only runs tests whose
     6→ * dependencies were modified. Override with EVALS_ALL=1 to run everything.
     7→ */
     8→
     9→import { spawnSync } from 'child_process';
    10→
    11→// --- Glob matching ---
    12→
    13→/**
    14→ * Match a file path against a glob pattern.
    15→ * Supports:
    16→ *   ** — match any number of path segments
    17→ *   *  — match within a single segment (no /)
    18→ */
    19→export function matchGlob(file: string, pattern: string): boolean {
    20→  const regexStr = pattern
    21→    .replace(/\./g, '\\.')
    22→    .replace(/\*\*/g, '{{GLOBSTAR}}')
    23→    .replace(/\*/g, '[^/]*')
    24→    .replace(/\{\{GLOBSTAR\}\}/g, '.*');
    25→  return new RegExp(`^${regexStr}$`).test(file);
    26→}
    27→
    28→// --- Touchfile maps ---
    29→
    30→/**
    31→ * E2E test touchfiles — keyed by testName (the string passed to runSkillTest).
    32→ * Each test lists the file patterns that, if changed, require the test to run.
    33→ */
    34→export const E2E_TOUCHFILES: Record<string, string[]> = {
    35→  // Browse core
    36→  'browse-basic':    ['browse/src/**'],
    37→  'browse-snapshot': ['browse/src/**'],
    38→
    39→  // SKILL.md setup + preamble (depend on ROOT SKILL.md only)
    40→  'skillmd-setup-discovery':  ['SKILL.md', 'SKILL.md.tmpl'],
    41→  'skillmd-no-local-binary':  ['SKILL.md', 'SKILL.md.tmpl'],
    42→  'skillmd-outside-git':      ['SKILL.md', 'SKILL.md.tmpl'],
    43→  'contributor-mode':         ['SKILL.md', 'SKILL.md.tmpl'],
    44→  'session-awareness':        ['SKILL.md', 'SKILL.md.tmpl'],
    45→
    46→  // QA
    47→  'qa-quick':       ['qa/**', 'browse/src/**'],
    48→  'qa-b6-static':   ['qa/**', 'browse/src/**', 'browse/test/fixtures/qa-eval.html', 'test/fixtures/qa-eval-ground-truth.json'],
    49→  'qa-b7-spa':      ['qa/**', 'browse/src/**', 'browse/test/fixtures/qa-eval-spa.html', 'test/fixtures/qa-eval-spa-ground-truth.json'],
    50→  'qa-b8-checkout': ['qa/**', 'browse/src/**', 'browse/test/fixtures/qa-eval-checkout.html', 'test/fixtures/qa-eval-checkout-ground-truth.json'],
    51→  'qa-only-no-fix': ['qa-only/**', 'qa/templates/**'],
    52→  'qa-fix-loop':    ['qa/**', 'browse/src/**'],
    53→
    54→  // Review
    55→  'review-sql-injection':     ['review/**', 'test/fixtures/review-eval-vuln.rb'],
    56→  'review-enum-completeness': ['review/**', 'test/fixtures/review-eval-enum*.rb'],
    57→  'review-base-branch':       ['review/**'],
    58→  'review-design-lite':       ['review/**', 'test/fixtures/review-eval-design-slop.*'],
    59→
    60→  // Plan reviews
    61→  'plan-ceo-review':           ['plan-ceo-review/**'],
    62→  'plan-ceo-review-selective': ['plan-ceo-review/**'],
    63→  'plan-eng-review':           ['plan-eng-review/**'],
    64→  'plan-eng-review-artifact':  ['plan-eng-review/**'],
    65→
    66→  // Ship
    67→  'ship-base-branch': ['ship/**'],
    68→
    69→  // Retro
    70→  'retro':             ['retro/**'],
    71→  'retro-base-branch': ['retro/**'],
    72→
    73→  // Document-release
    74→  'document-release': ['document-release/**'],
    75→
    76→  // QA bootstrap
    77→  'qa-bootstrap': ['qa/**', 'browse/src/**', 'ship/**'],
    78→
    79→  // Ship coverage audit
    80→  'ship-coverage-audit': ['ship/**'],
    81→
    82→  // Design
    83→  'design-consultation-core':     ['design-consultation/**'],
    84→  'design-consultation-research': ['design-consultation/**'],
    85→  'design-consultation-existing': ['design-consultation/**'],
    86→  'design-consultation-preview':  ['design-consultation/**'],
    87→  'plan-design-review-plan-mode':   ['plan-design-review/**'],
    88→  'plan-design-review-no-ui-scope': ['plan-design-review/**'],
    89→  'design-review-fix':              ['design-review/**', 'browse/src/**'],
    90→
    91→  // gstack-upgrade
    92→  'gstack-upgrade-happy-path': ['gstack-upgrade/**'],
    93→};
    94→
    95→/**
    96→ * LLM-judge test touchfiles — keyed by test description string.
    97→ */
    98→export const LLM_JUDGE_TOUCHFILES: Record<string, string[]> = {
    99→  'command reference table':          ['SKILL.md', 'SKILL.md.tmpl', 'browse/src/commands.ts'],
   100→  'snapshot flags reference':         ['SKILL.md', 'SKILL.md.tmpl', 'browse/src/snapshot.ts'],
   101→  'browse/SKILL.md reference':        ['browse/SKILL.md', 'browse/SKILL.md.tmpl', 'browse/src/**'],
   102→  'setup block':                      ['SKILL.md', 'SKILL.md.tmpl'],
   103→  'regression vs baseline':           ['SKILL.md', 'SKILL.md.tmpl', 'browse/src/commands.ts', 'test/fixtures/eval-baselines.json'],
   104→  'qa/SKILL.md workflow':             ['qa/SKILL.md', 'qa/SKILL.md.tmpl'],
   105→  'qa/SKILL.md health rubric':        ['qa/SKILL.md', 'qa/SKILL.md.tmpl'],
   106→  'cross-skill greptile consistency': ['review/SKILL.md', 'review/SKILL.md.tmpl', 'ship/SKILL.md', 'ship/SKILL.md.tmpl', 'review/greptile-triage.md', 'retro/SKILL.md', 'retro/SKILL.md.tmpl'],
   107→  'baseline score pinning':           ['SKILL.md', 'SKILL.md.tmpl', 'test/fixtures/eval-baselines.json'],
   108→
   109→  // Ship & Release
   110→  'ship/SKILL.md workflow':               ['ship/SKILL.md', 'ship/SKILL.md.tmpl'],
   111→  'document-release/SKILL.md workflow':   ['document-release/SKILL.md', 'document-release/SKILL.md.tmpl'],
   112→
   113→  // Plan Reviews
   114→  'plan-ceo-review/SKILL.md modes':       ['plan-ceo-review/SKILL.md', 'plan-ceo-review/SKILL.md.tmpl'],
   115→  'plan-eng-review/SKILL.md sections':    ['plan-eng-review/SKILL.md', 'plan-eng-review/SKILL.md.tmpl'],
   116→  'plan-design-review/SKILL.md passes':   ['plan-design-review/SKILL.md', 'plan-design-review/SKILL.md.tmpl'],
   117→
   118→  // Design skills
   119→  'design-review/SKILL.md fix loop':      ['design-review/SKILL.md', 'design-review/SKILL.md.tmpl'],
   120→  'design-consultation/SKILL.md research': ['design-consultation/SKILL.md', 'design-consultation/SKILL.md.tmpl'],
   121→
   122→  // Other skills
   123→  'retro/SKILL.md instructions':          ['retro/SKILL.md', 'retro/SKILL.md.tmpl'],
   124→  'qa-only/SKILL.md workflow':            ['qa-only/SKILL.md', 'qa-only/SKILL.md.tmpl'],
   125→  'gstack-upgrade/SKILL.md upgrade flow': ['gstack-upgrade/SKILL.md', 'gstack-upgrade/SKILL.md.tmpl'],
   126→};
   127→
   128→/**
   129→ * Changes to any of these files trigger ALL tests (both E2E and LLM-judge).
   130→ */
   131→export const GLOBAL_TOUCHFILES = [
   132→  'test/helpers/session-runner.ts',
   133→  'test/helpers/eval-store.ts',
   134→  'test/helpers/llm-judge.ts',
   135→  'scripts/gen-skill-docs.ts',
   136→  'test/helpers/touchfiles.ts',
   137→  'browse/test/test-server.ts',
   138→];
   139→
   140→// --- Base branch detection ---
   141→
   142→/**
   143→ * Detect the base branch by trying refs in order.
   144→ * Returns the first valid ref, or null if none found.
   145→ */
   146→export function detectBaseBranch(cwd: string): string | null {
   147→  for (const ref of ['origin/main', 'origin/master', 'main', 'master']) {
   148→    const result = spawnSync('git', ['rev-parse', '--verify', ref], {
   149→      cwd, stdio: 'pipe', timeout: 3000,
   150→    });
   151→    if (result.status === 0) return ref;
   152→  }
   153→  return null;
   154→}
   155→
   156→/**
   157→ * Get list of files changed between base branch and HEAD.
   158→ */
   159→export function getChangedFiles(baseBranch: string, cwd: string): string[] {
   160→  const result = spawnSync('git', ['diff', '--name-only', `${baseBranch}...HEAD`], {
   161→    cwd, stdio: 'pipe', timeout: 5000,
   162→  });
   163→  if (result.status !== 0) return [];
   164→  return result.stdout.toString().trim().split('\n').filter(Boolean);
   165→}
   166→
   167→// --- Test selection ---
   168→
   169→/**
   170→ * Select tests to run based on changed files.
   171→ *
   172→ * Algorithm:
   173→ * 1. If any changed file matches a global touchfile → run ALL tests
   174→ * 2. Otherwise, for each test, check if any changed file matches its patterns
   175→ * 3. Return selected + skipped lists with reason
   176→ */
   177→export function selectTests(
   178→  changedFiles: string[],
   179→  touchfiles: Record<string, string[]>,
   180→  globalTouchfiles: string[] = GLOBAL_TOUCHFILES,
   181→): { selected: string[]; skipped: string[]; reason: string } {
   182→  const allTestNames = Object.keys(touchfiles);
   183→
   184→  // Global touchfile hit → run all
   185→  for (const file of changedFiles) {
   186→    if (globalTouchfiles.some(g => matchGlob(file, g))) {
   187→      return { selected: allTestNames, skipped: [], reason: `global: ${file}` };
   188→    }
   189→  }
   190→
   191→  // Per-test matching
   192→  const selected: string[] = [];
   193→  const skipped: string[] = [];
   194→  for (const [testName, patterns] of Object.entries(touchfiles)) {
   195→    const hit = changedFiles.some(f => patterns.some(p => matchGlob(f, p)));
   196→    (hit ? selected : skipped).push(testName);
   197→  }
   198→
   199→  return { selected, skipped, reason: 'diff' };
   200→}
   201→


     1→/**
     2→ * SKILL.md parser and validator.
     3→ *
     4→ * Extracts $B commands from code blocks, validates them against
     5→ * the command registry and snapshot flags.
     6→ *
     7→ * Used by:
     8→ *   - test/skill-validation.test.ts (Tier 1 static tests)
     9→ *   - scripts/skill-check.ts (health summary)
    10→ *   - scripts/dev-skill.ts (watch mode)
    11→ */
    12→
    13→import { ALL_COMMANDS } from '../../browse/src/commands';
    14→import { parseSnapshotArgs } from '../../browse/src/snapshot';
    15→import * as fs from 'fs';
    16→import * as path from 'path';
    17→
    18→export interface BrowseCommand {
    19→  command: string;
    20→  args: string[];
    21→  line: number;
    22→  raw: string;
    23→}
    24→
    25→export interface ValidationResult {
    26→  valid: BrowseCommand[];
    27→  invalid: BrowseCommand[];
    28→  snapshotFlagErrors: Array<{ command: BrowseCommand; error: string }>;
    29→  warnings: string[];
    30→}
    31→
    32→/**
    33→ * Extract all $B invocations from bash code blocks in a SKILL.md file.
    34→ */
    35→export function extractBrowseCommands(skillPath: string): BrowseCommand[] {
    36→  const content = fs.readFileSync(skillPath, 'utf-8');
    37→  const lines = content.split('\n');
    38→  const commands: BrowseCommand[] = [];
    39→
    40→  let inBashBlock = false;
    41→
    42→  for (let i = 0; i < lines.length; i++) {
    43→    const line = lines[i];
    44→
    45→    // Detect code block boundaries
    46→    if (line.trimStart().startsWith('```')) {
    47→      if (inBashBlock) {
    48→        inBashBlock = false;
    49→      } else if (line.trimStart().startsWith('```bash')) {
    50→        inBashBlock = true;
    51→      }
    52→      // Non-bash code blocks (```json, ```, ```js, etc.) are skipped
    53→      continue;
    54→    }
    55→
    56→    if (!inBashBlock) continue;
    57→
    58→    // Match lines with $B command invocations
    59→    // Handle multiple $B commands on one line (e.g., "$B click @e3       $B fill @e4 "value"")
    60→    const matches = line.matchAll(/\$B\s+(\S+)(?:\s+([^\$]*))?/g);
    61→    for (const match of matches) {
    62→      const command = match[1];
    63→      let argsStr = (match[2] || '').trim();
    64→
    65→      // Strip inline comments (# ...) — but not inside quotes
    66→      // Simple approach: remove everything from first unquoted # onward
    67→      let inQuote = false;
    68→      for (let j = 0; j < argsStr.length; j++) {
    69→        if (argsStr[j] === '"') inQuote = !inQuote;
    70→        if (argsStr[j] === '#' && !inQuote) {
    71→          argsStr = argsStr.slice(0, j).trim();
    72→          break;
    73→        }
    74→      }
    75→
    76→      // Parse args — handle quoted strings
    77→      const args: string[] = [];
    78→      if (argsStr) {
    79→        const argMatches = argsStr.matchAll(/"([^"]*)"|(\S+)/g);
    80→        for (const am of argMatches) {
    81→          args.push(am[1] ?? am[2]);
    82→        }
    83→      }
    84→
    85→      commands.push({
    86→        command,
    87→        args,
    88→        line: i + 1, // 1-based
    89→        raw: match[0].trim(),
    90→      });
    91→    }
    92→  }
    93→
    94→  return commands;
    95→}
    96→
    97→/**
    98→ * Extract and validate all $B commands in a SKILL.md file.
    99→ */
   100→export function validateSkill(skillPath: string): ValidationResult {
   101→  const commands = extractBrowseCommands(skillPath);
   102→  const result: ValidationResult = {
   103→    valid: [],
   104→    invalid: [],
   105→    snapshotFlagErrors: [],
   106→    warnings: [],
   107→  };
   108→
   109→  if (commands.length === 0) {
   110→    result.warnings.push('no $B commands found');
   111→    return result;
   112→  }
   113→
   114→  for (const cmd of commands) {
   115→    if (!ALL_COMMANDS.has(cmd.command)) {
   116→      result.invalid.push(cmd);
   117→      continue;
   118→    }
   119→
   120→    // Validate snapshot flags
   121→    if (cmd.command === 'snapshot' && cmd.args.length > 0) {
   122→      try {
   123→        parseSnapshotArgs(cmd.args);
   124→      } catch (err: any) {
   125→        result.snapshotFlagErrors.push({ command: cmd, error: err.message });
   126→        continue;
   127→      }
   128→    }
   129→
   130→    result.valid.push(cmd);
   131→  }
   132→
   133→  return result;
   134→}
   135→
   136→/**
   137→ * Extract all REMOTE_SLUG=$(...) assignment patterns from .md files in given subdirectories.
   138→ * Returns a Map from filename → array of full assignment lines found.
   139→ */
   140→export function extractRemoteSlugPatterns(rootDir: string, subdirs: string[]): Map<string, string[]> {
   141→  const results = new Map<string, string[]>();
   142→  const pattern = /^REMOTE_SLUG=\$\(.*\)$/;
   143→
   144→  for (const subdir of subdirs) {
   145→    const dir = path.join(rootDir, subdir);
   146→    if (!fs.existsSync(dir)) continue;
   147→
   148→    const files = fs.readdirSync(dir).filter(f => f.endsWith('.md'));
   149→    for (const file of files) {
   150→      const filePath = path.join(dir, file);
   151→      const content = fs.readFileSync(filePath, 'utf-8');
   152→      const matches: string[] = [];
   153→
   154→      for (const line of content.split('\n')) {
   155→        const trimmed = line.trim();
   156→        if (pattern.test(trimmed)) {
   157→          matches.push(trimmed);
   158→        }
   159→      }
   160→
   161→      if (matches.length > 0) {
   162→        results.set(`${subdir}/${file}`, matches);
   163→      }
   164→    }
   165→  }
   166→
   167→  return results;
   168→}
   169→
   170→/**
   171→ * Parse a markdown weight table anchored to a "### Weights" heading.
   172→ * Expects rows like: | Category | 15% |
   173→ * Returns Map<category, number> where number is the percentage (e.g., 15).
   174→ */
   175→export function extractWeightsFromTable(content: string): Map<string, number> {
   176→  const weights = new Map<string, number>();
   177→
   178→  // Find the ### Weights section
   179→  const weightsIdx = content.indexOf('### Weights');
   180→  if (weightsIdx === -1) return weights;
   181→
   182→  // Find the table within that section (stop at next heading or end)
   183→  const section = content.slice(weightsIdx);
   184→  const lines = section.split('\n');
   185→
   186→  for (let i = 1; i < lines.length; i++) {
   187→    const line = lines[i].trim();
   188→
   189→    // Stop at next heading
   190→    if (line.startsWith('#') && !line.startsWith('###')) break;
   191→    if (line.startsWith('### ') && i > 0) break;
   192→
   193→    // Parse table rows: | Category | N% |
   194→    const match = line.match(/^\|\s*(\w[\w\s]*\w|\w+)\s*\|\s*(\d+)%\s*\|$/);
   195→    if (match) {
   196→      const category = match[1].trim();
   197→      const pct = parseInt(match[2], 10);
   198→      // Skip header row
   199→      if (category !== 'Category' && !isNaN(pct)) {
   200→        weights.set(category, pct);
   201→      }
   202→    }
   203→  }
   204→
   205→  return weights;
   206→}
   207→