Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
214c005
feat: enforce Dribbble and Stitch as hard pipeline requirements
DavisSylvester Apr 16, 2026
097e288
feat: add retry, Dribbble API client, design cache, and reliability docs
DavisSylvester Apr 16, 2026
ee72b59
push prds
DavisSylvester Apr 16, 2026
2d5f822
fix: remove broken Playwright auto-install, add --skip-playwright flag
DavisSylvester Apr 16, 2026
0a353a2
feat: add raw text PRD generation with --prompt flag
DavisSylvester Apr 16, 2026
ac016e2
refactor: extract inline prompts to markdown files in docs/prompts/
DavisSylvester Apr 16, 2026
82345c6
docs: add conversation log for session 3
DavisSylvester Apr 16, 2026
2f612e9
feat: wire real Playwright browser into standalone CLI runner
DavisSylvester Apr 16, 2026
7f066ea
docs: add conversation log for session 4
DavisSylvester Apr 16, 2026
77e46c4
feat: Node.js browser bridge for Bun compat, fix Dribbble scraper
DavisSylvester Apr 16, 2026
554c605
fix: use iframe-aware selectors for Stitch form submission
DavisSylvester Apr 16, 2026
3fdf6a1
feat: add --login for persistent Stitch session auth
DavisSylvester Apr 16, 2026
0a61746
fix: Stitch submission — retry input detection, poll for project URL
DavisSylvester Apr 16, 2026
d8c3062
docs: add knowledge base entries for Bun/Playwright, Stitch iframe, D…
DavisSylvester Apr 16, 2026
839abaf
feat(ui-plan): Panel Model pattern + full-stack-dashboard tuning example
DavisSylvester Apr 18, 2026
cfa8d98
feat(ui): Angular 19 workspace with Panel primitives + Stat atom
DavisSylvester Apr 18, 2026
3f312c2
build(deps): bump serialize-javascript and @angular-devkit/build-angular
dependabot[bot] Apr 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 186 additions & 0 deletions .ai/conversations/davis-2026-04-15.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,189 @@ Created `.docs/conversations/2026-04-15.md` with full session documentation. Sav

### Assistant
Ran docs skill. No API services in this repo — skipped OpenAPI/Postman. Saved this conversation log to `.ai/conversations/davis-2026-04-15.md`.

---

## Session 2 — 2026-04-16

## Summary

The pipeline was failing on `--prd ./sample-prds/thumbtackAngie.md` because the PRD file was plain text (no markdown headings), causing the parser to return "Untitled PRD (0 sections)" and producing empty Dribbble search queries. Implemented a raw text PRD generation feature: the CLI now auto-detects unstructured input and calls an LLM to generate a proper structured PRD before running the pipeline. Also added a `--prompt` flag for inline text descriptions.

## Files Modified

### Created
- `src/agents/prd-generation-agent.mts` — New agent extending `BaseAgent` that sends raw text to an LLM and returns a structured PRD markdown document. Validates output has >= 3 sections.
- `src/prompts/prd-generation.mts` — System prompt instructing the LLM to generate a PRD with 8 required sections (Overview, Features, Data Model, Pages/Views, User Roles, API Endpoints, Non-Functional Requirements).

### Modified
- `src/input/prd-parser.mts` — Changed `ParsedPrd` from a flat interface to a discriminated union (`StructuredPrd | RawTextPrd`). Files with 0 headings now return `kind: 'raw'`. Added `parseStructuredContent()` helper for re-parsing LLM-generated markdown.
- `src/cli/parse-args.mts` — Added `--prompt "<text>"` flag and `run-prompt` command variant. Updated help text and examples.
- `src/container/di.mts` — Registered `PrdGenerationAgent` in the DI container with `buildChain('planning')` role.
- `src/io/workspace.mts` — Added `saveGeneratedPrd()` method that writes generated PRD to `{workspaceDir}/generated-prd.md`.
- `src/index.mts` — Wired the detection and generation flow: detects raw text from `--prd` files or `--prompt` flag, runs PRD generation agent (logged as "Phase 0a: PRD Generation"), saves output, parses it, and continues the pipeline.

## Commits

(Changes not yet committed)

## Transcript

### User
> [Pasted pipeline output showing failure: "Untitled PRD (0 sections)" and "Aborting pipeline — Dribbble search failed from all sources"]

### Assistant
Diagnosed two compounding failures: (1) PRD parser returned empty title/sections because the file had no markdown headings, (2) Dribbble search got 0 results because Playwright was in standalone mode and search queries were derived from the empty scope. Proposed two fixes: improve the PRD parser and add a `--skip-dribbble` flag.

### User
> the cli should allow raw text and if it receives text it should generate a prd and then use it

### Assistant
Entered plan mode. Explored the codebase thoroughly: CLI parsing, PRD parser, entry point, LLM agent pattern, DI container, prompt templates, and pipeline flow. Designed a plan with 7 file changes covering content-based detection in the parser, a new `--prompt` flag, a `PrdGenerationAgent`, a system prompt, DI registration, workspace save method, and entry point wiring.

### User
> how many tokens have i used today

### Assistant
Explained that token usage isn't accessible from within the session. Suggested `/cost` for session cost and the Anthropic Console for daily totals.

### User
> [Approved plan]

### Assistant
Implemented the full feature across 7 files:
1. Updated `prd-parser.mts` with discriminated union (`StructuredPrd | RawTextPrd`) and `parseStructuredContent()` helper
2. Created `src/prompts/prd-generation.mts` with detailed system prompt
3. Created `src/agents/prd-generation-agent.mts` extending `BaseAgent`
4. Added `--prompt` flag to `parse-args.mts`
5. Registered agent in `di.mts`
6. Added `saveGeneratedPrd()` to `workspace.mts`
7. Wired everything in `index.mts` with "Phase 0a: PRD Generation" logging

TypeScript compiled cleanly. ESLint passed on all changed files (2 pre-existing errors in `pipeline.mts` unrelated to changes). CLI `--help` output verified.

### User
> document the changes

### Assistant
Ran docs skill. Appended session 2 to this conversation log.

---

## Session 3 — 2026-04-15

## Summary

Extracted all inline system prompts and rules from TypeScript files into standalone markdown files under `docs/prompts/`. Created a `loadPrompt()` utility that reads prompt text from `.md` files at startup via `Bun.file()`. This makes prompts easy to edit without touching TypeScript source. Affected 8 prompts across `src/prompts/`, `src/agents/`, and `src/orchestrator/`.

## Files Modified

### Created
- `docs/prompts/prd-generation.md` — PRD generation system prompt
- `docs/prompts/planning.md` — Angular planning/task decomposition prompt
- `docs/prompts/design-selection.md` — Dribbble design evaluation prompt
- `docs/prompts/codegen.md` — Angular code generation standards and rules
- `docs/prompts/component-library.md` — Component library generation prompt
- `docs/prompts/validation.md` — Code validation severity definitions and rules
- `docs/prompts/visual-fidelity.md` — Visual fidelity scoring and comparison prompt
- `docs/prompts/style-guide-extraction.md` — UI design box model decomposition prompt
- `src/prompts/load-prompt.mts` — Utility to load prompt markdown files via `Bun.file()`

### Modified
- `src/prompts/codegen.mts` — Replaced inline template literal with `loadPrompt("codegen.md")`
- `src/prompts/component-library.mts` — Replaced inline template literal with `loadPrompt("component-library.md")`
- `src/prompts/design-selection.mts` — Replaced inline template literal with `loadPrompt("design-selection.md")`
- `src/prompts/planning.mts` — Replaced inline template literal with `loadPrompt("planning.md")`
- `src/prompts/prd-generation.mts` — Replaced inline template literal with `loadPrompt("prd-generation.md")`
- `src/agents/validation-agent.mts` — Moved inline `VALIDATION_SYSTEM_PROMPT` to `loadPrompt("validation.md")`
- `src/agents/visual-fidelity-agent.mts` — Moved inline `FIDELITY_SYSTEM_PROMPT` to `loadPrompt("visual-fidelity.md")`
- `src/orchestrator/style-guide-extraction.mts` — Moved inline `SYSTEM_PROMPT` and `ELEMENT_TABLE` to `loadPrompt("style-guide-extraction.md")`

## Transcript

### User
> there seems to be a lot of my rules nested into the typescript files. Can we move the rules into md files to make updating easier and then reference the md files

### Assistant
Initially misunderstood scope as the global `~/.claude/CLAUDE.md`. User clarified they meant the project's TypeScript files.

### User
> continue, but I am talking about rules and workflow prompts in this project i want those as separate md files

### Assistant
Explored the codebase and found 8 system prompts embedded as template literals across `src/prompts/`, `src/agents/`, and `src/orchestrator/`. Created `docs/prompts/` with 8 `.md` files, a `loadPrompt()` utility, and updated all source files to load prompts from markdown at startup. TypeScript type check passed cleanly.

### User
> awesome, document, commit and push

### Assistant
Ran docs skill, appended session 3 to conversation log, committed and pushed.

---

## Session 4 — 2026-04-16

## Summary

Wired real Playwright browser automation into the standalone CLI runner. Previously, all browser callbacks (navigate, snapshot, screenshot, openTab) were no-ops when running from the command line — only working inside Claude Code with the Playwright MCP plugin. Now the CLI launches a real Chromium instance via the `playwright` package. The snapshot transformer converts Playwright 1.59's `ariaSnapshot()` YAML-like output into the text format all existing parsers expect, with inline URLs for Dribbble link scraping and `[ref=eN]` markers for Stitch fill/click interactions.

## Files Modified

### Created
- `src/browser/playwright-browser.mts` — Core browser module: launches Chromium, implements all PlaywrightCallbacks (navigate, snapshot, screenshot, openTab, fill, click, runCommand). Snapshot uses `page.ariaSnapshot()` + transformer that inlines URLs and adds refs for interactive elements.

### Modified
- `package.json` — Added `playwright` dependency
- `bun.lock` — Updated lockfile
- `src/cli/parse-args.mts` — Added `--headless` flag (default: headed mode so user sees the browser)
- `src/orchestrator/pipeline.mts` — Added optional `fill`/`click` to `PlaywrightCallbacks` interface; Stitch callbacks use them when available instead of no-ops
- `src/index.mts` — Replaced no-op Playwright callbacks with `launchBrowser()` from the new module. Added `try/finally` for browser cleanup.

## Commits

(Pending)

## Transcript

### User
> [Pasted pipeline output showing LLM_PROVIDER=openai instead of ollama]

### Assistant
Found `.env` has `LLM_PROVIDER=openai` explicitly set. The default in `env.mts` is `ollama` but the `.env` overrides it.

### User
> why is there a env.mts when we have a .env file

### Assistant
Explained the difference: `.env` holds the values, `env.mts` is the Zod schema that validates/types them at startup. This is the pattern from the user's own global CLAUDE.md / docs/bun.md.

### User
> [Pasted full pipeline output showing Dribbble scraper returning 0 results for all queries]

### Assistant
Diagnosed the chain: (1) Dribbble API client undefined (no `DRIBBBLE_ACCESS_TOKEN`), (2) Playwright scraper returns empty because standalone mode has no-op callbacks, (3) no design cache. Offered three options: add API token, add skip-design flag, or wire real Playwright.

### User
> how do i run so all browser calls are not running no-ops

### Assistant
Explained the two paths: run from Claude Code (Playwright MCP available) or wire real Playwright into the CLI. Showed the pattern with `chromium.launch()`.

### User
> option 2

### Assistant
Created a plan via the Plan agent, then implemented:
1. Installed `playwright` via `bun add`
2. Created `src/browser/playwright-browser.mts` with full browser lifecycle management
3. Built an AX tree snapshot transformer compatible with all existing parsers (DribbbleScraper, StitchService, build-validation, page-reviewer)
4. Added `--headless` CLI flag
5. Extended `PlaywrightCallbacks` with optional `fill`/`click`
6. Replaced no-op callbacks in `index.mts` with real browser + try/finally cleanup
7. Type check passed cleanly

### User
> awesome, document, commit and push

### Assistant
Updated conversation log, committed and pushed.
18 changes: 18 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"permissions": {
"allow": [
"Bash(bun run *)",
"Bash(ollama list *)",
"Bash(bun install *)",
"Bash(npx tsc *)",
"Bash(bunx tsc *)",
"Bash(bun test *)",
"Bash(git add *)",
"Bash(git commit -m ' *)",
"WebSearch",
"WebFetch(domain:www.banani.co)",
"WebFetch(domain:ybuild.ai)",
"WebFetch(domain:www.komposo.ai)"
]
}
}
126 changes: 126 additions & 0 deletions .docs/conversations/2026-04-15.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,135 @@ The pipeline uses a callback-based architecture where Playwright MCP tools are i

---

---

## Session 2: Hard Gates, Reliability Improvements, Design Tool Research

### 4. Enforce Dribbble & Stitch as Hard Pipeline Requirements

**Request:** Set HARD rules that the Dribbble scrape is a REQUIRED step — if it fails, exit. Same with Google Stitch.

**Problem:** Both Phase 1 (Dribbble) and Phase 2 (Stitch) previously degraded gracefully — Dribbble failure logged a warning and continued with default design notes, Stitch failure just skipped design generation. This allowed the pipeline to produce low-quality output with no real design backing.

**Changes to `src/orchestrator/pipeline.mts`:**

- **Phase 1 (Dribbble):** If `dribbbleScraper.search()` returns `ok: false` or zero designs, the pipeline logs an error and aborts immediately
- **Phase 2 (Stitch):** If `stitchService.generateDesigns()` returns `ok: false`, the pipeline logs an error and aborts immediately
- Downstream conditionals (`if (selectedDesign)`, `if (chosenDesign)`) simplified to unconditional execution since both are now guaranteed
- `selectedDesign` type narrowed from `SelectedDesign | undefined` to `SelectedDesign`

**Commit:** `feat: enforce Dribbble and Stitch as hard pipeline requirements` — `214c005`

---

### 5. Reliability Improvements: Retry, API Client, Design Cache

**Request:** Implement all four reliability recommendations: retry with backoff, Dribbble API migration, Stitch retry + longer waits, and design cache.

**Context:** With Dribbble and Stitch as hard gates, any transient failure (network blip, rate limit, slow page load) kills the entire pipeline. Both integrations are Playwright screen-scraping against third-party UIs — inherently fragile.

#### 5a. Retry-with-Backoff Utility

**File Created:** `src/utils/retry-with-backoff.mts`

- Generic async retry with exponential backoff + random jitter
- Configurable: `maxAttempts`, `baseDelayMs`, `maxDelayMs`, `jitter`, `label`
- Used by both Dribbble scraper and Stitch service

#### 5b. Dribbble API Client

**File Created:** `src/services/dribbble-api-client.mts`

- Calls `api.dribbble.com/v2` with OAuth access token — no DOM parsing, no anti-bot risk
- Each query retries 3x with backoff (2s base, 15s cap)
- Client-side filtering: matches shots whose title or tags overlap with query terms
- Activated when `DRIBBBLE_ACCESS_TOKEN` is set in env

**File Modified:** `src/services/dribbble-scraper.mts`

- Each per-query Playwright scrape now retries 3x with backoff (3s base, 15s cap)
- Extracted `scrapeQuery()` private method so the full navigate→screenshot→parse cycle retries cleanly

#### 5c. Stitch Retry + Longer Waits

**File Modified:** `src/services/stitch-service.mts`

- Each per-design `submitToStitch` call now retries 3x with backoff (5s base, 30s cap)
- Page load wait increased from 3s → 5s
- Design generation wait increased from 15s → 25s

#### 5d. Design Cache

**File Modified:** `src/io/workspace.mts`

- Added `saveCachedDribbbleDesigns` / `loadCachedDribbbleDesigns` — keyed by hash of project title + scope
- Added `saveCachedStitchDesigns` / `loadCachedStitchDesigns` — same key
- Stored in `.workspace/.design-cache/`
- `init()` now creates the `.design-cache` directory

#### 5e. Pipeline Wired with Layered Fallback

**File Modified:** `src/orchestrator/pipeline.mts`

**Phase 1 (Dribbble) strategy:**
1. Try Dribbble API client (if `DRIBBBLE_ACCESS_TOKEN` configured)
2. Fall back to Playwright scraper
3. Last resort: load cached designs from a prior run
4. Abort if all sources exhausted

**Phase 2 (Stitch) strategy:**
1. Try live Stitch generation (with per-submission retry built in)
2. Last resort: load cached designs from a prior run
3. Abort if all sources exhausted

Successful results are always cached for future runs.

#### 5f. Config & DI Updates

| File | Change |
|------|--------|
| `src/config/env.mts` | Added `DRIBBBLE_ACCESS_TOKEN` optional env var |
| `src/container/di.mts` | Creates `DribbbleApiClient` when token is present; added to `Container` interface |
| `src/index.mts` | Passes `dribbbleApiClient` to pipeline deps |
| `.env.example` | Documented `DRIBBBLE_ACCESS_TOKEN` with setup instructions |

#### 5g. Tests

| File | Tests |
|------|-------|
| `tests/retry-with-backoff.test.mts` | 6 tests — immediate success, retry + recover, exhaust attempts, maxAttempts=1, last-attempt success, exponential backoff timing, delay cap |
| `tests/dribbble-api-client.test.mts` | 3 tests — query generation, special character stripping, API error handling |
| `tests/design-cache.test.mts` | 5 tests — null for missing key, save/load Dribbble designs, overwrite cache, save/load Stitch designs |

**Test results:** 60 pass, 0 fail, 151 expect() calls

---

### 6. Design Tool Research: Google Stitch Alternatives

**Request:** Investigate whether Galileo AI or other tools are better options than Google Stitch as of April 2026.

**Key Finding:** Galileo AI was acquired by Google in mid-2025 and rebranded as Google Stitch. It no longer operates as a standalone product. The tool already in use *is* Galileo.

**Landscape (April 2026):**

| Tool | Best For | API? | Pricing |
|------|----------|------|---------|
| **Google Stitch** (current) | Highest-quality prompt-to-design, multiple variants | No REST API | Free |
| **v0 by Vercel** | Code-focused but excellent dashboard output | **Yes — REST API (beta)** | Free / $20-30/mo |
| **UX Pilot** | Polished screens + screen flows, Figma plugin | No API (credit-based) | Free / $22/mo |
| **Banani** | Fast multi-screen generation, MCP code export | MCP export only | Free (20/day) / $20/mo |
| **Komposo** | Clean code output + Figma export | No | Free / $15-39/mo |

**Decision:** Keep Google Stitch as the primary design generator. v0 is the strongest fallback candidate due to its real REST API (eliminates Playwright fragility), but not needed yet given the retry + cache improvements already implemented.

---

### Git Log (end of session)

```
214c005 feat: enforce Dribbble and Stitch as hard pipeline requirements
5f2040c docs: add conversation logs for 2026-04-15 session
b9fca50 feat: add preflight dependency check with auto-install
d13e74d feat: add style guide extraction phase (box model decomposition)
1a2b128 feat: initial commit for angular generator agent
Expand Down
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ TASK_COST_LIMIT=3.00 # Max cost per task in USD (aborts if exceeded)
STITCH_DESIGN_COUNT=5 # Number of Stitch designs (min 5)

# --- Design Search (Dribbble) ------------------------------------------------
# Dribbble API token (recommended — more reliable than Playwright scraping).
# Get one at: https://dribbble.com/account/applications
# If not set, falls back to Playwright scraper.
# DRIBBBLE_ACCESS_TOKEN=
DRIBBBLE_RESULT_COUNT=5 # Minimum Dribbble designs to scrape (min 5)

# --- Build Validation (Playwright) -------------------------------------------
Expand Down
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ Thumbs.db
# Pipeline workspace output
.workspace/

# Saved browser sessions — contains auth cookies
.auth/

# LangGraph
.langgraph_api/

Expand All @@ -47,3 +50,12 @@ bun.lockb
# Temporary files
tmp/
temp/

# Angular UI workspace
ui/node_modules/
ui/dist/
ui/.angular/
ui/out-tsc/

# Visual validation artifacts (regenerated per run)
visual-actual/
Loading
Loading