feat: persist design mockups to ~/.gstack/projects/$SLUG/designs/

Mockups were going to .context/mockups/ (gitignored, workspace-local).
This meant designs disappeared when switching workspaces or conversations,
and downstream skills couldn't reference approved mockups from earlier
reviews.

Now all three design skills save to persistent project-scoped dirs:
- /plan-design-review: ~/.gstack/projects/$SLUG/designs/<screen>-<date>/
- /design-consultation: ~/.gstack/projects/$SLUG/designs/design-system-<date>/
- /design-review: ~/.gstack/projects/$SLUG/designs/design-audit-<date>/

Each directory gets an approved.json recording the user's pick, feedback,
and branch. This lets /design-review verify against mockups that
/plan-design-review approved, and design history is browsable via
ls ~/.gstack/projects/$SLUG/designs/.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-03-27 00:27:13 -06:00
parent ceb7f6382e
commit 25e6e8fb16
6 changed files with 102 additions and 58 deletions
+15 -8
View File
@@ -661,37 +661,44 @@ This phase generates visual previews of the proposed design system. Two paths de
Generate AI-rendered mockups showing the proposed design system applied to realistic screens for this product. This is far more powerful than an HTML preview — the user sees what their product could actually look like.
```bash
mkdir -p .context/mockups
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)"
_DESIGN_DIR=~/.gstack/projects/$SLUG/designs/design-system-$(date +%Y%m%d)
mkdir -p "$_DESIGN_DIR"
echo "DESIGN_DIR: $_DESIGN_DIR"
```
Construct a design brief from the Phase 3 proposal (aesthetic, colors, typography, spacing, layout) and the product context from Phase 1:
```bash
$D variants --brief "<product name: [name]. Product type: [type]. Aesthetic: [direction]. Colors: primary [hex], secondary [hex], neutrals [range]. Typography: display [font], body [font]. Layout: [approach]. Show a realistic [page type] screen with [specific content for this product].>" --count 3 --output-dir .context/mockups/
$D variants --brief "<product name: [name]. Product type: [type]. Aesthetic: [direction]. Colors: primary [hex], secondary [hex], neutrals [range]. Typography: display [font], body [font]. Layout: [approach]. Show a realistic [page type] screen with [specific content for this product].>" --count 3 --output-dir "$_DESIGN_DIR/"
```
Run quality check on each variant:
```bash
$D check --image .context/mockups/variant-A.png --brief "<the original brief>"
$D check --image "$_DESIGN_DIR/variant-A.png" --brief "<the original brief>"
```
Create a comparison board and open it:
```bash
$D compare --images ".context/mockups/variant-A.png,.context/mockups/variant-B.png,.context/mockups/variant-C.png" --output .context/mockups/design-board.html
$B goto file://$(pwd)/.context/mockups/design-board.html
$D compare --images "$_DESIGN_DIR/variant-A.png,$_DESIGN_DIR/variant-B.png,$_DESIGN_DIR/variant-C.png" --output "$_DESIGN_DIR/design-board.html"
$B goto "file://$_DESIGN_DIR/design-board.html"
```
Tell the user: "I've generated 3 visual directions applying your design system to a realistic [product type] screen. Pick your favorite — I'll use it to refine the design system and extract exact tokens for DESIGN.md."
After the user picks a direction:
- Use `$D extract --image .context/mockups/variant-<CHOSEN>.png` to analyze the approved mockup and extract design tokens (colors, typography, spacing) that will populate DESIGN.md in Phase 6. This grounds the design system in what was actually approved visually, not just what was described in text.
- If the user wants to iterate: `$D iterate --feedback "<user's feedback>" --output .context/mockups/refined.png`
- Use `$D extract --image "$_DESIGN_DIR/variant-<CHOSEN>.png"` to analyze the approved mockup and extract design tokens (colors, typography, spacing) that will populate DESIGN.md in Phase 6. This grounds the design system in what was actually approved visually, not just what was described in text.
- If the user wants to iterate: `$D iterate --feedback "<user's feedback>" --output "$_DESIGN_DIR/refined.png"`
- Write an `approved.json` to record the choice:
```bash
echo '{"approved_variant":"<VARIANT>","feedback":"<USER_FEEDBACK>","date":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","screen":"design-system","branch":"'$(git branch --show-current 2>/dev/null)'"}' > "$_DESIGN_DIR/approved.json"
```
**Plan mode vs. implementation mode:**
- **If in plan mode:** Add the approved mockup path and extracted tokens to the plan file under an "## Approved Design Direction" section. The design system gets written to DESIGN.md when the plan is implemented.
- **If in plan mode:** Add the approved mockup path (the full `$_DESIGN_DIR` path) and extracted tokens to the plan file under an "## Approved Design Direction" section. The design system gets written to DESIGN.md when the plan is implemented.
- **If NOT in plan mode:** Proceed directly to Phase 6 and write DESIGN.md with the extracted tokens.
### Path B: HTML Preview Page (fallback if DESIGN_NOT_AVAILABLE)
+15 -8
View File
@@ -253,37 +253,44 @@ This phase generates visual previews of the proposed design system. Two paths de
Generate AI-rendered mockups showing the proposed design system applied to realistic screens for this product. This is far more powerful than an HTML preview — the user sees what their product could actually look like.
```bash
mkdir -p .context/mockups
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)"
_DESIGN_DIR=~/.gstack/projects/$SLUG/designs/design-system-$(date +%Y%m%d)
mkdir -p "$_DESIGN_DIR"
echo "DESIGN_DIR: $_DESIGN_DIR"
```
Construct a design brief from the Phase 3 proposal (aesthetic, colors, typography, spacing, layout) and the product context from Phase 1:
```bash
$D variants --brief "<product name: [name]. Product type: [type]. Aesthetic: [direction]. Colors: primary [hex], secondary [hex], neutrals [range]. Typography: display [font], body [font]. Layout: [approach]. Show a realistic [page type] screen with [specific content for this product].>" --count 3 --output-dir .context/mockups/
$D variants --brief "<product name: [name]. Product type: [type]. Aesthetic: [direction]. Colors: primary [hex], secondary [hex], neutrals [range]. Typography: display [font], body [font]. Layout: [approach]. Show a realistic [page type] screen with [specific content for this product].>" --count 3 --output-dir "$_DESIGN_DIR/"
```
Run quality check on each variant:
```bash
$D check --image .context/mockups/variant-A.png --brief "<the original brief>"
$D check --image "$_DESIGN_DIR/variant-A.png" --brief "<the original brief>"
```
Create a comparison board and open it:
```bash
$D compare --images ".context/mockups/variant-A.png,.context/mockups/variant-B.png,.context/mockups/variant-C.png" --output .context/mockups/design-board.html
$B goto file://$(pwd)/.context/mockups/design-board.html
$D compare --images "$_DESIGN_DIR/variant-A.png,$_DESIGN_DIR/variant-B.png,$_DESIGN_DIR/variant-C.png" --output "$_DESIGN_DIR/design-board.html"
$B goto "file://$_DESIGN_DIR/design-board.html"
```
Tell the user: "I've generated 3 visual directions applying your design system to a realistic [product type] screen. Pick your favorite — I'll use it to refine the design system and extract exact tokens for DESIGN.md."
After the user picks a direction:
- Use `$D extract --image .context/mockups/variant-<CHOSEN>.png` to analyze the approved mockup and extract design tokens (colors, typography, spacing) that will populate DESIGN.md in Phase 6. This grounds the design system in what was actually approved visually, not just what was described in text.
- If the user wants to iterate: `$D iterate --feedback "<user's feedback>" --output .context/mockups/refined.png`
- Use `$D extract --image "$_DESIGN_DIR/variant-<CHOSEN>.png"` to analyze the approved mockup and extract design tokens (colors, typography, spacing) that will populate DESIGN.md in Phase 6. This grounds the design system in what was actually approved visually, not just what was described in text.
- If the user wants to iterate: `$D iterate --feedback "<user's feedback>" --output "$_DESIGN_DIR/refined.png"`
- Write an `approved.json` to record the choice:
```bash
echo '{"approved_variant":"<VARIANT>","feedback":"<USER_FEEDBACK>","date":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","screen":"design-system","branch":"'$(git branch --show-current 2>/dev/null)'"}' > "$_DESIGN_DIR/approved.json"
```
**Plan mode vs. implementation mode:**
- **If in plan mode:** Add the approved mockup path and extracted tokens to the plan file under an "## Approved Design Direction" section. The design system gets written to DESIGN.md when the plan is implemented.
- **If in plan mode:** Add the approved mockup path (the full `$_DESIGN_DIR` path) and extracted tokens to the plan file under an "## Approved Design Direction" section. The design system gets written to DESIGN.md when the plan is implemented.
- **If NOT in plan mode:** Proceed directly to Phase 6 and write DESIGN.md with the extracted tokens.
### Path B: HTML Preview Page (fallback if DESIGN_NOT_AVAILABLE)
+9 -7
View File
@@ -584,8 +584,10 @@ If `DESIGN_NOT_AVAILABLE`: skip mockup generation — the fix loop works without
**Create output directories:**
```bash
REPORT_DIR=".gstack/design-reports"
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)"
REPORT_DIR=~/.gstack/projects/$SLUG/designs/design-audit-$(date +%Y%m%d)
mkdir -p "$REPORT_DIR/screenshots"
echo "REPORT_DIR: $REPORT_DIR"
```
---
@@ -999,8 +1001,8 @@ Record baseline design score and AI slop score at end of Phase 6.
## Output Structure
```
.gstack/design-reports/
├── design-audit-{domain}-{YYYY-MM-DD}.md # Structured report
~/.gstack/projects/$SLUG/designs/design-audit-{YYYYMMDD}/
├── design-audit-{domain}.md # Structured report
├── screenshots/
│ ├── first-impression.png # Phase 1
│ ├── {page}-annotated.png # Per-page annotated
@@ -1219,15 +1221,15 @@ After all fixes are applied:
## Phase 10: Report
Write the report to both local and project-scoped locations:
Write the report to `$REPORT_DIR` (already set up in the setup phase):
**Local:** `.gstack/design-reports/design-audit-{domain}-{YYYY-MM-DD}.md`
**Primary:** `$REPORT_DIR/design-audit-{domain}.md`
**Project-scoped:**
**Also write a summary to the project index:**
```bash
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG
```
Write to `~/.gstack/projects/{slug}/{user}-{branch}-design-audit-{datetime}.md`
Write a one-line summary to `~/.gstack/projects/{slug}/{user}-{branch}-design-audit-{datetime}.md` with a pointer to the full report in `$REPORT_DIR`.
**Per-finding additions** (beyond standard design audit report):
- Fix Status: verified / best-effort / reverted / deferred
+9 -7
View File
@@ -89,8 +89,10 @@ If `DESIGN_NOT_AVAILABLE`: skip mockup generation — the fix loop works without
**Create output directories:**
```bash
REPORT_DIR=".gstack/design-reports"
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)"
REPORT_DIR=~/.gstack/projects/$SLUG/designs/design-audit-$(date +%Y%m%d)
mkdir -p "$REPORT_DIR/screenshots"
echo "REPORT_DIR: $REPORT_DIR"
```
---
@@ -108,8 +110,8 @@ Record baseline design score and AI slop score at end of Phase 6.
## Output Structure
```
.gstack/design-reports/
├── design-audit-{domain}-{YYYY-MM-DD}.md # Structured report
~/.gstack/projects/$SLUG/designs/design-audit-{YYYYMMDD}/
├── design-audit-{domain}.md # Structured report
├── screenshots/
│ ├── first-impression.png # Phase 1
│ ├── {page}-annotated.png # Per-page annotated
@@ -248,15 +250,15 @@ After all fixes are applied:
## Phase 10: Report
Write the report to both local and project-scoped locations:
Write the report to `$REPORT_DIR` (already set up in the setup phase):
**Local:** `.gstack/design-reports/design-audit-{domain}-{YYYY-MM-DD}.md`
**Primary:** `$REPORT_DIR/design-audit-{domain}.md`
**Project-scoped:**
**Also write a summary to the project index:**
```bash
{{SLUG_SETUP}}
```
Write to `~/.gstack/projects/{slug}/{user}-{branch}-design-audit-{datetime}.md`
Write a one-line summary to `~/.gstack/projects/{slug}/{user}-{branch}-design-audit-{datetime}.md` with a pointer to the full report in `$REPORT_DIR`.
**Per-finding additions** (beyond standard design audit report):
- Fix Status: verified / best-effort / reverted / deferred
+27 -14
View File
@@ -532,30 +532,37 @@ The ONLY time you skip mockups is when:
If the user explicitly says "skip mockups" or "text only", respect that. Otherwise, generate.
**PLAN MODE EXCEPTION — ALWAYS RUN:** These commands write design artifacts to
`.context/mockups/` (gitignored directory, not source files). Mockups are design
artifacts that inform the plan, not code changes. The gstack designer outputs PNGs
and HTML comparison boards for human review during the planning phase. Generating
mockups during planning is the whole point.
`~/.gstack/projects/$SLUG/designs/` (user config directory, not project files).
Mockups are design artifacts that inform the plan, not code changes. The gstack
designer outputs PNGs and HTML comparison boards for human review during the
planning phase. Generating mockups during planning is the whole point.
Allowed commands under this exception:
- `mkdir -p .context/mockups/`
- `mkdir -p ~/.gstack/projects/$SLUG/designs/...`
- `$D generate`, `$D variants`, `$D compare`, `$D iterate`, `$D evolve`, `$D check`
- `$B goto file:///` (to view comparison board in browser)
First, set up the output directory. Name it after the screen/feature being designed and today's date:
```bash
mkdir -p .context/mockups
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 (e.g., `homepage-variants`, `settings-page`, `onboarding-flow`).
For each UI screen/section in scope, construct a design brief from the plan's description (and DESIGN.md if present) and generate variants:
```bash
$D variants --brief "<description assembled from plan + DESIGN.md constraints>" --count 3 --output-dir .context/mockups/
$D variants --brief "<description assembled from plan + DESIGN.md constraints>" --count 3 --output-dir "$_DESIGN_DIR/"
```
After generation, run a cross-model quality check on each variant:
```bash
$D check --image .context/mockups/variant-A.png --brief "<the original brief>"
$D check --image "$_DESIGN_DIR/variant-A.png" --brief "<the original brief>"
```
Flag any variants that fail the quality check. Offer to regenerate failures.
@@ -563,15 +570,21 @@ Flag any variants that fail the quality check. Offer to regenerate failures.
Create a comparison board and open it for review:
```bash
$D compare --images ".context/mockups/variant-A.png,.context/mockups/variant-B.png,.context/mockups/variant-C.png" --output .context/mockups/design-board.html
$B goto file://$(pwd)/.context/mockups/design-board.html
$D compare --images "$_DESIGN_DIR/variant-A.png,$_DESIGN_DIR/variant-B.png,$_DESIGN_DIR/variant-C.png" --output "$_DESIGN_DIR/design-board.html"
$B goto "file://$_DESIGN_DIR/design-board.html"
```
Tell the user: "I've generated design directions and opened the comparison board. Pick your favorite, rate the others, and I'll use your choice to calibrate the review passes."
Read the user's feedback. Note which direction was approved — this becomes the visual reference for all subsequent review passes.
**Multiple variants/screens:** If the user asked for multiple variants (e.g., "5 versions of the homepage"), generate ALL as separate variant sets with their own comparison boards. Complete all mockup generation and user selection before starting review passes.
After the user picks a direction, write an `approved.json` to record the choice:
```bash
echo '{"approved_variant":"<VARIANT>","feedback":"<USER_FEEDBACK>","date":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","screen":"<SCREEN_NAME>","branch":"'$(git branch --show-current 2>/dev/null)'"}' > "$_DESIGN_DIR/approved.json"
```
**Multiple variants/screens:** If the user asked for multiple variants (e.g., "5 versions of the homepage"), generate ALL as separate variant sets with their own comparison boards. Each screen/variant set gets its own subdirectory under `designs/`. Complete all mockup generation and user selection before starting review passes.
**If `DESIGN_NOT_AVAILABLE`:** Tell the user: "The gstack designer isn't set up yet. Run `$D setup` to enable visual mockups. Proceeding with text-only review, but you're missing the best part." Then proceed to review passes with text-based review.
@@ -851,7 +864,7 @@ If mockups were generated in Step 0.5 and review passes changed significant desi
AskUserQuestion: "The review passes changed [list major design changes]. Want me to regenerate mockups to reflect the updated plan? This ensures the visual reference matches what we're actually building."
If yes, use `$D iterate` with feedback summarizing the changes, or `$D variants` with an updated brief. Save to `.context/mockups/`.
If yes, use `$D iterate` with feedback summarizing the changes, or `$D variants` with an updated brief. Save to the same `$_DESIGN_DIR` directory.
## CRITICAL RULE — How to ask questions
Follow the AskUserQuestion format from the Preamble above. Additional rules for plan design reviews:
@@ -923,10 +936,10 @@ If visual mockups were generated during this review, add to the plan file:
| Screen/Section | Mockup Path | Direction | Notes |
|----------------|-------------|-----------|-------|
| [screen name] | .context/mockups/[filename].png | [brief description] | [constraints from review] |
| [screen name] | ~/.gstack/projects/$SLUG/designs/[folder]/[filename].png | [brief description] | [constraints from review] |
```
Include the file path to each approved mockup (the variant the user chose), a one-line description of the direction, and any constraints. The implementer reads this to know exactly which visual to build from. If no mockups were generated, omit this section.
Include the full path to each approved mockup (the variant the user chose), a one-line description of the direction, and any constraints. The implementer reads this to know exactly which visual to build from. These persist across conversations and workspaces. If no mockups were generated, omit this section.
## Review Log
+27 -14
View File
@@ -168,30 +168,37 @@ The ONLY time you skip mockups is when:
If the user explicitly says "skip mockups" or "text only", respect that. Otherwise, generate.
**PLAN MODE EXCEPTION — ALWAYS RUN:** These commands write design artifacts to
`.context/mockups/` (gitignored directory, not source files). Mockups are design
artifacts that inform the plan, not code changes. The gstack designer outputs PNGs
and HTML comparison boards for human review during the planning phase. Generating
mockups during planning is the whole point.
`~/.gstack/projects/$SLUG/designs/` (user config directory, not project files).
Mockups are design artifacts that inform the plan, not code changes. The gstack
designer outputs PNGs and HTML comparison boards for human review during the
planning phase. Generating mockups during planning is the whole point.
Allowed commands under this exception:
- `mkdir -p .context/mockups/`
- `mkdir -p ~/.gstack/projects/$SLUG/designs/...`
- `$D generate`, `$D variants`, `$D compare`, `$D iterate`, `$D evolve`, `$D check`
- `$B goto file:///` (to view comparison board in browser)
First, set up the output directory. Name it after the screen/feature being designed and today's date:
```bash
mkdir -p .context/mockups
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 (e.g., `homepage-variants`, `settings-page`, `onboarding-flow`).
For each UI screen/section in scope, construct a design brief from the plan's description (and DESIGN.md if present) and generate variants:
```bash
$D variants --brief "<description assembled from plan + DESIGN.md constraints>" --count 3 --output-dir .context/mockups/
$D variants --brief "<description assembled from plan + DESIGN.md constraints>" --count 3 --output-dir "$_DESIGN_DIR/"
```
After generation, run a cross-model quality check on each variant:
```bash
$D check --image .context/mockups/variant-A.png --brief "<the original brief>"
$D check --image "$_DESIGN_DIR/variant-A.png" --brief "<the original brief>"
```
Flag any variants that fail the quality check. Offer to regenerate failures.
@@ -199,15 +206,21 @@ Flag any variants that fail the quality check. Offer to regenerate failures.
Create a comparison board and open it for review:
```bash
$D compare --images ".context/mockups/variant-A.png,.context/mockups/variant-B.png,.context/mockups/variant-C.png" --output .context/mockups/design-board.html
$B goto file://$(pwd)/.context/mockups/design-board.html
$D compare --images "$_DESIGN_DIR/variant-A.png,$_DESIGN_DIR/variant-B.png,$_DESIGN_DIR/variant-C.png" --output "$_DESIGN_DIR/design-board.html"
$B goto "file://$_DESIGN_DIR/design-board.html"
```
Tell the user: "I've generated design directions and opened the comparison board. Pick your favorite, rate the others, and I'll use your choice to calibrate the review passes."
Read the user's feedback. Note which direction was approved — this becomes the visual reference for all subsequent review passes.
**Multiple variants/screens:** If the user asked for multiple variants (e.g., "5 versions of the homepage"), generate ALL as separate variant sets with their own comparison boards. Complete all mockup generation and user selection before starting review passes.
After the user picks a direction, write an `approved.json` to record the choice:
```bash
echo '{"approved_variant":"<VARIANT>","feedback":"<USER_FEEDBACK>","date":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","screen":"<SCREEN_NAME>","branch":"'$(git branch --show-current 2>/dev/null)'"}' > "$_DESIGN_DIR/approved.json"
```
**Multiple variants/screens:** If the user asked for multiple variants (e.g., "5 versions of the homepage"), generate ALL as separate variant sets with their own comparison boards. Each screen/variant set gets its own subdirectory under `designs/`. Complete all mockup generation and user selection before starting review passes.
**If `DESIGN_NOT_AVAILABLE`:** Tell the user: "The gstack designer isn't set up yet. Run `$D setup` to enable visual mockups. Proceeding with text-only review, but you're missing the best part." Then proceed to review passes with text-based review.
@@ -314,7 +327,7 @@ If mockups were generated in Step 0.5 and review passes changed significant desi
AskUserQuestion: "The review passes changed [list major design changes]. Want me to regenerate mockups to reflect the updated plan? This ensures the visual reference matches what we're actually building."
If yes, use `$D iterate` with feedback summarizing the changes, or `$D variants` with an updated brief. Save to `.context/mockups/`.
If yes, use `$D iterate` with feedback summarizing the changes, or `$D variants` with an updated brief. Save to the same `$_DESIGN_DIR` directory.
## CRITICAL RULE — How to ask questions
Follow the AskUserQuestion format from the Preamble above. Additional rules for plan design reviews:
@@ -386,10 +399,10 @@ If visual mockups were generated during this review, add to the plan file:
| Screen/Section | Mockup Path | Direction | Notes |
|----------------|-------------|-----------|-------|
| [screen name] | .context/mockups/[filename].png | [brief description] | [constraints from review] |
| [screen name] | ~/.gstack/projects/$SLUG/designs/[folder]/[filename].png | [brief description] | [constraints from review] |
```
Include the file path to each approved mockup (the variant the user chose), a one-line description of the direction, and any constraints. The implementer reads this to know exactly which visual to build from. If no mockups were generated, omit this section.
Include the full path to each approved mockup (the variant the user chose), a one-line description of the direction, and any constraints. The implementer reads this to know exactly which visual to build from. These persist across conversations and workspaces. If no mockups were generated, omit this section.
## Review Log