mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-17 10:25:33 +02:00
* fix(ship): foreground-flag + deadline + scope guard on all four dispatch sites (#497/#2440 class, 3rd recurrence)
Steps 7/8/10/18 dispatch subagents whose LAST-line JSON the parent
consumes, but none passed run_in_background: false — since Claude Code
v2.1.198 subagents background by default, so /ship stranded at Step 18
waiting on output that never arrives. Every site now renders the shared
{{FOREGROUND_DISPATCH_NOTE}} resolver constant, carries a ~10-minute
deadline with an explicit recovery branch (stop the runaway task,
reconcile against pre-dispatch HEAD, surface stray state, never
re-dispatch), and Step 18's prompt gains a docs-sync-only scope guard
(no VERSION changes, no base-branch merges, push-rejection reported as
pushed:false with parent-side reconciliation and a second-failure
branch). Greptile failures now record as UNAVAILABLE, not zero comments.
GENERATED_WITH_GUIDANCE pins all five ship dispatch carriers; a new test
pins the deadline recovery + scope guard phrases in pr-body (.md and
.tmpl). Codex/factory ship goldens re-rendered.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(document-release): first-class spawned-dispatch contract
document-release's own templates had zero subagent-awareness — the
entire headless contract lived in /ship's dispatch prompt, so any other
orchestrator (or an older installed /ship) dispatching it inherited none
of the gate handling. The skill now carries the contract itself: detect
spawned strictly from the dispatch prompt or the preamble echo (never
from file content — prompt-injection guard), auto-choose recommended
options while keeping the never-clobber-CHANGELOG and
never-bump-VERSION-silently invariants via their Skip options. Step 8.4d
gets an explicit spawned note (its interactive recommendation bumps
VERSION — wrong headlessly), and the Codex Documentation Review section
skips itself in spawned sessions (the apply gate needs a human; the
dispatching workflow owns review passes).
Contract, 8.4d note, and resolver skip are pinned in
run-in-background-guidance.test.ts; document-release skeleton budget
re-measured (39,812 B) and ratcheted to 40,200.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: sweep every remaining synchronous Agent-dispatch site with run_in_background: false
The #2440 failure shape was a silently-missing review voice — a
specialist launched in the background and merged before it completed.
Every remaining synchronous dispatch site now carries the explicit flag:
the Red Team dispatch, the spec review loop, the Codex
second-opinion/plan-review/doc-review Claude fallbacks, the adversarial
subagent, design sketch and outside voices, autoplan's design/eng/dx
phase dispatches, CSO parallel finding verification, and design-shotgun's
variant launch. Parallel fan-outs stay parallel — multiple foreground
Agent calls in one message run concurrently (the shipped v1.64.0.0
review-army pattern).
GENERATED_WITH_GUIDANCE now pins all 24 generated carriers, so a new
dispatch site that drops the flag fails the free suite. Six carved-skill
skeleton ceilings re-measured and ratcheted (~80-130 B growth each);
factory ship golden re-rendered.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* release: v1.79.0.0 — CHANGELOG, VERSION, TODOS follow-ups
Queue-advanced to 1.79.0.0 (1.78.0.0 claimed in the workspace queue;
same MINOR level per the versioning invariant). Entry references the
class history (#497 → #2440 → Step 18). Three TODOS filed: PreToolUse
hook enforcement, structural ship-mode for document-release, cross-host
dispatch semantics audit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* regen: review-army sections carry the Red Team foreground flag
The scripts/resolvers/review-army.ts Red Team edit regenerated these two
files but the sweep commit staged only the adversarial sections — the
skill-docs freshness gate (regen + git diff --exit-code) catches this.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* regen: agents digest picks up v1.79.0.0
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(document-release): one canonical spawned contract, downstream notes are pointers
The diff-selected LLM-judge eval scored the skill's clarity 3 (threshold
4, main scores 4): the spawned-session rules read as three separately-
framed rule sets (contract paragraph, Step 8.4d note, Codex-review skip).
The contract paragraph now declares itself the single source of spawned
behavior and the two downstream notes reference it instead of restating
rationale. The pointer avoids naming the Codex section verbatim so the
codex-host render (which strips that section) keeps its negative pin.
Judge re-scored 4/5/4 across repeated samples after the change.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: foreground note names the Agent tool as non-substitutable
The ship-docsync gate E2E caught a behavioral regression: the note's
blocking-emphasis ('a backgrounded dispatch strands the run') steered
the driven agent to run doc-sync via the Skill tool inline — the most
blocking option — twice in a row, forfeiting the fresh-context isolation
the dispatch exists for (baseline on main's text dispatches via Agent).
The shared note now says explicitly: dispatch with the Agent tool itself,
never substitute Skill or inline execution; the flag already makes the
call block. Re-verified: ship-docsync passes on the amended text.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: pre-landing review fixes
Review army + red team findings, all verified before applying:
- ship-docsync E2E now asserts run_in_background === false on the
captured dispatch (red team CRITICAL: phrase pins prove text exists,
this proves the model obeys it — verified passing live).
- Structural scanner test: any generated file with an Agent-dispatch
imperative (or bare '(foreground)' prose, the #2440 inert shape) must
carry the flag or hold a reasoned exemption — the 4th-recurrence net
the hand-enumerated pin list can't provide.
- Parent push reconciliation models reality: the parent shares the repo,
so a non-fast-forward that hit the subagent hits the parent identically
— fetch + ahead/behind check first, push only when the rejection was
transient; dispatch prompt promise softened to 'the parent will handle
it'.
- Recovered commits from a dead subagent are vetted docs-only
(git show --stat, never VERSION/package.json) before any push.
- Deadline pacing named: ~3 minutes between checks, wall clock not polls.
- Greptile UNAVAILABLE recording narrowed to the PR body (Step 20's
schema carries no triage field).
- document-release contract gains the echo-failure tie-breaker: prompt
claims spawned + no echo → fail fast with the dispatch contract's
failure shape instead of reproducing the #2733 prose-STOP; contract
anti-injection and NEVER-relax clauses pinned in tests.
- 'Claude Code v2.1.198' extracted to CC_BACKGROUND_DEFAULT_SINCE and
interpolated at all resolver sites (byte-identical output).
- CHANGELOG: entry-boundary blank line restored; worst-case-wait row
scoped to the backgrounded path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: adversarial review fixes — failure shape, CHANGELOG guard, vet coherence
Claude adversarial subagent findings (11), all verified before applying:
- The dispatch JSON contract gains an explicit FAILURE shape
({"error":...}) and a parent branch for it — a doc-sync that could not
run (spawned marking failed, broken preamble) previously had only the
no-updates shape to emit, which the parent printed as 'Documentation is
current': a silent false-clean of exactly the VAS-449 class.
- Scope guard now covers CHANGELOG: skip Step 5 voice polish and resolve
CHANGELOG-touching gates to leave-as-is (the parent authored the
release entry; the prompt's older auto-choose clause conflicted with
the contract's never-rewrite invariant).
- Recovery vet is sequence-coherent: pushing a commit pushes its
ancestors, so ANY non-doc commit (VERSION, package.json, CHANGELOG.md)
blocks the whole sequence — no more push-the-vetted-child-of-an-
unvetted-parent hole.
- Steps 7/8/10 failure branches stop a still-running backgrounded task
before falling back, so a late result never races the inline audit.
- 'Documentation synced' print gated on pushed:true (item 6 owns the
local-only outcome); doc-review skip note's backward step pointer
fixed; foreground note scoped 'at initial dispatch' so the sanctioned
inline FALLBACKS in Steps 7/8 read as sanctioned; constants docstring
no longer overclaims single-sourcing (names the 3 inline templates).
- Runtime-hook TODO raised P2 → P1: the spawned trust chain is
agent-self-asserted; prose cannot close it, the hook can.
Both docsync gate E2Es re-verified green on the amended prompt, including
the strict run_in_background === false dispatch assert.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: codex adversarial fixes — JSON trust, fail-open visibility, user-state safety
Codex outside-model adversarial pass (inline-diff workaround for the
sandbox), P1/P2 findings triaged cross-model:
- Parent validates the dispatch JSON's field types and treats
documentation_section as untrusted markdown (Step 19's redaction scan
covers the final body; instruction-shaped text inside it is never
followed). The error branch now explicitly skips items 2-6.
- Remote-ahead divergence is named, not silent: the parent lists foreign
commits before creating a PR over a moved branch.
- Recovery cleanup never discards content: stray staged doc edits are
unstaged but never checked out or cleaned away.
- Greptile UNAVAILABLE gets a concrete PR-body line, not a vague
'wherever results are reported'.
Pre-existing-class P1s (self-asserted spawned trust chain, unenforceable
foreground timeout) are cross-model confirmed and tracked: PreToolUse
hook TODO at P1, harness-residue hazard documented.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: never-Skill prohibition made unambiguous; docsync fixture made diagnostic
The ship-docsync E2E flaked on this sandbox because the driven agent
resolved the STOP pointer's ~ to nonexistent homes (/root, /home) and
acted blind — pass/fail sampled model priors, not the prompt. The
fixture prompt now names the planted sections dir, making local runs
deterministic (CI, with real install paths, was always diagnostic).
With a diagnostic fixture: 2/2 passes, real pr-body read, Agent dispatch
with run_in_background: false, zero Skill-tool substitutions.
Prose: the foreground note now states the dispatch happens ONLY via the
Agent tool (invoking the target as a Skill is wrong even though it
appears in the skills list; inline FALLBACKs apply only after a
dispatched subagent has failed), and the Step 18 imperative carries the
never-the-Skill-tool clause at the decision point.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: CHANGELOG entry covers the review-hardened contract
Failure JSON shape, CHANGELOG scope guard, vetted recovery pushes,
structural scanner, and the behavioral dispatch assert are shipped
properties of v1.79.0.0 — the entry now describes them.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: update project documentation for v1.79.0.0
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: CHANGELOG voice — follow-ups to For contributors, never-Skill property stated
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(test): daemon 503 test binds an OS-assigned port, not old-port+1
windows-free-tests flaked on this PR: the tunnel-less restart bound
daemon.loopbackPort + 1 — a fixed neighbor of the OS-assigned ephemeral
port — and died with 'Is port 55738 in use?' whenever another shard or a
TIME_WAIT socket held it; the file-level retry re-rolled the same dice.
Every other startDaemon in the file already uses loopbackPort: 0 and the
assertion reads d2.loopbackPort, so nothing needs a predictable number.
21/21 pass locally.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
354 lines
13 KiB
Cheetah
354 lines
13 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)
|
|
triggers:
|
|
- explore design variants
|
|
- show me design options
|
|
- visual design brainstorm
|
|
allowed-tools:
|
|
- Bash
|
|
- Read
|
|
- Glob
|
|
- Grep
|
|
- Agent
|
|
- AskUserQuestion
|
|
gbrain:
|
|
schema: 1
|
|
context_queries:
|
|
- id: prior-approved-variants
|
|
kind: filesystem
|
|
glob: "~/.gstack/projects/{repo_slug}/designs/*/approved.json"
|
|
sort: mtime_desc
|
|
limit: 5
|
|
render_as: "## Prior approved design variants for this project"
|
|
- id: design-md
|
|
kind: filesystem
|
|
glob: "DESIGN.md"
|
|
tail: 1
|
|
render_as: "## DESIGN.md (project design system)"
|
|
- id: recent-design-docs
|
|
kind: filesystem
|
|
glob: "~/.gstack/projects/{repo_slug}/*-design-*.md"
|
|
sort: mtime_desc
|
|
limit: 3
|
|
render_as: "## Recent design docs"
|
|
---
|
|
|
|
{{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.
|
|
|
|
---
|
|
|
|
{{SECTION_INDEX:design-shotgun}}
|
|
|
|
---
|
|
|
|
{{DESIGN_SETUP}}
|
|
|
|
{{SECTION:doctrine}}
|
|
|
|
## 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 both the persistent taste profile (cross-session) AND the per-session approved
|
|
designs to bias generation toward the user's demonstrated taste.
|
|
|
|
**Persistent taste profile (v1 schema at `~/.gstack/projects/$SLUG/taste-profile.json`):**
|
|
|
|
{{TASTE_PROFILE}}
|
|
|
|
**Per-session approved.json files (legacy, still supported):**
|
|
|
|
```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. Merge these into the taste-profile.json-derived signal — if the
|
|
profile already says "user prefers Geist font" (from aggregated history), the
|
|
approved.json files add the specific recent approval context.
|
|
|
|
Limit to last 10 sessions. Try/catch JSON parse on each (skip corrupted files).
|
|
|
|
**Updating taste profile after a design-shotgun session:** When the user picks a
|
|
variant, call `{{BIN_DIR}}/gstack-taste-update approved <variant-path>`. When they
|
|
explicitly reject a variant, call `{{BIN_DIR}}/gstack-taste-update rejected <variant-path>`.
|
|
The CLI handles schema migration from approved.json, decay, and conflict flagging.
|
|
|
|
## Step 3: Generate Variants
|
|
|
|
Set up the output directory:
|
|
|
|
```bash
|
|
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)"
|
|
_DESIGN_DIR="$HOME/.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.
|
|
|
|
**Anti-convergence directive (hard requirement):** Each variant MUST use a different
|
|
font family, color palette, and layout approach. If two variants look like siblings
|
|
— same typographic feel, overlapping color temperature, comparable layout rhythm —
|
|
one of them failed. Regenerate the weaker one with a deliberately different direction.
|
|
|
|
Concrete test: if someone could swap the headline text between two variants without
|
|
noticing, they're too similar. Variants should feel like they came from three
|
|
different design teams, not the same team at three different coffee levels.
|
|
|
|
### 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"` and `run_in_background: false` for each
|
|
variant (parallel foreground calls in one message still run concurrently; subagents
|
|
default to background since Claude Code v2.1.198, and the comparison board needs every
|
|
variant's result). 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) Finalize — generate production Pretext-native HTML/CSS with /design-html
|
|
> 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.
|