Merge remote-tracking branch 'origin/main' into garrytan/learn-from-reviews

Resolved conflicts:
- VERSION: bumped to 0.14.6.0 (our branch on top of main's 0.14.5.0)
- CHANGELOG.md: kept our entry on top, main's 7 new entries below, updated version
- package.json: version synced to 0.14.6.0
- Regenerated all SKILL.md files from merged templates

Main brought: Review Army (parallel specialist reviewers), always-on adversarial,
CSS inspector, per-tab agents, design-to-code, comparison board, ship idempotency,
skill prefix fix, session intelligence roadmap.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-03-31 21:07:07 -07:00
93 changed files with 11423 additions and 821 deletions
+65 -29
View File
@@ -378,6 +378,21 @@ success/error/abort, and `USED_BROWSE` with true/false based on whether `$B` was
If you cannot determine the outcome, use "unknown". The local JSONL always logs. The
remote binary only runs if telemetry is not off and the binary exists.
## Plan Mode Safe Operations
When in plan mode, these operations are always allowed because they produce
artifacts that inform the plan, not code changes:
- `$B` commands (browse: screenshots, page inspection, navigation, snapshots)
- `$D` commands (design: generate mockups, variants, comparison boards, iterate)
- `codex exec` / `codex review` (outside voice, plan review, adversarial challenge)
- Writing to `~/.gstack/` (config, analytics, review logs, design artifacts, learnings)
- Writing to the plan file (already allowed by plan mode)
- `open` commands for viewing generated artifacts (comparison boards, HTML previews)
These are read-only in spirit — they inspect the live site, generate visual artifacts,
or get independent opinions. They do NOT modify project source files.
## Plan Status Footer
When you are in plan mode and about to call ExitPlanMode:
@@ -854,31 +869,42 @@ $D compare --images "$_DESIGN_DIR/variant-A.png,$_DESIGN_DIR/variant-B.png,$_DES
This command generates the board HTML, starts an HTTP server on a random port,
and opens it in the user's default browser. **Run it in the background** with `&`
because the agent needs to keep running while the user interacts with the board.
because the server needs to stay running while the user interacts with the board.
**IMPORTANT: Reading feedback via file polling (not stdout):**
Parse the port from stderr output: `SERVE_STARTED: port=XXXXX`. You need this
for the board URL and for reloading during regeneration cycles.
The server writes feedback to files next to the board HTML. The agent polls for these:
**PRIMARY WAIT: AskUserQuestion with board URL**
After the board is serving, use AskUserQuestion to wait for the user. Include the
board URL so they can click it if they lost the browser tab:
"I've opened a comparison board with the design variants:
http://127.0.0.1:<PORT>/ — Rate them, leave comments, remix
elements you like, and click Submit when you're done. Let me know when you've
submitted your feedback (or paste your preferences here). If you clicked
Regenerate or Remix on the board, tell me and I'll generate new variants."
**Do NOT use AskUserQuestion to ask which variant the user prefers.** The comparison
board IS the chooser. AskUserQuestion is just the blocking wait mechanism.
**After the user responds to AskUserQuestion:**
Check for feedback files next to the board HTML:
- `$_DESIGN_DIR/feedback.json` — written when user clicks Submit (final choice)
- `$_DESIGN_DIR/feedback-pending.json` — written when user clicks Regenerate/Remix/More Like This
**Polling loop** (run after launching `$D serve` in background):
```bash
# Poll for feedback files every 5 seconds (up to 10 minutes)
for i in $(seq 1 120); do
if [ -f "$_DESIGN_DIR/feedback.json" ]; then
echo "SUBMIT_RECEIVED"
cat "$_DESIGN_DIR/feedback.json"
break
elif [ -f "$_DESIGN_DIR/feedback-pending.json" ]; then
echo "REGENERATE_RECEIVED"
cat "$_DESIGN_DIR/feedback-pending.json"
rm "$_DESIGN_DIR/feedback-pending.json"
break
fi
sleep 5
done
if [ -f "$_DESIGN_DIR/feedback.json" ]; then
echo "SUBMIT_RECEIVED"
cat "$_DESIGN_DIR/feedback.json"
elif [ -f "$_DESIGN_DIR/feedback-pending.json" ]; then
echo "REGENERATE_RECEIVED"
cat "$_DESIGN_DIR/feedback-pending.json"
rm "$_DESIGN_DIR/feedback-pending.json"
else
echo "NO_FEEDBACK_FILE"
fi
```
The feedback JSON has this shape:
@@ -892,24 +918,30 @@ The feedback JSON has this shape:
}
```
**If `feedback-pending.json` found (`"regenerated": true`):**
**If `feedback.json` found:** The user clicked Submit on the board.
Read `preferred`, `ratings`, `comments`, `overall` from the JSON. Proceed with
the approved variant.
**If `feedback-pending.json` found:** The user clicked Regenerate/Remix on the board.
1. Read `regenerateAction` from the JSON (`"different"`, `"match"`, `"more_like_B"`,
`"remix"`, or custom text)
2. If `regenerateAction` is `"remix"`, read `remixSpec` (e.g. `{"layout":"A","colors":"B"}`)
3. Generate new variants with `$D iterate` or `$D variants` using updated brief
4. Create new board: `$D compare --images "..." --output "$_DESIGN_DIR/design-board.html"`
5. Parse the port from the `$D serve` stderr output (`SERVE_STARTED: port=XXXXX`),
then reload the board in the user's browser (same tab):
5. Reload the board in the user's browser (same tab):
`curl -s -X POST http://127.0.0.1:PORT/api/reload -H 'Content-Type: application/json' -d '{"html":"$_DESIGN_DIR/design-board.html"}'`
6. The board auto-refreshes. **Poll again** for the next feedback file.
7. Repeat until `feedback.json` appears (user clicked Submit).
6. The board auto-refreshes. **AskUserQuestion again** with the same board URL to
wait for the next round of feedback. Repeat until `feedback.json` appears.
**If `feedback.json` found (`"regenerated": false`):**
1. Read `preferred`, `ratings`, `comments`, `overall` from the JSON
2. Proceed with the approved variant
**If `NO_FEEDBACK_FILE`:** The user typed their preferences directly in the
AskUserQuestion response instead of using the board. Use their text response
as the feedback.
**If `$D serve` fails or no feedback within 10 minutes:** Fall back to AskUserQuestion:
"I've opened the design board. Which variant do you prefer? Any feedback?"
**POLLING FALLBACK:** Only use polling if `$D serve` fails (no port available).
In that case, show each variant inline using the Read tool (so the user can see them),
then use AskUserQuestion:
"The comparison board server failed to start. I've shown the variants above.
Which do you prefer? Any feedback?"
**After receiving feedback (any path):** Output a clear summary confirming
what was understood:
@@ -1064,6 +1096,10 @@ List all decisions. Flag any that used agent defaults without explicit user conf
- B) I want to change something (specify what)
- C) Start over
After shipping DESIGN.md, if the session produced screen-level mockups or page layouts
(not just system-level tokens), suggest:
"Want to see this design system as working Pretext-native HTML? Run /design-html."
---
## Capture Learnings
+4
View File
@@ -415,6 +415,10 @@ List all decisions. Flag any that used agent defaults without explicit user conf
- B) I want to change something (specify what)
- C) Start over
After shipping DESIGN.md, if the session produced screen-level mockups or page layouts
(not just system-level tokens), suggest:
"Want to see this design system as working Pretext-native HTML? Run /design-html."
---
{{LEARNINGS_LOG}}