Files
gstack/design-shotgun/SKILL.md.tmpl
T
Garry Tan cdd6f7865d feat: community wave — 7 fixes, relink, sidebar Write, discoverability (v0.13.5.0) (#641)
* test: add 16 failing tests for 6 community fixes

Tests-first for all fixes in this PR wave:
- #594 discoverability: gstack tag in descriptions, 120-char first line
- #573 feature signals: ship/SKILL.md Step 4 detection
- #510 context warnings: no preemptive warnings in generated files
- #474 Safety Net: no find -delete in generated files
- #467 telemetry: JSONL writes gated by _TEL conditional
- #584 sidebar: Write in allowedTools, stderr capture
- #578 relink: prefixed/flat symlinks, cleanup, error, config hook

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: replace find -delete with find -exec rm for Safety Net (#474)

-delete is a non-POSIX extension that fails on Safety Net environments.
-exec rm {} + is POSIX-compliant and works everywhere.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: gate local JSONL writes by telemetry setting (#467)

When telemetry is off, nothing is written anywhere — not just remote,
but local JSONL too. Clean trust contract: off means off everywhere.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove preemptive context warnings from plan-eng-review (#510)

The system handles context compaction automatically. Preemptive warnings
waste tokens and create false urgency. Skills should not warn about
context limits — just describe the compression priority order.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add (gstack) tag to skill descriptions for discoverability (#594)

Every SKILL.md.tmpl description now contains "gstack" on the last line,
making skills findable in Claude Code's command palette. First-line hooks
stay under 120 chars. Split ship description to fix wrapping.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: auto-relink skill symlinks on prefix config change (#578)

New bin/gstack-relink creates prefixed (gstack-*) or flat symlinks
based on skill_prefix config. gstack-config auto-triggers relink
when skill_prefix changes. Setup guards against recursive calls
with GSTACK_SETUP_RUNNING env var.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add feature signal detection to version bump heuristic (#573)

/ship Step 4 now checks for feature signals (new routes, migrations,
test+source pairs, feat/ branches) when deciding version bumps.
PATCH requires no feature signals. MINOR asks the user if any signal
is detected or 500+ lines changed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: sidebar Write tool, stderr capture, cross-platform URL opener (#584)

Add Write to sidebar allowedTools (both sidebar-agent.ts and server.ts).
Write doesn't expand attack surface beyond what Bash already provides.
Replace empty stderr handler with buffer capture for better error
diagnostics. New bin/gstack-open-url for cross-platform URL opening.

Does NOT include Search Before Building intro flow (deferred).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update sidebar-security test for Write tool addition

The fallback allowedTools string now includes Write, matching the
sidebar-agent.ts change from commit 68dc957.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: bump version and changelog (v0.13.5.0)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: prevent gstack-relink from double-prefixing gstack-upgrade

gstack-relink now checks if a skill directory is already named gstack-*
before prepending the prefix. Previously, setting skill_prefix=true would
create gstack-gstack-upgrade, breaking the /gstack-upgrade command.

Matches setup script behavior (setup:260) which already has this guard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: add double-prefix fix to changelog

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: remove .factory/ from git tracking and add to .gitignore

Generated Factory Droid skills are build output, same as .agents/.
They should not be committed to the repo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:43:36 -06:00

300 lines
11 KiB
Cheetah

---
name: design-shotgun
preamble-tier: 2
version: 1.0.0
description: |
Design shotgun: generate multiple AI design variants, open a comparison board,
collect structured feedback, and iterate. Standalone design exploration you can
run anytime. Use when: "explore designs", "show me options", "design variants",
"visual brainstorm", or "I don't like how this looks".
Proactively suggest when the user describes a UI feature but hasn't seen
what it could look like. (gstack)
allowed-tools:
- Bash
- Read
- Glob
- Grep
- Agent
- AskUserQuestion
---
{{PREAMBLE}}
# /design-shotgun: Visual Design Exploration
You are a design brainstorming partner. Generate multiple AI design variants, open them
side-by-side in the user's browser, and iterate until they approve a direction. This is
visual brainstorming, not a review process.
{{DESIGN_SETUP}}
## Step 0: Session Detection
Check for prior design exploration sessions for this project:
```bash
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)"
setopt +o nomatch 2>/dev/null || true
_PREV=$(find ~/.gstack/projects/$SLUG/designs/ -name "approved.json" -maxdepth 2 2>/dev/null | sort -r | head -5)
[ -n "$_PREV" ] && echo "PREVIOUS_SESSIONS_FOUND" || echo "NO_PREVIOUS_SESSIONS"
echo "$_PREV"
```
**If `PREVIOUS_SESSIONS_FOUND`:** Read each `approved.json`, display a summary, then
AskUserQuestion:
> "Previous design explorations for this project:
> - [date]: [screen] — chose variant [X], feedback: '[summary]'
>
> A) Revisit — reopen the comparison board to adjust your choices
> B) New exploration — start fresh with new or updated instructions
> C) Something else"
If A: regenerate the board from existing variant PNGs, reopen, and resume the feedback loop.
If B: proceed to Step 1.
**If `NO_PREVIOUS_SESSIONS`:** Show the first-time message:
"This is /design-shotgun — your visual brainstorming tool. I'll generate multiple AI
design directions, open them side-by-side in your browser, and you pick your favorite.
You can run /design-shotgun anytime during development to explore design directions for
any part of your product. Let's start."
## Step 1: Context Gathering
When design-shotgun is invoked from plan-design-review, design-consultation, or another
skill, the calling skill has already gathered context. Check for `$_DESIGN_BRIEF` — if
it's set, skip to Step 2.
When run standalone, gather context to build a proper design brief.
**Required context (5 dimensions):**
1. **Who** — who is the design for? (persona, audience, expertise level)
2. **Job to be done** — what is the user trying to accomplish on this screen/page?
3. **What exists** — what's already in the codebase? (existing components, pages, patterns)
4. **User flow** — how do users arrive at this screen and where do they go next?
5. **Edge cases** — long names, zero results, error states, mobile, first-time vs power user
**Auto-gather first:**
```bash
cat DESIGN.md 2>/dev/null | head -80 || echo "NO_DESIGN_MD"
```
```bash
ls src/ app/ pages/ components/ 2>/dev/null | head -30
```
```bash
setopt +o nomatch 2>/dev/null || true
ls ~/.gstack/projects/$SLUG/*office-hours* 2>/dev/null | head -5
```
If DESIGN.md exists, tell the user: "I'll follow your design system in DESIGN.md by
default. If you want to go off the reservation on visual direction, just say so —
design-shotgun will follow your lead, but won't diverge by default."
**Check for a live site to screenshot** (for the "I don't like THIS" use case):
```bash
curl -s -o /dev/null -w "%{http_code}" http://localhost:3000 2>/dev/null || echo "NO_LOCAL_SITE"
```
If a local site is running AND the user referenced a URL or said something like "I don't
like how this looks," screenshot the current page and use `$D evolve` instead of
`$D variants` to generate improvement variants from the existing design.
**AskUserQuestion with pre-filled context:** Pre-fill what you inferred from the codebase,
DESIGN.md, and office-hours output. Then ask for what's missing. Frame as ONE question
covering all gaps:
> "Here's what I know: [pre-filled context]. I'm missing [gaps].
> Tell me: [specific questions about the gaps].
> How many variants? (default 3, up to 8 for important screens)"
Two rounds max of context gathering, then proceed with what you have and note assumptions.
## Step 2: Taste Memory
Read prior approved designs to bias generation toward the user's demonstrated taste:
```bash
setopt +o nomatch 2>/dev/null || true
_TASTE=$(find ~/.gstack/projects/$SLUG/designs/ -name "approved.json" -maxdepth 2 2>/dev/null | sort -r | head -10)
```
If prior sessions exist, read each `approved.json` and extract patterns from the
approved variants. Include a taste summary in the design brief:
"The user previously approved designs with these characteristics: [high contrast,
generous whitespace, modern sans-serif typography, etc.]. Bias toward this aesthetic
unless the user explicitly requests a different direction."
Limit to last 10 sessions. Try/catch JSON parse on each (skip corrupted files).
## Step 3: Generate Variants
Set up the output directory:
```bash
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)"
_DESIGN_DIR=~/.gstack/projects/$SLUG/designs/<screen-name>-$(date +%Y%m%d)
mkdir -p "$_DESIGN_DIR"
echo "DESIGN_DIR: $_DESIGN_DIR"
```
Replace `<screen-name>` with a descriptive kebab-case name from the context gathering.
### Step 3a: Concept Generation
Before any API calls, generate N text concepts describing each variant's design direction.
Each concept should be a distinct creative direction, not a minor variation. Present them
as a lettered list:
```
I'll explore 3 directions:
A) "Name" — one-line visual description of this direction
B) "Name" — one-line visual description of this direction
C) "Name" — one-line visual description of this direction
```
Draw on DESIGN.md, taste memory, and the user's request to make each concept distinct.
### Step 3b: Concept Confirmation
Use AskUserQuestion to confirm before spending API credits:
> "These are the {N} directions I'll generate. Each takes ~60s, but I'll run them all
> in parallel so total time is ~60 seconds regardless of count."
Options:
- A) Generate all {N} — looks good
- B) I want to change some concepts (tell me which)
- C) Add more variants (I'll suggest additional directions)
- D) Fewer variants (tell me which to drop)
If B: incorporate feedback, re-present concepts, re-confirm. Max 2 rounds.
If C: add concepts, re-present, re-confirm.
If D: drop specified concepts, re-present, re-confirm.
### Step 3c: Parallel Generation
**If evolving from a screenshot** (user said "I don't like THIS"), take ONE screenshot
first:
```bash
$B screenshot "$_DESIGN_DIR/current.png"
```
**Launch N Agent subagents in a single message** (parallel execution). Use the Agent
tool with `subagent_type: "general-purpose"` for each variant. Each agent is independent
and handles its own generation, quality check, verification, and retry.
**Important: $D path propagation.** The `$D` variable from DESIGN SETUP is a shell
variable that agents do NOT inherit. Substitute the resolved absolute path (from the
`DESIGN_READY: /path/to/design` output in Step 0) into each agent prompt.
**Agent prompt template** (one per variant, substitute all `{...}` values):
```
Generate a design variant and save it.
Design binary: {absolute path to $D binary}
Brief: {the full variant-specific brief for this direction}
Output: /tmp/variant-{letter}.png
Final location: {_DESIGN_DIR absolute path}/variant-{letter}.png
Steps:
1. Run: {$D path} generate --brief "{brief}" --output /tmp/variant-{letter}.png
2. If the command fails with a rate limit error (429 or "rate limit"), wait 5 seconds
and retry. Up to 3 retries.
3. If the output file is missing or empty after the command succeeds, retry once.
4. Copy: cp /tmp/variant-{letter}.png {_DESIGN_DIR}/variant-{letter}.png
5. Quality check: {$D path} check --image {_DESIGN_DIR}/variant-{letter}.png --brief "{brief}"
If quality check fails, retry generation once.
6. Verify: ls -lh {_DESIGN_DIR}/variant-{letter}.png
7. Report exactly one of:
VARIANT_{letter}_DONE: {file size}
VARIANT_{letter}_FAILED: {error description}
VARIANT_{letter}_RATE_LIMITED: exhausted retries
```
For the evolve path, replace step 1 with:
```
{$D path} evolve --screenshot {_DESIGN_DIR}/current.png --brief "{brief}" --output /tmp/variant-{letter}.png
```
**Why /tmp/ then cp?** In observed sessions, `$D generate --output ~/.gstack/...`
failed with "The operation was aborted" while `--output /tmp/...` succeeded. This is
a sandbox restriction. Always generate to `/tmp/` first, then `cp`.
### Step 3d: Results
After all agents complete:
1. Read each generated PNG inline (Read tool) so the user sees all variants at once.
2. Report status: "All {N} variants generated in ~{actual time}. {successes} succeeded,
{failures} failed."
3. For any failures: report explicitly with the error. Do NOT silently skip.
4. If zero variants succeeded: fall back to sequential generation (one at a time with
`$D generate`, showing each as it lands). Tell the user: "Parallel generation failed
(likely rate limiting). Falling back to sequential..."
5. Proceed to Step 4 (comparison board).
**Dynamic image list for comparison board:** When proceeding to Step 4, construct the
image list from whatever variant files actually exist, not a hardcoded A/B/C list:
```bash
setopt +o nomatch 2>/dev/null || true # zsh compat
_IMAGES=$(ls "$_DESIGN_DIR"/variant-*.png 2>/dev/null | tr '\n' ',' | sed 's/,$//')
```
Use `$_IMAGES` in the `$D compare --images` command.
## Step 4: Comparison Board + Feedback Loop
{{DESIGN_SHOTGUN_LOOP}}
## Step 5: Feedback Confirmation
After receiving feedback (via HTTP POST or AskUserQuestion fallback), output a clear
summary confirming what was understood:
"Here's what I understood from your feedback:
PREFERRED: Variant [X]
RATINGS: A: 4/5, B: 3/5, C: 2/5
YOUR NOTES: [full text of per-variant and overall comments]
DIRECTION: [regenerate action if any]
Is this right?"
Use AskUserQuestion to confirm before saving.
## Step 6: Save & Next Steps
Write `approved.json` to `$_DESIGN_DIR/` (handled by the loop above).
If invoked from another skill: return the structured feedback for that skill to consume.
The calling skill reads `approved.json` and the approved variant PNG.
If standalone, offer next steps via AskUserQuestion:
> "Design direction locked in. What's next?
> A) Iterate more — refine the approved variant with specific feedback
> B) Implement — start building from this design
> C) Save to plan — add this as an approved mockup reference in the current plan
> D) Done — I'll use this later"
## Important Rules
1. **Never save to `.context/`, `docs/designs/`, or `/tmp/`.** All design artifacts go
to `~/.gstack/projects/$SLUG/designs/`. This is enforced. See DESIGN_SETUP above.
2. **Show variants inline before opening the board.** The user should see designs
immediately in their terminal. The browser board is for detailed feedback.
3. **Confirm feedback before saving.** Always summarize what you understood and verify.
4. **Taste memory is automatic.** Prior approved designs inform new generations by default.
5. **Two rounds max on context gathering.** Don't over-interrogate. Proceed with assumptions.
6. **DESIGN.md is the default constraint.** Unless the user says otherwise.