diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md
index f42a2bb1..4b2758e4 100644
--- a/.planning/REQUIREMENTS.md
+++ b/.planning/REQUIREMENTS.md
@@ -34,9 +34,9 @@ Requirements for Content Generation milestone. Each maps to roadmap phases.
### Document Generation
-- [ ] **DOC-01**: User can generate formatted PDF reports from conversation content
-- [ ] **DOC-02**: User can generate invoices and contracts from templates
-- [ ] **DOC-03**: User can generate one-pagers and API documentation
+- [x] **DOC-01**: User can generate formatted PDF reports from conversation content
+- [x] **DOC-02**: User can generate invoices and contracts from templates
+- [x] **DOC-03**: User can generate one-pagers and API documentation
### Icon Generation
@@ -66,12 +66,12 @@ Requirements for Content Generation milestone. Each maps to roadmap phases.
### Branding Media Kit
-- [ ] **BRAND-01**: User can generate a full brand identity from a single conversation
-- [ ] **BRAND-02**: System produces logo mark (SVG), avatar in multiple sizes
-- [ ] **BRAND-03**: System produces social media profile images and banners per platform
-- [ ] **BRAND-04**: System produces email signature and letterhead templates
-- [ ] **BRAND-05**: System produces a brand guidelines document (PDF)
-- [ ] **BRAND-06**: User can download all brand assets as a zip package
+- [x] **BRAND-01**: User can generate a full brand identity from a single conversation
+- [x] **BRAND-02**: System produces logo mark (SVG), avatar in multiple sizes
+- [x] **BRAND-03**: System produces social media profile images and banners per platform
+- [x] **BRAND-04**: System produces email signature and letterhead templates
+- [x] **BRAND-05**: System produces a brand guidelines document (PDF)
+- [x] **BRAND-06**: User can download all brand assets as a zip package
### Format Conversion
@@ -166,15 +166,15 @@ Which phases cover which requirements. Updated during roadmap creation.
| VOICE-01 | Phase 42 | Complete |
| VOICE-02 | Phase 42 | Complete |
| VOICE-03 | Phase 42 | Complete |
-| DOC-01 | Phase 43 | Pending |
-| DOC-02 | Phase 43 | Pending |
-| DOC-03 | Phase 43 | Pending |
-| BRAND-01 | Phase 43 | Pending |
-| BRAND-02 | Phase 43 | Pending |
-| BRAND-03 | Phase 43 | Pending |
-| BRAND-04 | Phase 43 | Pending |
-| BRAND-05 | Phase 43 | Pending |
-| BRAND-06 | Phase 43 | Pending |
+| DOC-01 | Phase 43 | Complete |
+| DOC-02 | Phase 43 | Complete |
+| DOC-03 | Phase 43 | Complete |
+| BRAND-01 | Phase 43 | Complete |
+| BRAND-02 | Phase 43 | Complete |
+| BRAND-03 | Phase 43 | Complete |
+| BRAND-04 | Phase 43 | Complete |
+| BRAND-05 | Phase 43 | Complete |
+| BRAND-06 | Phase 43 | Complete |
| PRES-01 | Phase 44 | Pending |
| PRES-02 | Phase 44 | Pending |
| PRES-03 | Phase 44 | Pending |
diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md
index 835d0eff..d38ef5e4 100644
--- a/.planning/ROADMAP.md
+++ b/.planning/ROADMAP.md
@@ -173,7 +173,7 @@ Plans:
- [x] **Phase 40: Job Infrastructure** — content_jobs table, async render lifecycle, SSE progress events, namespaced storage without size limit (INFRA-01..04) (completed 2026-04-04)
- [x] **Phase 41: Diagrams, Icons & Theme Engine** — Mermaid diagrams, SVG icon generation, OKLCH theme palette with WCAG AA and live preview (DIAG-01..05, ICON-01..03, THEME-01..07) (completed 2026-04-04)
- [x] **Phase 42: Wallpapers, Social, Format Conversion & Voice** — LLM SVG + sharp wallpapers, social content, format conversion registry with AI fallback, Whisper web chat mic (WALL-01..04, SOCIAL-01..03, CONV-01..09, VOICE-01..03) (completed 2026-04-04)
-- [ ] **Phase 43: Documents & Branding** — Playwright PDF reports and invoices, full brand identity kit with zip export (DOC-01..03, BRAND-01..06)
+- [x] **Phase 43: Documents & Branding** — Playwright PDF reports and invoices, full brand identity kit with zip export (DOC-01..03, BRAND-01..06) (completed 2026-04-04)
- [ ] **Phase 44: Video & Presentations** — Remotion workspace package, pitch decks and demo videos, SSE render progress (PRES-01..04)
- [ ] **Phase 45: Content as Skills** — Markdown skill files for all content types, Creative skill group on generalist agent (SKILL-01..03)
@@ -245,7 +245,12 @@ Plans:
2. Generating a one-pager or API reference document produces a styled PDF with navigable headings
3. Starting a brand identity conversation produces a logo mark (SVG), avatar at multiple sizes, platform-specific social images, an email signature, and a brand guidelines PDF — all in a single brand kit
4. The complete brand kit can be downloaded as a single zip file with assets organized by type
-**Plans**: TBD
+**Plans**: 3 plans
+
+Plans:
+- [x] 43-01-PLAN.md — Types, archiver install, PDF renderer (Playwright HTML-to-PDF), job-runner wiring
+- [x] 43-02-PLAN.md — Brand kit renderer (logo, avatars, social images, templates, guidelines PDF, ZIP packaging)
+- [x] 43-03-PLAN.md — Document and Brand UI panels, ContentStudio tab extensions
**UI hint**: yes
### Phase 44: Video & Presentations
@@ -362,6 +367,6 @@ All 52 v1.7 requirements are mapped to exactly one phase. No orphans.
| 40. Job Infrastructure | v1.7 | 2/2 | Complete | 2026-04-04 |
| 41. Diagrams, Icons & Theme Engine | v1.7 | 6/6 | Complete | 2026-04-04 |
| 42. Wallpapers, Social, Format Conversion & Voice | v1.7 | 6/6 | Complete | 2026-04-04 |
-| 43. Documents & Branding | v1.7 | 0/TBD | Not started | - |
+| 43. Documents & Branding | v1.7 | 3/3 | Complete | 2026-04-04 |
| 44. Video & Presentations | v1.7 | 0/TBD | Not started | - |
| 45. Content as Skills | v1.7 | 0/TBD | Not started | - |
diff --git a/.planning/STATE.md b/.planning/STATE.md
index 43dff900..e36e3eb6 100644
--- a/.planning/STATE.md
+++ b/.planning/STATE.md
@@ -3,14 +3,14 @@ gsd_state_version: 1.0
milestone: v1.7
milestone_name: Content Generation
status: verifying
-stopped_at: Completed 42-05-PLAN.md — Wallpaper and Social UI panels, ContentStudio extended to 5 tabs
-last_updated: "2026-04-04T22:23:10.096Z"
+stopped_at: Completed 43-03-PLAN.md — DocumentGeneratePanel, BrandKitPanel, BrandKitResult, ContentStudio 7 tabs
+last_updated: "2026-04-04T22:56:41.659Z"
last_activity: 2026-04-04
progress:
total_phases: 6
- completed_phases: 3
- total_plans: 14
- completed_plans: 14
+ completed_phases: 4
+ total_plans: 17
+ completed_plans: 17
percent: 0
---
@@ -21,11 +21,11 @@ progress:
See: .planning/PROJECT.md (updated 2026-04-04)
**Core value:** A fresh onboard asks for ONE thing (root directory), auto-creates PM + Engineer agents, and drops you in the dashboard.
-**Current focus:** Phase 42 — wallpapers-social-format-conversion-voice
+**Current focus:** Phase 43 — documents-branding
## Current Position
-Phase: 43
+Phase: 44
Plan: Not started
Status: Phase complete — ready for verification
Last activity: 2026-04-04
@@ -86,6 +86,11 @@ Key constraints for v1.7:
- [Phase 42-wallpapers-social-format-conversion-voice]: Direct EventSource for pre-submitted convert jobs — useContentJob.submit() cannot track an existing jobId without re-submitting via contentJobs route
- [Phase 42-wallpapers-social-format-conversion-voice]: FORMAT_GROUPS exported from ConvertPanel so ConvertPage can import for allowlist validation without duplicating the list
- [Phase 42-wallpapers-social-format-conversion-voice]: WallpaperBundle/AppIconBundle/SocialPostBundle types defined locally in panel component files — no content-bundles.ts addition needed since these types are only consumed by their respective components
+- [Phase 43-documents-branding]: stripMarkdownFences duplicated locally in pdf-renderer — wallpaper-renderer does not export it
+- [Phase 43-documents-branding]: buildPdfSystemPrompt uses switch with 4 distinct LLM prompt variants per docType (report/invoice/api-docs/one-pager)
+- [Phase 43]: Social images in brand-renderer use SVG templates (colored rect + embedded logo) rather than LLM-generated — fast, deterministic, always on-brand
+- [Phase 43-documents-branding]: BrandKitBundle type defined in BrandKitResult.tsx and imported by BrandKitPanel — type co-located with display component, avoids duplication
+- [Phase 43-documents-branding]: iframe sandbox=allow-same-origin for email signature and letterhead previews — prevents script execution while allowing inline CSS
### Pending Todos
@@ -100,6 +105,6 @@ None yet.
## Session Continuity
-Last session: 2026-04-04T22:22:05.529Z
-Stopped at: Completed 42-05-PLAN.md — Wallpaper and Social UI panels, ContentStudio extended to 5 tabs
+Last session: 2026-04-04T22:56:11.026Z
+Stopped at: Completed 43-03-PLAN.md — DocumentGeneratePanel, BrandKitPanel, BrandKitResult, ContentStudio 7 tabs
Resume file: None
diff --git a/.planning/phases/43-documents-branding/43-01-PLAN.md b/.planning/phases/43-documents-branding/43-01-PLAN.md
new file mode 100644
index 00000000..ba279d23
--- /dev/null
+++ b/.planning/phases/43-documents-branding/43-01-PLAN.md
@@ -0,0 +1,230 @@
+---
+phase: 43-documents-branding
+plan: 01
+type: execute
+wave: 1
+depends_on: []
+files_modified:
+ - server/src/services/renderers/types.ts
+ - server/src/services/renderers/pdf-renderer.ts
+ - server/src/services/content-job-runner.ts
+ - server/src/__tests__/pdf-renderer.test.ts
+ - server/package.json
+autonomous: true
+requirements: [DOC-01, DOC-02, DOC-03]
+
+must_haves:
+ truths:
+ - "renderPdfDocument produces a pdf-document-bundle with non-empty pdfBase64 for report docType"
+ - "renderPdfDocument produces a pdf-document-bundle for invoice docType with line items"
+ - "renderPdfDocument produces a pdf-document-bundle for api-docs docType"
+ - "content-job-runner dispatches pdf-document jobType to pdf-renderer"
+ - "PdfDocumentBundle and BrandKitBundle types exported from types.ts"
+ artifacts:
+ - path: "server/src/services/renderers/pdf-renderer.ts"
+ provides: "PDF rendering via Playwright HTML-to-PDF"
+ exports: ["renderPdfDocument"]
+ - path: "server/src/services/renderers/types.ts"
+ provides: "PdfDocumentBundle + BrandKitBundle type definitions"
+ contains: "PdfDocumentBundle"
+ - path: "server/src/__tests__/pdf-renderer.test.ts"
+ provides: "Unit tests for PDF renderer"
+ min_lines: 40
+ key_links:
+ - from: "server/src/services/content-job-runner.ts"
+ to: "server/src/services/renderers/pdf-renderer.ts"
+ via: "dynamic import in renderContent switch"
+ pattern: 'case "pdf-document"'
+ - from: "server/src/services/renderers/pdf-renderer.ts"
+ to: "server/src/services/renderers/diagram-renderer.js"
+ via: "resolveBrowserPath import"
+ pattern: "resolveBrowserPath"
+---
+
+
+PDF renderer and shared types for Phase 43 document generation.
+
+Purpose: Enable PDF report, invoice, one-pager, and API documentation generation via Playwright HTML-to-PDF. Also installs `archiver` and defines both bundle types needed by Plans 02-03.
+Output: Working pdf-renderer.ts, updated types.ts, job-runner wiring, archiver installed.
+
+
+
+@$HOME/.claude/get-shit-done/workflows/execute-plan.md
+@$HOME/.claude/get-shit-done/templates/summary.md
+
+
+
+@.planning/PROJECT.md
+@.planning/ROADMAP.md
+@.planning/STATE.md
+@.planning/phases/43-documents-branding/43-RESEARCH.md
+
+@server/src/services/renderers/types.ts
+@server/src/services/content-job-runner.ts
+@server/src/services/renderers/diagram-renderer.ts
+@server/src/services/puter-inference.ts
+
+
+
+
+From server/src/services/renderers/types.ts:
+```typescript
+export interface RenderResult {
+ filename: string;
+ contentType: string;
+ buffer: Buffer;
+}
+export type ContentBundle = DiagramBundle | IconSetBundle | ThemePaletteBundle | WallpaperBundle | AppIconBundle | SocialPostBundle | ConvertBundle;
+```
+
+From server/src/services/renderers/diagram-renderer.ts:
+```typescript
+export function resolveBrowserPath(): string; // resolves Playwright Chromium binary path
+```
+
+From server/src/services/puter-inference.ts:
+```typescript
+export interface ChatMessage { role: "system" | "user" | "assistant"; content: string; }
+export async function puterChatComplete(messages: ChatMessage[], model?: string): Promise;
+```
+
+From server/src/services/content-job-runner.ts:
+```typescript
+// renderContent() switch — add new case for "pdf-document"
+export async function renderContent(jobType: string, input: Record): Promise;
+```
+
+
+
+
+
+
+ Task 1: Install archiver, add bundle types, create pdf-renderer with tests
+ server/package.json, server/src/services/renderers/types.ts, server/src/services/renderers/pdf-renderer.ts, server/src/__tests__/pdf-renderer.test.ts
+
+ - server/src/services/renderers/types.ts (current bundle types and ContentBundle union)
+ - server/src/services/renderers/diagram-renderer.ts (resolveBrowserPath, Playwright launch pattern, stripUnsafeDirectives)
+ - server/src/services/renderers/wallpaper-renderer.ts (stripMarkdownFences helper — lines 42-50)
+ - server/src/services/puter-inference.ts (puterChatComplete signature)
+ - server/src/__tests__/diagram-renderer.test.ts (test mock pattern for playwright-core and puter-inference)
+
+
+ - Test 1: renderPdfDocument with docType="report" returns { filename: "document-report.json", contentType: "application/json" } and buffer parses to PdfDocumentBundle with type "pdf-document-bundle" and non-empty pdfBase64
+ - Test 2: renderPdfDocument with docType="invoice" returns bundle with docType "invoice"
+ - Test 3: renderPdfDocument with docType="api-docs" returns bundle with docType "api-docs"
+ - Test 4: renderPdfDocument with docType="one-pager" returns bundle with docType "one-pager"
+ - Test 5: LLM system prompt varies by docType (report vs invoice vs api-docs vs one-pager)
+
+
+ 1. Install archiver: `pnpm --filter @paperclipai/server add archiver && pnpm --filter @paperclipai/server add -D @types/archiver`
+
+ 2. Add to server/src/services/renderers/types.ts — append BEFORE the ContentBundle union:
+ ```typescript
+ export interface PdfDocumentBundle {
+ type: "pdf-document-bundle";
+ docType: string;
+ title: string;
+ pdfBase64: string;
+ }
+
+ export interface BrandKitBundle {
+ type: "brand-kit-bundle";
+ spec: {
+ name: string;
+ tagline: string;
+ primaryColor: string;
+ secondaryColor: string;
+ fontStyle: string;
+ industry: string;
+ };
+ logoSvgBase64: string;
+ avatarPngs: Record;
+ socialImages: Record;
+ signatureHtml: string;
+ letterheadHtml: string;
+ guidelinesPdfBase64: string;
+ zipBase64: string;
+ }
+ ```
+ Update ContentBundle union to include `| PdfDocumentBundle | BrandKitBundle`.
+
+ 3. Create server/src/services/renderers/pdf-renderer.ts:
+ - Import `chromium` from playwright-core, `resolveBrowserPath` from diagram-renderer, `puterChatComplete` from puter-inference, `RenderResult` and `PdfDocumentBundle` from types
+ - Create a local `stripMarkdownFences(raw: string): string` helper that removes ```html and ``` fences (same pattern as wallpaper-renderer line 42-50 — do NOT import from wallpaper-renderer as it is not exported)
+ - Create `buildPdfSystemPrompt(docType: string): string` with type-specific instructions for "report", "invoice", "one-pager", "api-docs" — each variant has different structural instructions. CRITICAL: system prompt must say "Use only inline CSS in a